private IASTFunctionDeclarator findDeclaratorInSelection( ITextSelection selection, IASTTranslationUnit unit) { IASTNode firstNodeInsideSelection = unit.getNodeSelector(null) .findFirstContainedNode(selection.getOffset(), selection.getLength()); IASTFunctionDeclarator declarator = findDeclaratorInAncestors(firstNodeInsideSelection); if (declarator == null) { firstNodeInsideSelection = unit.getNodeSelector(null) .findEnclosingNode(selection.getOffset(), selection.getLength()); declarator = findDeclaratorInAncestors(firstNodeInsideSelection); } return declarator; }
/** Checks if a given region contains at least a piece of a node after rewrite. */ private boolean doesRegionContainNode(IASTTranslationUnit ast, int offset, int length) { IASTNodeSelector nodeSelector = ast.getNodeSelector(ast.getFilePath()); while (length > 0) { IASTNode node = nodeSelector.findFirstContainedNode(offset, length - 1); if (node == null) return false; if (!isNodeRemoved(node)) return true; int oldOffset = offset; offset = endOffset(node); length -= offset - oldOffset; } return false; }
protected IASTName findName(String section, int len) { if (len == 0) len = section.length(); for (int i = 0; i < strategy.getAstCount(); i++) { IASTTranslationUnit ast = strategy.getAst(i); final IASTNodeSelector nodeSelector = ast.getNodeSelector(null); final int offset = strategy.getAstSource(i).indexOf(section); if (offset >= 0) { IASTName name = nodeSelector.findName(offset, len); if (name == null) name = nodeSelector.findImplicitName(offset, len); return name; } } return null; }
@Deprecated public IASTName[] getSelectedNames(IASTTranslationUnit ast, int start, int length) { IASTNode selectedNode = ast.getNodeSelector(null).findNode(start, length); if (selectedNode == null) return new IASTName[0]; if (selectedNode instanceof IASTName) return new IASTName[] {(IASTName) selectedNode}; if (selectedNode instanceof IASTPreprocessorMacroExpansion) { return new IASTName[] {((IASTPreprocessorMacroExpansion) selectedNode).getMacroReference()}; } NameCollector collector = new NameCollector(); selectedNode.accept(collector); return collector.getNames(); }
public MultiMacroExpansionExplorer(IASTTranslationUnit tu, IASTFileLocation loc) { if (tu == null || loc == null || loc.getNodeLength() == 0) { throw new IllegalArgumentException(); } final ILocationResolver resolver = getResolver(tu); final IASTNodeSelector nodeLocator = tu.getNodeSelector(null); final IASTPreprocessorMacroExpansion[] expansions = resolver.getMacroExpansions(loc); final int count = expansions.length; loc = extendLocation(loc, expansions); fMacroLocations = getMacroLocations(resolver); fFilePath = tu.getFilePath(); fSource = resolver.getUnpreprocessedSignature(loc); fBoundaries = new int[count * 2 + 1]; fDelegates = new SingleMacroExpansionExplorer[count]; final int firstOffset = loc.getNodeOffset(); int bidx = -1; int didx = -1; for (IASTPreprocessorMacroExpansion expansion : expansions) { IASTName ref = expansion.getMacroReference(); if (ref != null) { ArrayList<IASTName> refs = new ArrayList<IASTName>(); refs.add(ref); refs.addAll(Arrays.asList(expansion.getNestedMacroReferences())); IASTFileLocation refLoc = expansion.getFileLocation(); int from = refLoc.getNodeOffset() - firstOffset; int to = from + refLoc.getNodeLength(); IASTNode enclosing = nodeLocator.findEnclosingNode(from + firstOffset - 1, 2); boolean isPPCond = enclosing instanceof IASTPreprocessorIfStatement || enclosing instanceof IASTPreprocessorElifStatement; fBoundaries[++bidx] = from; fBoundaries[++bidx] = to; fDelegates[++didx] = new SingleMacroExpansionExplorer( new String(fSource, from, to - from), refs.toArray(new IASTName[refs.size()]), fMacroLocations, fFilePath, refLoc.getStartingLineNumber(), isPPCond, (LexerOptions) tu.getAdapter(LexerOptions.class)); } } fBoundaries[++bidx] = fSource.length; }
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException { if (ast == null) { return Status.OK_STATUS; } int selectionStart = fTextSelection.getOffset(); int selectionLength = fTextSelection.getLength(); final IASTNodeSelector nodeSelector = ast.getNodeSelector(null); IASTName sourceName = nodeSelector.findEnclosingName(selectionStart, selectionLength); IName[] implicitTargets = findImplicitTargets(ast, nodeSelector, selectionStart, selectionLength); if (sourceName == null) { if (implicitTargets.length > 0) { if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, implicitTargets)) return Status.OK_STATUS; } } else { boolean found = false; final IASTNode parent = sourceName.getParent(); if (parent instanceof IASTPreprocessorIncludeStatement) { openInclude(((IASTPreprocessorIncludeStatement) parent)); return Status.OK_STATUS; } NameKind kind = getNameKind(sourceName); IBinding b = sourceName.resolveBinding(); IBinding[] bindings = new IBinding[] {b}; if (b instanceof IProblemBinding) { IBinding[] candidateBindings = ((IProblemBinding) b).getCandidateBindings(); if (candidateBindings.length != 0) { bindings = candidateBindings; } } else if (kind == NameKind.DEFINITION && b instanceof IType) { // Don't navigate away from a type definition. // Select the name at the current location instead. navigateToName(sourceName); return Status.OK_STATUS; } IName[] targets = IName.EMPTY_ARRAY; String filename = ast.getFilePath(); for (IBinding binding : bindings) { if (binding != null && !(binding instanceof IProblemBinding)) { IName[] names = findDeclNames(ast, kind, binding); for (final IName name : names) { if (name != null) { if (name instanceof IIndexName && filename.equals(((IIndexName) name).getFileLocation().getFileName())) { // Exclude index names from the current file. } else if (areOverlappingNames(name, sourceName)) { // Exclude the current location. } else if (binding instanceof IParameter) { if (isInSameFunction(sourceName, name)) { targets = ArrayUtil.append(targets, name); } } else if (binding instanceof ICPPTemplateParameter) { if (isInSameTemplate(sourceName, name)) { targets = ArrayUtil.append(targets, name); } } else { targets = ArrayUtil.append(targets, name); } } } } } targets = ArrayUtil.trim(ArrayUtil.addAll(targets, implicitTargets)); if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, targets)) { found = true; } else { // Leave old method as fallback for local variables, parameters and // everything else not covered by ICElementHandle. found = navigateOneLocation(targets); } if (!found && !navigationFallBack(ast, sourceName, kind)) { fAction.reportSymbolLookupFailure(new String(sourceName.toCharArray())); } return Status.OK_STATUS; } // No enclosing name, check if we're in an include statement IASTNode node = nodeSelector.findEnclosingNode(selectionStart, selectionLength); if (node instanceof IASTPreprocessorIncludeStatement) { openInclude((IASTPreprocessorIncludeStatement) node); return Status.OK_STATUS; } else if (node instanceof IASTPreprocessorFunctionStyleMacroDefinition) { IASTPreprocessorFunctionStyleMacroDefinition mdef = (IASTPreprocessorFunctionStyleMacroDefinition) node; for (IASTFunctionStyleMacroParameter par : mdef.getParameters()) { String parName = par.getParameter(); if (parName.equals(fSelectedText)) { if (navigateToLocation(par.getFileLocation())) { return Status.OK_STATUS; } } } } if (!navigationFallBack(ast, null, NameKind.REFERENCE)) { fAction.reportSelectionMatchFailure(); } return Status.OK_STATUS; }
@Override public void modifyAST(IIndex index, IMarker marker) { CompositeChange c = new CompositeChange(Messages.QuickFixCreateParameter_0); try { ITranslationUnit baseTU = getTranslationUnitViaEditor(marker); IASTTranslationUnit baseAST = baseTU.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS); IASTName astName = getASTNameFromMarker(marker, baseAST); if (astName == null) { return; } IASTDeclaration declaration = CxxAstUtils.createDeclaration(astName, baseAST.getASTNodeFactory(), index); // We'll need a FunctionParameterDeclaration later final IASTDeclSpecifier finalDeclSpec = (IASTDeclSpecifier) declaration.getChildren()[0]; final IASTDeclarator finalDeclarator = (IASTDeclarator) declaration.getChildren()[1]; IASTFunctionDefinition function = CxxAstUtils.getEnclosingFunction(astName); if (function == null) { return; } // Find the function declarations NameFinderVisitor nameFinderVisitor = new NameFinderVisitor(); function.accept(nameFinderVisitor); IASTName funcName = nameFinderVisitor.name; IBinding binding = funcName.resolveBinding(); IIndexName[] declarations = index.findNames(binding, IIndex.FIND_DECLARATIONS_DEFINITIONS); if (declarations.length == 0) { return; } HashMap<ITranslationUnit, IASTTranslationUnit> cachedASTs = new HashMap<ITranslationUnit, IASTTranslationUnit>(); HashMap<ITranslationUnit, ASTRewrite> cachedRewrites = new HashMap<ITranslationUnit, ASTRewrite>(); for (IIndexName iname : declarations) { ITranslationUnit declTU = CxxAstUtils.getTranslationUnitFromIndexName(iname); if (declTU == null) { continue; } ASTRewrite rewrite; IASTTranslationUnit declAST; if (!cachedASTs.containsKey(declTU)) { declAST = declTU.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS); rewrite = ASTRewrite.create(declAST); cachedASTs.put(declTU, declAST); cachedRewrites.put(declTU, rewrite); } else { declAST = cachedASTs.get(declTU); rewrite = cachedRewrites.get(declTU); } IASTFileLocation fileLocation = iname.getFileLocation(); IASTName declName = declAST .getNodeSelector(null) .findEnclosingName(fileLocation.getNodeOffset(), fileLocation.getNodeLength()); if (declName == null) { continue; } INodeFactory factory = declAST.getASTNodeFactory(); IASTFunctionDeclarator functionDecl; { IASTNode n = declName; while (n instanceof IASTName) { n = n.getParent(); } functionDecl = (IASTFunctionDeclarator) n; } IASTParameterDeclaration newParam = factory.newParameterDeclaration(finalDeclSpec, finalDeclarator); rewrite.insertBefore(functionDecl, null, newParam, null); } for (ASTRewrite rewrite : cachedRewrites.values()) { c.add(rewrite.rewriteAST()); } c.perform(new NullProgressMonitor()); } catch (CoreException e) { CheckersUiActivator.log(e); } }