private IName[] findDefinitions( IIndex index, IASTTranslationUnit ast, NameKind kind, IBinding binding) throws CoreException { List<IASTName> declNames = new ArrayList<IASTName>(); declNames.addAll(Arrays.asList(ast.getDefinitionsInAST(binding))); for (Iterator<IASTName> i = declNames.iterator(); i.hasNext(); ) { IASTName name = i.next(); final IBinding b2 = name.resolveBinding(); if (b2 instanceof ICPPUsingDeclaration) { i.remove(); } if (binding != b2 && binding instanceof ICPPSpecialization) { // Make sure binding specializes b2 so that for instance we do not navigate from // one partial specialization to another. IBinding spec = binding; while (spec instanceof ICPPSpecialization) { spec = ((ICPPSpecialization) spec).getSpecializedBinding(); if (spec == b2) break; } if (!(spec instanceof ICPPSpecialization)) { i.remove(); } } } if (!declNames.isEmpty()) { return declNames.toArray(new IASTName[declNames.size()]); } // 2. Try definition in index. return index.findNames( binding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES); }
private IName[] findDeclarations(IIndex index, IASTTranslationUnit ast, IBinding binding) throws CoreException { IName[] declNames = ast.getDeclarationsInAST(binding); for (int i = 0; i < declNames.length; i++) { IName name = declNames[i]; if (name.isDefinition()) declNames[i] = null; } declNames = (IName[]) ArrayUtil.removeNulls(IName.class, declNames); if (declNames.length == 0) { declNames = index.findNames( binding, IIndex.FIND_DECLARATIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES); } return declNames; }
@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); } }