| /******************************************************************************* |
| * Copyright (c) 2004, 2009 Tasktop Technologies and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Tasktop Technologies - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.mylyn.internal.cdt.ui.contentassist; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; |
| import org.eclipse.cdt.core.dom.ast.DOMException; |
| import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; |
| import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; |
| import org.eclipse.cdt.core.dom.ast.IASTDeclarator; |
| import org.eclipse.cdt.core.dom.ast.IASTFunctionStyleMacroParameter; |
| import org.eclipse.cdt.core.dom.ast.IASTIdExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTName; |
| import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; |
| import org.eclipse.cdt.core.dom.ast.IASTNode; |
| import org.eclipse.cdt.core.dom.ast.IASTPreprocessorFunctionStyleMacroDefinition; |
| import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; |
| import org.eclipse.cdt.core.dom.ast.IBinding; |
| import org.eclipse.cdt.core.dom.ast.ICompositeType; |
| import org.eclipse.cdt.core.dom.ast.IEnumeration; |
| import org.eclipse.cdt.core.dom.ast.IEnumerator; |
| import org.eclipse.cdt.core.dom.ast.IField; |
| import org.eclipse.cdt.core.dom.ast.IFunction; |
| import org.eclipse.cdt.core.dom.ast.IFunctionType; |
| import org.eclipse.cdt.core.dom.ast.IParameter; |
| import org.eclipse.cdt.core.dom.ast.IScope; |
| import org.eclipse.cdt.core.dom.ast.IType; |
| import org.eclipse.cdt.core.dom.ast.ITypedef; |
| import org.eclipse.cdt.core.dom.ast.IVariable; |
| import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; |
| import org.eclipse.cdt.core.model.CModelException; |
| import org.eclipse.cdt.core.model.CoreModel; |
| import org.eclipse.cdt.core.model.CoreModelUtil; |
| import org.eclipse.cdt.core.model.ICElement; |
| import org.eclipse.cdt.core.model.ITranslationUnit; |
| import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; |
| import org.eclipse.cdt.core.parser.util.CharArrayUtils; |
| import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding; |
| import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction; |
| import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitMethod; |
| import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitTypedef; |
| import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; |
| import org.eclipse.cdt.internal.ui.text.contentassist.CContentAssistInvocationContext; |
| import org.eclipse.cdt.internal.ui.text.contentassist.CProposalContextInformation; |
| import org.eclipse.cdt.internal.ui.text.contentassist.ParsingBasedProposalComputer; |
| import org.eclipse.cdt.internal.ui.text.contentassist.RelevanceConstants; |
| import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider; |
| import org.eclipse.cdt.ui.CUIPlugin; |
| import org.eclipse.cdt.ui.text.ICPartitions; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.ITypedRegion; |
| import org.eclipse.jface.text.TextUtilities; |
| import org.eclipse.jface.text.contentassist.ICompletionProposal; |
| import org.eclipse.mylyn.commons.core.StatusHandler; |
| import org.eclipse.mylyn.internal.cdt.ui.CDTUIBridgePlugin; |
| import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages; |
| import org.eclipse.swt.graphics.Image; |
| |
| /** |
| * Searches the DOM (both the AST and the index) for completion proposals. |
| * |
| * @author Bryan Wilkinson |
| */ |
| public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer { |
| |
| /** |
| * Default constructor is required (executable extension). |
| */ |
| public DOMCompletionProposalComputer() { |
| } |
| |
| @Override |
| protected List<ICompletionProposal> computeCompletionProposals(CContentAssistInvocationContext context, |
| IASTCompletionNode completionNode, String prefix) { |
| |
| List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>(); |
| |
| if (inPreprocessorDirective(context)) { |
| if (!inPreprocessorKeyword(context)) { |
| // add only macros |
| if (prefix.length() == 0) { |
| try { |
| prefix = context.computeIdentifierPrefix().toString(); |
| } catch (BadLocationException exc) { |
| CUIPlugin.log(exc); |
| } |
| } |
| addMacroProposals(context, prefix, proposals); |
| } |
| } else { |
| boolean handleMacros = false; |
| IASTName[] names = completionNode.getNames(); |
| |
| for (int i = 0; i < names.length; ++i) { |
| if (names[i].getTranslationUnit() == null) { |
| // The node isn't properly hooked up, must have backtracked out of this node |
| continue; |
| } |
| |
| IASTCompletionContext astContext = names[i].getCompletionContext(); |
| if (astContext == null) { |
| continue; |
| } else if (astContext instanceof IASTIdExpression || astContext instanceof IASTNamedTypeSpecifier) { |
| // handle macros only if there is a prefix |
| handleMacros = prefix.length() > 0; |
| } |
| |
| IBinding[] bindings = astContext.findBindings(names[i], !context.isContextInformationStyle()); |
| if (bindings != null) { |
| for (int j = 0; j < bindings.length; ++j) { |
| handleBinding(bindings[j], context, prefix, astContext, proposals); |
| } |
| } |
| } |
| |
| if (handleMacros) { |
| addMacroProposals(context, prefix, proposals); |
| } |
| } |
| |
| return proposals; |
| } |
| |
| /** |
| * Test whether the invocation offset is inside or before the preprocessor directive keyword. |
| * |
| * @param context |
| * the invocation context |
| * @return <code>true</code> if the invocation offset is inside or before the directive keyword |
| */ |
| private boolean inPreprocessorKeyword(CContentAssistInvocationContext context) { |
| IDocument doc = context.getDocument(); |
| int offset = context.getInvocationOffset(); |
| |
| try { |
| final ITypedRegion partition = TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING, offset, true); |
| if (ICPartitions.C_PREPROCESSOR.equals(partition.getType())) { |
| String ppPrefix = doc.get(partition.getOffset(), offset - partition.getOffset()); |
| if (ppPrefix.matches("\\s*#\\s*\\w*")) { //$NON-NLS-1$ |
| // we are inside the directive keyword |
| return true; |
| } |
| } |
| |
| } catch (BadLocationException exc) { |
| } |
| return false; |
| } |
| |
| /** |
| * Check if the invocation offset is inside a preprocessor directive. |
| * |
| * @param context |
| * the content asist invocation context |
| * @return <code>true</code> if invocation offset is inside a preprocessor directive |
| */ |
| private boolean inPreprocessorDirective(CContentAssistInvocationContext context) { |
| IDocument doc = context.getDocument(); |
| int offset = context.getInvocationOffset(); |
| |
| try { |
| final ITypedRegion partition = TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING, offset, true); |
| if (ICPartitions.C_PREPROCESSOR.equals(partition.getType())) { |
| return true; |
| } |
| |
| } catch (BadLocationException exc) { |
| } |
| return false; |
| } |
| |
| private void addMacroProposals(CContentAssistInvocationContext context, String prefix, |
| List<ICompletionProposal> proposals) { |
| char[] prefixChars = prefix.toCharArray(); |
| final boolean matchPrefix = !context.isContextInformationStyle(); |
| IASTCompletionNode completionNode = context.getCompletionNode(); |
| IASTPreprocessorMacroDefinition[] macros = completionNode.getTranslationUnit().getMacroDefinitions(); |
| if (macros != null) { |
| for (int i = 0; i < macros.length; ++i) { |
| final char[] macroName = macros[i].getName().toCharArray(); |
| if (CharArrayUtils.equals(macroName, 0, matchPrefix ? prefixChars.length : macroName.length, |
| prefixChars, true)) { |
| handleMacro(macros[i], context, prefix, proposals); |
| } |
| } |
| } |
| macros = completionNode.getTranslationUnit().getBuiltinMacroDefinitions(); |
| if (macros != null) { |
| for (int i = 0; i < macros.length; ++i) { |
| final char[] macroName = macros[i].getName().toCharArray(); |
| if (CharArrayUtils.equals(macroName, 0, matchPrefix ? prefixChars.length : macroName.length, |
| prefixChars, true)) { |
| handleMacro(macros[i], context, prefix, proposals); |
| } |
| } |
| } |
| } |
| |
| private void handleMacro(IASTPreprocessorMacroDefinition macro, CContentAssistInvocationContext context, |
| String prefix, List<ICompletionProposal> proposals) { |
| |
| //CElementHandleFactory.create; |
| final String macroName = macro.getName().toString(); |
| final int baseRelevance = computeBaseRelevance(prefix, macroName); |
| |
| Image image = getImage(CElementImageProvider.getMacroImageDescriptor()); |
| |
| if (macro instanceof IASTPreprocessorFunctionStyleMacroDefinition) { |
| IASTPreprocessorFunctionStyleMacroDefinition functionMacro = (IASTPreprocessorFunctionStyleMacroDefinition) macro; |
| |
| StringBuilder repStringBuff = new StringBuilder(); |
| repStringBuff.append(macroName); |
| repStringBuff.append('('); |
| |
| StringBuilder args = new StringBuilder(); |
| |
| IASTFunctionStyleMacroParameter[] params = functionMacro.getParameters(); |
| if (params != null) { |
| for (int i = 0; i < params.length; ++i) { |
| if (i > 0) { |
| args.append(", "); //$NON-NLS-1$ |
| } |
| args.append(params[i].getParameter()); |
| } |
| } |
| String argString = args.toString(); |
| |
| StringBuilder descStringBuff = new StringBuilder(repStringBuff.toString()); |
| descStringBuff.append(argString); |
| descStringBuff.append(')'); |
| |
| repStringBuff.append(')'); |
| String repString = repStringBuff.toString(); |
| String descString = descStringBuff.toString(); |
| |
| CCompletionProposal proposal = createProposal(repString, descString, prefix.length(), image, baseRelevance |
| + RelevanceConstants.MACRO_TYPE_RELEVANCE, context, getCElement(macro), macro.getName().toString()); |
| if (!context.isContextInformationStyle()) { |
| proposal.setCursorPosition(repString.length() - 1); |
| } |
| |
| if (argString.length() > 0) { |
| CProposalContextInformation info = new CProposalContextInformation(image, descString, argString); |
| info.setContextInformationPosition(context.getContextInformationOffset()); |
| proposal.setContextInformation(info); |
| } |
| |
| proposals.add(proposal); |
| } else { |
| proposals.add(createProposal(macroName, macroName, prefix.length(), image, baseRelevance |
| + RelevanceConstants.MACRO_TYPE_RELEVANCE, context, getCElement(macro), macro.getName().toString())); |
| } |
| } |
| |
| @SuppressWarnings("restriction") |
| protected void handleBinding(IBinding binding, CContentAssistInvocationContext cContext, String prefix, |
| IASTCompletionContext astContext, List<ICompletionProposal> proposals) { |
| |
| if ((binding instanceof CPPImplicitFunction || binding instanceof CPPImplicitTypedef) |
| && !(binding instanceof CPPImplicitMethod)) { |
| return; |
| } |
| |
| if (!isAnonymousBinding(binding)) { |
| final String name = binding.getName(); |
| final int baseRelevance = computeBaseRelevance(prefix, name); |
| if (binding instanceof ICPPClassType) { |
| handleClass((ICPPClassType) binding, astContext, cContext, baseRelevance, proposals); |
| } else if (binding instanceof IFunction) { |
| handleFunction((IFunction) binding, cContext, baseRelevance, proposals); |
| } else if (!cContext.isContextInformationStyle()) { |
| if (binding instanceof IVariable) { |
| handleVariable((IVariable) binding, cContext, baseRelevance, proposals); |
| } else if (binding instanceof ITypedef) { |
| proposals.add(createProposal(name, name, getImage(binding), baseRelevance |
| + RelevanceConstants.TYPEDEF_TYPE_RELEVANCE, cContext, getCElement(binding), |
| binding.getName())); |
| } else if (binding instanceof ICPPNamespace) { |
| handleNamespace((ICPPNamespace) binding, astContext, cContext, baseRelevance, proposals); |
| } else if (binding instanceof IEnumeration) { |
| proposals.add(createProposal(name, name, getImage(binding), baseRelevance |
| + RelevanceConstants.ENUMERATION_TYPE_RELEVANCE, cContext, getCElement(binding), |
| binding.getName())); |
| } else if (binding instanceof IEnumerator) { |
| proposals.add(createProposal(name, name, getImage(binding), baseRelevance |
| + RelevanceConstants.ENUMERATOR_TYPE_RELEVANCE, cContext, getCElement(binding), |
| binding.getName())); |
| } else { |
| proposals.add(createProposal(name, name, getImage(binding), baseRelevance |
| + RelevanceConstants.DEFAULT_TYPE_RELEVANCE, cContext, getCElement(binding), |
| binding.getName())); |
| } |
| } |
| } |
| } |
| |
| private boolean isAnonymousBinding(IBinding binding) { |
| char[] name = binding.getNameCharArray(); |
| return name.length == 0 || name[0] == '{'; |
| } |
| |
| private void handleClass(ICPPClassType classType, IASTCompletionContext astContext, |
| CContentAssistInvocationContext context, int baseRelevance, List<ICompletionProposal> proposals) { |
| if (context.isContextInformationStyle()) { |
| try { |
| ICPPConstructor[] constructors = classType.getConstructors(); |
| for (ICPPConstructor constructor : constructors) { |
| handleFunction(constructor, context, baseRelevance, proposals); |
| } |
| } catch (DOMException e) { |
| } |
| } else { |
| int relevance = 0; |
| try { |
| switch (classType.getKey()) { |
| case ICPPClassType.k_class: |
| relevance = RelevanceConstants.CLASS_TYPE_RELEVANCE; |
| break; |
| case ICompositeType.k_struct: |
| relevance = RelevanceConstants.STRUCT_TYPE_RELEVANCE; |
| break; |
| case ICompositeType.k_union: |
| relevance = RelevanceConstants.UNION_TYPE_RELEVANCE; |
| break; |
| } |
| } catch (DOMException exc) { |
| } |
| if (astContext instanceof IASTName && !(astContext instanceof ICPPASTQualifiedName)) { |
| IASTName name = (IASTName) astContext; |
| if (name.getParent() instanceof IASTDeclarator) { |
| proposals.add(createProposal( |
| classType.getName() + "::", classType.getName(), getImage(classType), baseRelevance + relevance, context, getCElement(classType), classType.getName())); //$NON-NLS-1$ |
| } |
| } |
| proposals.add(createProposal(classType.getName(), classType.getName(), getImage(classType), baseRelevance |
| + RelevanceConstants.CLASS_TYPE_RELEVANCE, context, getCElement(classType), classType.getName())); |
| } |
| } |
| |
| private void handleFunction(IFunction function, CContentAssistInvocationContext context, int baseRelevance, |
| List<ICompletionProposal> proposals) { |
| Image image = getImage(function); |
| |
| StringBuilder repStringBuff = new StringBuilder(); |
| repStringBuff.append(function.getName()); |
| repStringBuff.append('('); |
| |
| StringBuilder dispargs = new StringBuilder(); // for the displayString |
| StringBuilder idargs = new StringBuilder(); // for the idString |
| String returnTypeStr = null; |
| try { |
| IParameter[] params = function.getParameters(); |
| if (params != null) { |
| for (int i = 0; i < params.length; ++i) { |
| IType paramType = params[i].getType(); |
| if (i > 0) { |
| dispargs.append(','); |
| idargs.append(','); |
| } |
| |
| dispargs.append(ASTTypeUtil.getType(paramType, false)); |
| idargs.append(ASTTypeUtil.getType(paramType, false)); |
| String paramName = params[i].getName(); |
| if (paramName != null && paramName.length() > 0) { |
| dispargs.append(' '); |
| dispargs.append(paramName); |
| } |
| } |
| |
| if (function.takesVarArgs()) { |
| if (params.length > 0) { |
| dispargs.append(','); |
| idargs.append(','); |
| } |
| dispargs.append("..."); //$NON-NLS-1$ |
| idargs.append("..."); //$NON-NLS-1$ |
| } else if (params.length == 0) { // force the void in |
| dispargs.append("void"); //$NON-NLS-1$ |
| idargs.append("void"); //$NON-NLS-1$ |
| } |
| } |
| IFunctionType functionType = function.getType(); |
| if (functionType != null) { |
| IType returnType = functionType.getReturnType(); |
| if (returnType != null) { |
| returnTypeStr = ASTTypeUtil.getType(returnType, false); |
| } |
| } |
| } catch (DOMException e) { |
| } |
| |
| String dispargString = dispargs.toString(); |
| String idargString = idargs.toString(); |
| |
| StringBuilder dispStringBuff = new StringBuilder(repStringBuff.toString()); |
| dispStringBuff.append(dispargString); |
| dispStringBuff.append(')'); |
| if (returnTypeStr != null && returnTypeStr.length() > 0) { |
| dispStringBuff.append(" : "); //$NON-NLS-1$ |
| dispStringBuff.append(returnTypeStr); |
| } |
| String dispString = dispStringBuff.toString(); |
| |
| StringBuilder idStringBuff = new StringBuilder(repStringBuff.toString()); |
| idStringBuff.append(idargString); |
| idStringBuff.append(')'); |
| String idString = idStringBuff.toString(); |
| |
| repStringBuff.append(')'); |
| String repString = repStringBuff.toString(); |
| |
| final int relevance = function instanceof ICPPMethod ? RelevanceConstants.METHOD_TYPE_RELEVANCE |
| : RelevanceConstants.FUNCTION_TYPE_RELEVANCE; |
| CCompletionProposal proposal = createProposal(repString, dispString, idString, context.getCompletionNode() |
| .getLength(), image, baseRelevance + relevance, context, getCElement(function), function.getName()); |
| if (!context.isContextInformationStyle()) { |
| proposal.setCursorPosition(repString.length() - 1); |
| } |
| |
| if (dispargString.length() > 0) { |
| CProposalContextInformation info = new CProposalContextInformation(image, dispString, dispargString); |
| info.setContextInformationPosition(context.getContextInformationOffset()); |
| proposal.setContextInformation(info); |
| } |
| |
| proposals.add(proposal); |
| } |
| |
| private void handleVariable(IVariable variable, CContentAssistInvocationContext context, int baseRelevance, |
| List<ICompletionProposal> proposals) { |
| StringBuilder repStringBuff = new StringBuilder(); |
| repStringBuff.append(variable.getName()); |
| |
| String returnTypeStr = "<unknown>"; //$NON-NLS-1$ |
| try { |
| IType varType = variable.getType(); |
| if (varType != null) { |
| returnTypeStr = ASTTypeUtil.getType(varType, false); |
| } |
| } catch (DOMException e) { |
| } |
| |
| StringBuilder dispStringBuff = new StringBuilder(repStringBuff.toString()); |
| if (returnTypeStr != null) { |
| dispStringBuff.append(" : "); //$NON-NLS-1$ |
| dispStringBuff.append(returnTypeStr); |
| } |
| String dispString = dispStringBuff.toString(); |
| |
| StringBuilder idStringBuff = new StringBuilder(repStringBuff.toString()); |
| String idString = idStringBuff.toString(); |
| |
| String repString = repStringBuff.toString(); |
| |
| Image image = getImage(variable); |
| final int relevance = isLocalVariable(variable) ? RelevanceConstants.LOCAL_VARIABLE_TYPE_RELEVANCE |
| : isField(variable) ? RelevanceConstants.FIELD_TYPE_RELEVANCE |
| : RelevanceConstants.VARIABLE_TYPE_RELEVANCE; |
| CCompletionProposal proposal = createProposal(repString, dispString, idString, context.getCompletionNode() |
| .getLength(), image, baseRelevance + relevance, context, getCElement(variable), variable.getName()); |
| proposals.add(proposal); |
| } |
| |
| private static boolean isField(IVariable variable) { |
| return variable instanceof IField; |
| } |
| |
| private static boolean isLocalVariable(IVariable variable) { |
| try { |
| return isLocalScope(variable.getScope()); |
| } catch (DOMException exc) { |
| return false; |
| } |
| } |
| |
| private static boolean isLocalScope(IScope scope) { |
| while (scope != null) { |
| if (scope instanceof ICPPFunctionScope || scope instanceof ICPPBlockScope |
| || scope instanceof ICFunctionScope) { |
| return true; |
| } |
| try { |
| scope = scope.getParent(); |
| } catch (DOMException e) { |
| scope = null; |
| } |
| } |
| return false; |
| } |
| |
| private void handleNamespace(ICPPNamespace namespace, IASTCompletionContext astContext, |
| CContentAssistInvocationContext cContext, int baseRelevance, List<ICompletionProposal> proposals) { |
| |
| if (astContext instanceof ICPPASTQualifiedName) { |
| IASTCompletionContext parent = ((ICPPASTQualifiedName) astContext).getCompletionContext(); |
| handleNamespace(namespace, parent, cContext, baseRelevance, proposals); |
| return; |
| } |
| |
| StringBuilder repStringBuff = new StringBuilder(); |
| repStringBuff.append(namespace.getName()); |
| |
| if (!(astContext instanceof ICPPASTUsingDeclaration) && !(astContext instanceof ICPPASTUsingDirective)) { |
| repStringBuff.append("::"); //$NON-NLS-1$ |
| } |
| |
| String repString = repStringBuff.toString(); |
| proposals.add(createProposal(repString, namespace.getName(), getImage(namespace), baseRelevance |
| + RelevanceConstants.NAMESPACE_TYPE_RELEVANCE, cContext, getCElement(namespace), namespace.getName())); |
| } |
| |
| private ICElement getCElement(ICPPNamespace namespace) { |
| // ignore |
| return null; |
| } |
| |
| private ICElement getCElement(IVariable variable) { |
| return null; |
| } |
| |
| private ICElement getCElement(IFunction function) { |
| |
| return null; |
| } |
| |
| private ICElement getCElement(ICPPClassType classType) { |
| return null; |
| } |
| |
| private ICElement getCElement(IASTPreprocessorMacroDefinition macro) { |
| try { |
| return getCElement(macro.getFileLocation().getFileName(), macro.getFileLocation().getNodeOffset()); |
| } catch (Exception e) { |
| StatusHandler.log(new Status(IStatus.ERROR, CDTUIBridgePlugin.ID_PLUGIN, |
| "Unable to get CElement for Macro", e)); //$NON-NLS-1$ |
| } |
| return null; |
| } |
| |
| @SuppressWarnings("restriction") |
| private ICElement getCElement(IBinding binding) { |
| IASTNode definition = null; |
| if (binding instanceof ICInternalBinding) { |
| IASTNode[] declarations = ((ICInternalBinding) binding).getDeclarations(); |
| if (declarations != null && declarations.length >= 0) { |
| definition = declarations[0]; |
| } |
| } else if (binding instanceof ICPPInternalBinding) { |
| IASTNode[] declarations = ((ICPPInternalBinding) binding).getDeclarations(); |
| if (declarations != null && declarations.length >= 0) { |
| definition = declarations[0]; |
| } |
| } |
| if (definition != null) { |
| try { |
| return getCElement(definition.getFileLocation().getFileName(), definition.getFileLocation() |
| .getNodeOffset()); |
| } catch (CModelException e) { |
| StatusHandler.log(new Status(IStatus.ERROR, CDTUIBridgePlugin.ID_PLUGIN, |
| "Unable to get CElement for Binding", e)); //$NON-NLS-1$ |
| } |
| } |
| return null; |
| } |
| |
| private ICElement getCElement(String filename, int offset) throws CModelException { |
| |
| IFile res = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(filename)); |
| |
| ITranslationUnit cu = null; |
| if (res instanceof IFile) { |
| IFile file = res; |
| if (CoreModel.isValidTranslationUnitName(null, file.getName())) { |
| cu = CoreModelUtil.findTranslationUnit(file); |
| } else { |
| return null; |
| } |
| } |
| if (cu != null) { |
| ICElement ce = cu.getElementAtOffset(offset); |
| System.out.println(ce); |
| return ce; |
| } else { |
| return null; |
| } |
| } |
| |
| private CCompletionProposal createProposal(String repString, String dispString, Image image, int relevance, |
| CContentAssistInvocationContext context, ICElement element, String bindingName) { |
| return createProposal(repString, dispString, null, context.getCompletionNode().getLength(), image, relevance, |
| context, element, bindingName); |
| } |
| |
| private CCompletionProposal createProposal(String repString, String dispString, int prefixLength, Image image, |
| int relevance, CContentAssistInvocationContext context, ICElement element, String bindingName) { |
| return createProposal(repString, dispString, null, prefixLength, image, relevance, context, element, |
| bindingName); |
| } |
| |
| private CCompletionProposal createProposal(String repString, String dispString, String idString, int prefixLength, |
| Image image, int relevance, CContentAssistInvocationContext context, ICElement element, String bindingName) { |
| int parseOffset = context.getParseOffset(); |
| int invocationOffset = context.getInvocationOffset(); |
| boolean doReplacement = !context.isContextInformationStyle(); |
| |
| int repLength = doReplacement ? prefixLength : 0; |
| int repOffset = doReplacement ? parseOffset - repLength : invocationOffset; |
| repString = doReplacement ? repString : ""; //$NON-NLS-1$ |
| |
| return new CCompletionProposal(repString, repOffset, repLength, image, dispString, idString, relevance, |
| context.getViewer(), element, bindingName); |
| } |
| |
| private Image getImage(ImageDescriptor desc) { |
| return desc != null ? CommonImages.getImage(desc) : null; |
| } |
| |
| private Image getImage(IBinding binding) { |
| ImageDescriptor imageDescriptor = null; |
| |
| try { |
| if (binding instanceof ITypedef) { |
| imageDescriptor = CElementImageProvider.getTypedefImageDescriptor(); |
| } else if (binding instanceof ICompositeType) { |
| if (((ICompositeType) binding).getKey() == ICPPClassType.k_class |
| || binding instanceof ICPPClassTemplate) { |
| imageDescriptor = CElementImageProvider.getClassImageDescriptor(); |
| } else if (((ICompositeType) binding).getKey() == ICompositeType.k_struct) { |
| imageDescriptor = CElementImageProvider.getStructImageDescriptor(); |
| } else if (((ICompositeType) binding).getKey() == ICompositeType.k_union) { |
| imageDescriptor = CElementImageProvider.getUnionImageDescriptor(); |
| } |
| } else if (binding instanceof ICPPMethod) { |
| switch (((ICPPMethod) binding).getVisibility()) { |
| case ICPPMember.v_private: |
| imageDescriptor = CElementImageProvider.getMethodImageDescriptor(ASTAccessVisibility.PRIVATE); |
| break; |
| case ICPPMember.v_protected: |
| imageDescriptor = CElementImageProvider.getMethodImageDescriptor(ASTAccessVisibility.PROTECTED); |
| break; |
| default: |
| imageDescriptor = CElementImageProvider.getMethodImageDescriptor(ASTAccessVisibility.PUBLIC); |
| break; |
| } |
| } else if (binding instanceof IFunction) { |
| imageDescriptor = CElementImageProvider.getFunctionImageDescriptor(); |
| } else if (binding instanceof ICPPField) { |
| switch (((ICPPField) binding).getVisibility()) { |
| case ICPPMember.v_private: |
| imageDescriptor = CElementImageProvider.getFieldImageDescriptor(ASTAccessVisibility.PRIVATE); |
| break; |
| case ICPPMember.v_protected: |
| imageDescriptor = CElementImageProvider.getFieldImageDescriptor(ASTAccessVisibility.PROTECTED); |
| break; |
| default: |
| imageDescriptor = CElementImageProvider.getFieldImageDescriptor(ASTAccessVisibility.PUBLIC); |
| break; |
| } |
| } else if (binding instanceof IField) { |
| imageDescriptor = CElementImageProvider.getFieldImageDescriptor(ASTAccessVisibility.PUBLIC); |
| } else if (binding instanceof IVariable) { |
| imageDescriptor = CElementImageProvider.getVariableImageDescriptor(); |
| } else if (binding instanceof IEnumeration) { |
| imageDescriptor = CElementImageProvider.getEnumerationImageDescriptor(); |
| } else if (binding instanceof IEnumerator) { |
| imageDescriptor = CElementImageProvider.getEnumeratorImageDescriptor(); |
| } else if (binding instanceof ICPPNamespace) { |
| imageDescriptor = CElementImageProvider.getNamespaceImageDescriptor(); |
| } else if (binding instanceof ICPPFunctionTemplate) { |
| imageDescriptor = CElementImageProvider.getFunctionImageDescriptor(); |
| } else if (binding instanceof ICPPUsingDeclaration) { |
| IBinding[] delegates = ((ICPPUsingDeclaration) binding).getDelegates(); |
| if (delegates.length > 0) { |
| return getImage(delegates[0]); |
| } |
| } |
| } catch (DOMException e) { |
| } |
| |
| return imageDescriptor != null ? CommonImages.getImage(imageDescriptor) : null; |
| } |
| } |