/** 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; }
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; }
/** Returns definitions of bindings referenced by implicit name at the given location. */ private IName[] findImplicitTargets( IASTTranslationUnit ast, IASTNodeSelector nodeSelector, int offset, int length) throws CoreException { IName[] definitions = IName.EMPTY_ARRAY; IASTName firstName = nodeSelector.findEnclosingImplicitName(offset, length); if (firstName != null) { IASTImplicitNameOwner owner = (IASTImplicitNameOwner) firstName.getParent(); for (IASTImplicitName name : owner.getImplicitNames()) { if (((ASTNode) name).getOffset() == ((ASTNode) firstName).getOffset()) { IBinding binding = name.resolveBinding(); // Guaranteed to resolve. IName[] declNames = findDeclNames(ast, NameKind.REFERENCE, binding); definitions = ArrayUtil.addAll(definitions, declNames); } } } return ArrayUtil.trim(definitions); }
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; }