Exemple #1
0
 /** 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;
  }