public void test_toLTK_Change_MergeCompositeChange() throws Exception { IFile testFile = testProject.setFileContent("test.dart", "012345"); Source source = createFileSource(testFile); // fill SourceChange SourceChange sourceChangeA = new SourceChange("My change A", source); SourceChange sourceChangeB = new SourceChange("My change B", source); sourceChangeA.addEdit(new Edit(0, 0, "a")); sourceChangeB.addEdit(new Edit(2, 0, "b")); CompositeChange compositeChangeA = new CompositeChange("A", sourceChangeA); CompositeChange compositeChangeB = new CompositeChange("B", sourceChangeB); MergeCompositeChange mergeChange = new MergeCompositeChange("My composite change", compositeChangeA, compositeChangeB); // toLTK org.eclipse.ltk.core.refactoring.Change ltkChange_ = ServiceUtils.toLTK(mergeChange); org.eclipse.ltk.core.refactoring.CompositeChange ltkChange = (org.eclipse.ltk.core.refactoring.CompositeChange) ltkChange_; assertEquals("My composite change", ltkChange.getName()); org.eclipse.ltk.core.refactoring.Change[] ltkChanges = ltkChange.getChildren(); assertThat(ltkChanges).hasSize(2); // ltkChange.perform(NULL_PM); String newContent = testProject.getFileString(testFile); assertEquals("a01b2345", newContent); }
@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); } }