From 2ce7d6544253266c8e33a0cd1dfa060d0b26ccdb Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 15 May 2008 14:19:36 +0000 Subject: [PATCH] Fix for nested modifications in ChangeGenerator by Emanuel Graf, bug 232255. --- .../core/dom/rewrite/ASTModificationMap.java | 2 +- .../rewrite/astwriter/DeclarationWriter.java | 12 ++- .../ASTModificationHelper.java | 48 ++++++---- .../changegenerator/ChangeGenerator.java | 82 +++++++++++++---- .../ChangeGeneratorWriterVisitor.java | 87 ++++++++----------- .../ModificationScopeStack.java | 52 ++++++++++- .../ModifiedASTDeclSpecWriter.java | 5 +- .../ModifiedASTDeclarationWriter.java | 25 ++++++ .../ModifiedASTDeclaratorWriter.java | 5 +- .../ModifiedASTExpressionWriter.java | 5 +- .../ModifiedASTStatementWriter.java | 5 +- 11 files changed, 222 insertions(+), 106 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclarationWriter.java diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTModificationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTModificationMap.java index 46db04febaf..b07fd4ec1b2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTModificationMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTModificationMap.java @@ -35,7 +35,7 @@ public class ASTModificationMap { * Adds a modification to this modification map. */ public void addModification(ASTModification mod) { - final IASTNode targetNode = mod.getTargetNode(); + final IASTNode targetNode = mod.getKind()==ASTModification.ModificationKind.INSERT_BEFORE ? mod.getTargetNode().getParent() :mod.getTargetNode(); List mods= fModifications.get(targetNode); if (mods == null || mods.isEmpty()) { mods= new ArrayList(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclarationWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclarationWriter.java index a631a5d4a3e..5b3823bb7e3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclarationWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclarationWriter.java @@ -159,7 +159,7 @@ public class DeclarationWriter extends NodeWriter{ templateSpecialization.getDeclaration().accept(visitor); } - private void writeTemplateDeclaration(ICPPASTTemplateDeclaration templateDeclaration) { + protected void writeTemplateDeclaration(ICPPASTTemplateDeclaration templateDeclaration) { if(templateDeclaration.isExported()){ scribe.print(EXPORT); } @@ -190,9 +190,7 @@ public class DeclarationWriter extends NodeWriter{ } scribe.printLBrace(); scribe.newLine(); - for (IASTDeclaration declarations : namespaceDefinition.getDeclarations()) { - declarations.accept(visitor); - } + writeDeclarationsInNamespace(namespaceDefinition, namespaceDefinition.getDeclarations()); if(hasFreestandingComments(namespaceDefinition)) { writeFreeStandingComments(namespaceDefinition); } @@ -205,6 +203,12 @@ public class DeclarationWriter extends NodeWriter{ } } + protected void writeDeclarationsInNamespace(ICPPASTNamespaceDefinition namespaceDefinition, IASTDeclaration[] declarations) { + for (IASTDeclaration declaration : declarations) { + declaration.accept(visitor); + } + } + private void writeNamespaceAlias(ICPPASTNamespaceAlias namespaceAliasDefinition) { scribe.print(NAMESPACE); namespaceAliasDefinition.getAlias().accept(visitor); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java index fb1c516dee8..df3366f683b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java @@ -14,23 +14,22 @@ package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification; -import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationMap; -import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification.ModificationKind; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ContainerNode; public class ASTModificationHelper { - private final ASTModificationStore modificationStore; + private final ModificationScopeStack modificationStore; - public ASTModificationHelper(ASTModificationStore modificationStore) { - this.modificationStore = modificationStore; + public ASTModificationHelper(ModificationScopeStack stack) { + this.modificationStore = stack; } @@ -48,13 +47,8 @@ public class ASTModificationHelper { modifiedChildren.remove(childModification.getTargetNode()); break; case INSERT_BEFORE: - if (newNode != null) { - modifiedChildren.add(modifiedChildren.indexOf(childModification.getTargetNode()), newNode); - } - break; case APPEND_CHILD: throw new UnhandledASTModificationException(childModification); - } }catch(ClassCastException e){ throw new UnhandledASTModificationException(childModification); @@ -63,11 +57,12 @@ public class ASTModificationHelper { } for(ASTModification parentModification : modificationsForNode(parent)){ - if(parentModification.getKind() == ModificationKind.APPEND_CHILD){ + switch(parentModification.getKind()){ + case APPEND_CHILD: IASTNode newNode = parentModification.getNewNode(); - T newTNode= cast(newNode, clazz); - if (newTNode != null) { - modifiedChildren.add(newTNode); + T appendedTNode = cast(newNode, clazz); + if (appendedTNode != null) { + modifiedChildren.add(appendedTNode); } else if (newNode instanceof ContainerNode){ ContainerNode nodeContainer = (ContainerNode) newNode; @@ -78,6 +73,18 @@ public class ASTModificationHelper { } } } + break; + + case INSERT_BEFORE: + T insertedTNode = cast(parentModification.getNewNode(), clazz); + + int targetNodeIndex = modifiedChildren.indexOf(parentModification.getTargetNode()); + if(targetNodeIndex >= 0){ + modifiedChildren.add(targetNodeIndex, insertedTNode); + } + break; + + case REPLACE: } } @@ -101,12 +108,15 @@ public class ASTModificationHelper { public List modificationsForNode( IASTNode targetNode) { - ASTModificationMap rootModifications = modificationStore.getRootModifications(); - if(rootModifications == null){ - rootModifications = new ASTModificationMap(); + List modificationsForNode; + if(modificationStore.getModifiedNodes().contains(targetNode)){ + modificationsForNode = modificationStore.getModificationsForNode(targetNode); } - List modificationsForNode = rootModifications.getModificationsForNode(targetNode); - return modificationsForNode; + else{ + modificationsForNode = Collections.emptyList(); + } + return modificationsForNode; + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java index 04c2ba7ddfb..67a53836e3e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java @@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationMap; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; @@ -37,6 +38,7 @@ import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.ASTCommenter; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; import org.eclipse.cdt.internal.core.dom.rewrite.util.FileContentHelper; import org.eclipse.cdt.internal.core.dom.rewrite.util.FileHelper; +import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; @@ -52,6 +54,7 @@ import org.eclipse.text.edits.TextEditGroup; public class ChangeGenerator extends CPPASTVisitor { + private final LinkedHashMap sourceOffsets = new LinkedHashMap(); public LinkedHashMap> modificationParent = new LinkedHashMap>(); private final LinkedHashMap changes = new LinkedHashMap(); @@ -117,25 +120,58 @@ public class ChangeGenerator extends CPPASTVisitor { for (IASTNode modifiedNode : rootModifications.getModifiedNodes()) { List modificationsForNode = rootModifications .getModificationsForNode(modifiedNode); - modificationParent.put(modifiedNode.getParent(), + IASTNode modifiedNodeParent = determineParentToBeRewritten(modifiedNode, modificationsForNode); + modificationParent.put(modifiedNodeParent != null ? modifiedNodeParent : modifiedNode, modificationsForNode); } } } + private IASTNode determineParentToBeRewritten(IASTNode modifiedNode, List modificationsForNode) { + IASTNode modifiedNodeParent = modifiedNode; + for(ASTModification currentModification : modificationsForNode){ + if(currentModification.getKind() != ASTModification.ModificationKind.APPEND_CHILD){ + modifiedNodeParent = modifiedNode.getParent(); + break; + } + } + modifiedNodeParent = modifiedNodeParent != null ? modifiedNodeParent : modifiedNode; + return modifiedNodeParent; + } + @Override public int visit(IASTTranslationUnit translationUnit) { if (hasChangedChild(translationUnit)) { synthTreatment(translationUnit); } - final IASTFileLocation fileLocation = translationUnit.getFileLocation(); - if (fileLocation != null) { - sourceOffsets.put(fileLocation.getFileName(), - Integer.valueOf(fileLocation.getNodeOffset())); - } + IASTFileLocation location = getFileLocationOfEmptyTranslationUnit(translationUnit); + sourceOffsets.put(location.getFileName(), + Integer.valueOf(location.getNodeOffset())); return super.visit(translationUnit); } + + /** + * This is a Workaround for a known but not jet solved Problem in IASTNode. If you get the FileFocation of a translationUnit + * that was built on an empty file you will get null because there it explicitly returns null if the index and length is 0. + * To get to the Filename and other information, the location is never the less needed. + * @param node + * @return a hopefully "unnull" FileLocation + */ + public IASTFileLocation getFileLocationOfEmptyTranslationUnit(IASTNode node) { + IASTFileLocation fileLocation = node.getFileLocation(); + if (fileLocation == null) { + ILocationResolver lr = (ILocationResolver) node.getTranslationUnit().getAdapter(ILocationResolver.class); + if (lr != null) { + fileLocation = lr.getMappedFileLocation(0, 0); + } else { + // support for old location map + fileLocation = node.getTranslationUnit().flattenLocationsToFile(node.getNodeLocations()); + } + } + + return fileLocation; + } @Override public int leave(IASTTranslationUnit tu) { @@ -164,7 +200,6 @@ public class ChangeGenerator extends CPPASTVisitor { } private void synthTreatment(IASTNode synthNode, String fileScope) { - String indent = getIndent(synthNode); ASTWriter synthWriter = new ASTWriter(indent); synthWriter.setModificationStore(modificationStore); @@ -184,8 +219,9 @@ public class ChangeGenerator extends CPPASTVisitor { synthWriter.setModificationStore(modificationStore); for (ASTModification modification : modificationParent.get(synthTU)) { - IASTFileLocation targetLocation = modification.getTargetNode() - .getFileLocation(); + IASTFileLocation targetLocation; + + targetLocation = getFileLocationOfEmptyTranslationUnit(modification.getTargetNode()); String currentFile = targetLocation.getFileName(); IPath implPath = new Path(currentFile); IFile relevantFile = ResourcesPlugin.getWorkspace().getRoot() @@ -209,8 +245,9 @@ public class ChangeGenerator extends CPPASTVisitor { newNodeCode)); break; case APPEND_CHILD: - edit.addChild(new InsertEdit(targetLocation.getNodeOffset() - + targetLocation.getNodeLength(), newNodeCode)); + String lineDelimiter = FileHelper.determineLineDelimiter(FileHelper.getIFilefromIASTNode(modification.getTargetNode())); + edit.addChild(new InsertEdit(targetLocation.getNodeOffset() + + targetLocation.getNodeLength(),lineDelimiter + lineDelimiter + newNodeCode)); break; } } @@ -236,7 +273,7 @@ public class ChangeGenerator extends CPPASTVisitor { .getFirstPositionOfCommonEndInSynthCode(lastCommonPositionInSynthCode, lastCommonPositionInOriginalCode); int firstPositionOfCommonEndInOriginalCode = codeComparer - .getFirstPositionOfCommonEndInOriginalCode(lastCommonPositionInSynthCode); + .getFirstPositionOfCommonEndInOriginalCode(lastCommonPositionInOriginalCode, lastCommonPositionInSynthCode); if (firstPositionOfCommonEndInSynthCode == -1) { formattedCode.append(synthSource .substring(lastCommonPositionInSynthCode + 1)); @@ -300,6 +337,7 @@ public class ChangeGenerator extends CPPASTVisitor { return modificationParent.containsKey(parent); } + @Override public int visit(IASTDeclarator declarator) { if (hasChangedChild(declarator)) { @@ -308,6 +346,16 @@ public class ChangeGenerator extends CPPASTVisitor { } return super.visit(declarator); } + + + @Override + public int visit(ICPPASTNamespaceDefinition namespaceDefinition) { + if(hasChangedChild(namespaceDefinition)){ + synthTreatment(namespaceDefinition); + return ASTVisitor.PROCESS_SKIP; + } + return super.visit(namespaceDefinition); + } @Override public int visit(IASTDeclSpecifier declSpec) { @@ -413,7 +461,7 @@ public class ChangeGenerator extends CPPASTVisitor { return lastCommonPosition; } - public int getFirstPositionOfCommonEndInOriginalCode(int limmit) { + public int getFirstPositionOfCommonEndInOriginalCode(int originalLimit, int synthLimit) { int lastCommonPosition = -1; int originalCodePosition = -1; @@ -431,8 +479,9 @@ public class ChangeGenerator extends CPPASTVisitor { synthCodePosition = nextInterrestingPosition(reverseSynthCode, synthCodePosition); } while (originalCodePosition > -1 + && originalCodePosition < originalCode.length() - originalLimit && synthCodePosition > -1 - && synthCodePosition < synthCode.length() - limmit + && synthCodePosition < synthCode.length() - synthLimit && reverseOriginalCode.charAt(originalCodePosition) == reverseSynthCode .charAt(synthCodePosition)); @@ -473,6 +522,7 @@ public class ChangeGenerator extends CPPASTVisitor { synthCodePosition); } while (originalCodePosition > -1 + && originalCodePosition < originalCode.length() - lastCommonPositionInOriginal && synthCodePosition > -1 && synthCodePosition < synthCode.length() - limmit && reverseOriginalCode.charAt(originalCodePosition) == reverseSynthCode @@ -531,9 +581,9 @@ public class ChangeGenerator extends CPPASTVisitor { private void createChange(MultiTextEdit edit, int changeOffset) { - int lastCommonPositionInSynth = getLastCommonPositionInSynthCode(); - int firstOfCommonEndInOriginal = getFirstPositionOfCommonEndInOriginalCode(lastCommonPositionInSynth); int lastCommonPositionInOriginal = getLastCommonPositionInOriginalCode(); + int lastCommonPositionInSynth = getLastCommonPositionInSynthCode(); + int firstOfCommonEndInOriginal = getFirstPositionOfCommonEndInOriginalCode(lastCommonPositionInOriginal, lastCommonPositionInSynth); int firstOfCommonEndInSynth = getFirstPositionOfCommonEndInSynthCode( lastCommonPositionInSynth, lastCommonPositionInOriginal); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java index 8821f0414ba..2a1a1662590 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java @@ -11,8 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator; -import java.util.List; - import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; @@ -32,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; +import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification.ModificationKind; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; @@ -82,17 +81,19 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { public ChangeGeneratorWriterVisitor(ASTModificationStore modStore, String givenIndentation, String fileScope, NodeCommentMap commentMap) { super(givenIndentation, commentMap); - declaratorWriter = new ModifiedASTDeclaratorWriter(scribe, this, - modStore, commentMap); - expWriter = new ModifiedASTExpressionWriter(scribe, this, macroHandler, - modStore, commentMap); - statementWriter = new ModifiedASTStatementWriter(scribe, this, modStore, commentMap); - declSpecWriter = new ModifiedASTDeclSpecWriter(scribe, this, modStore, commentMap); - this.modificationStore = modStore; this.fileScope = fileScope; this.shouldVisitTranslationUnit = true; this.stack = new ModificationScopeStack(modificationStore); + declaratorWriter = new ModifiedASTDeclaratorWriter(scribe, this, + stack, commentMap); + expWriter = new ModifiedASTExpressionWriter(scribe, this, macroHandler, + stack, commentMap); + statementWriter = new ModifiedASTStatementWriter(scribe, this, stack, commentMap); + declSpecWriter = new ModifiedASTDeclSpecWriter(scribe, this, stack, commentMap); + declarationWriter = new ModifiedASTDeclarationWriter(scribe, this, stack, commentMap); + + } @Override @@ -140,84 +141,72 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { @Override public int leave(IASTDeclaration declaration) { super.leave(declaration); - doAfterEveryNode(declaration); return PROCESS_SKIP; } @Override public int leave(IASTDeclarator declarator) { super.leave(declarator); - doAfterEveryNode(declarator); return PROCESS_SKIP; } @Override public int leave(IASTDeclSpecifier declSpec) { super.leave(declSpec); - doAfterEveryNode(declSpec); return PROCESS_SKIP; } @Override public int leave(IASTEnumerator enumerator) { super.leave(enumerator); - doAfterEveryNode(enumerator); return PROCESS_SKIP; } @Override public int leave(IASTExpression expression) { super.leave(expression); - doAfterEveryNode(expression); return PROCESS_SKIP; } @Override public int leave(IASTInitializer initializer) { super.leave(initializer); - doAfterEveryNode(initializer); return PROCESS_SKIP; } @Override public int leave(IASTName name) { super.leave(name); - doAfterEveryNode(name); return PROCESS_SKIP; } @Override public int leave(IASTParameterDeclaration parameterDeclaration) { super.leave(parameterDeclaration); - doAfterEveryNode(parameterDeclaration); return PROCESS_SKIP; } @Override public int leave(IASTProblem problem) { super.leave(problem); - doAfterEveryNode(problem); return PROCESS_SKIP; } @Override public int leave(IASTStatement statement) { super.leave(statement); - doAfterEveryNode(statement); return PROCESS_SKIP; } @Override public int leave(IASTTranslationUnit tu) { super.leave(tu); - doAfterEveryNode(tu); return PROCESS_SKIP; } @Override public int leave(IASTTypeId typeId) { super.leave(typeId); - doAfterEveryNode(typeId); return PROCESS_SKIP; } @@ -304,7 +293,7 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { @Override public int visit(IASTTranslationUnit tu) { ASTModificationHelper helper = new ASTModificationHelper( - modificationStore); + stack); IASTDeclaration[] declarations = helper.createModifiedChildArray(tu, tu.getDeclarations(), IASTDeclaration.class); for (IASTDeclaration currentDeclaration : declarations) { @@ -321,48 +310,42 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { } return PROCESS_SKIP; } - - protected void doAfterEveryNode(IASTNode node) { - stack.popScope(node); - } protected int doBeforeEveryNode(IASTNode node) { + stack.clean(node); if (fileScope != null) { String file = getCorrespondingFile(node); if (!fileScope.equals(file)) { return PROCESS_SKIP; } } - - if (stack.getModifiedNodes().contains(node)) { - List modificationList = stack - .getModificationsForNode(node); - if (modificationList == null) { - return PROCESS_CONTINUE; - } - - for (ASTModification currentMod : modificationList) { - switch (currentMod.getKind()) { - case APPEND_CHILD: - stack.pushScope(node); - return PROCESS_CONTINUE; - case INSERT_BEFORE: - stack.pushScope(node); - return PROCESS_CONTINUE; - case REPLACE: - - if (currentMod.getNewNode() == null) { - continue; + + for (IASTNode currentModifiedNode : stack.getModifiedNodes()) { + for (ASTModification currentMod : stack.getModificationsForNode(currentModifiedNode)) { + if(currentMod.getNewNode() == node){ + if(currentMod.getKind() != ModificationKind.REPLACE) { + stack.pushScope(currentModifiedNode); + return PROCESS_CONTINUE; } - stack.pushScope(node); - currentMod.getNewNode().accept(this); - stack.popScope(node); - break; } } - - return PROCESS_SKIP; } + for (IASTNode currentModifiedNode : stack.getModifiedNodes()) { + for (ASTModification currentMod : stack.getModificationsForNode(currentModifiedNode)) { + if(currentMod.getTargetNode() == node && currentMod.getKind() == ModificationKind.REPLACE){ + if(currentMod.getNewNode() != null){ + stack.pushScope(node); + currentMod.getNewNode().accept(this); + stack.popScope(node); + return PROCESS_SKIP; + } + else{ + return PROCESS_SKIP; + } + } + } + } + return PROCESS_CONTINUE; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModificationScopeStack.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModificationScopeStack.java index f73f23bc043..f589480a8a0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModificationScopeStack.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModificationScopeStack.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationMap; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; +import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification.ModificationKind; public class ModificationScopeStack { private LinkedList> scopeStack; @@ -59,8 +60,14 @@ public class ModificationScopeStack { public void popScope(IASTNode node) { List peek = scopeStack.peek(); if (peek != null) { - if (!peek.isEmpty() && peek.get(0).getTargetNode() == node) { - scopeStack.removeFirst(); + if (!peek.isEmpty() && peek.get(0)!=null) { + if( peek.get(0).getKind() == ModificationKind.REPLACE){ + if(peek.get(0).getTargetNode() == node) + scopeStack.removeFirst(); + } + else if(peek.get(0).getNewNode() == node){ + scopeStack.removeFirst(); + } } } } @@ -100,4 +107,45 @@ public class ModificationScopeStack { return Collections.unmodifiableList(modForNodeList); } + public void clean(IASTNode actualNode) { + while(scopeStack.size() > 1){ + for (IASTNode currentModifiedNode : getModifiedNodes()) { + for (ASTModification currentMod : getModificationsForNode(currentModifiedNode)) { + if(currentMod.getNewNode() == actualNode){ + return; + } + } + } + if(!nodeIsChildOfModifications(actualNode, scopeStack.getFirst())){ + scopeStack.removeFirst(); + } + else{ + return; + } + } + } + + private boolean nodeIsChildOfModifications(IASTNode actualNode, + List modifications) { + for(ASTModification currentModification : modifications){ + if(currentModification != null && nodeIsChildOfModification(currentModification, actualNode)){ + return true; + } + } + return false; + } + + private boolean nodeIsChildOfModification( + ASTModification modification, IASTNode actualNode) { + IASTNode nodeToTest = actualNode; + while(nodeToTest != null){ + if(modification.getNewNode() == nodeToTest){ + return true; + } + else{ + nodeToTest = nodeToTest.getParent(); + } + } + return false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java index 2e249dbfe3a..8fb0597b1f4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java @@ -14,7 +14,6 @@ package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; -import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.DeclSpecWriter; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.Scribe; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; @@ -23,9 +22,9 @@ public class ModifiedASTDeclSpecWriter extends DeclSpecWriter { private final ASTModificationHelper modificationHelper; - public ModifiedASTDeclSpecWriter(Scribe scribe, CPPASTVisitor visitor, ASTModificationStore modificationStore, NodeCommentMap commentMap) { + public ModifiedASTDeclSpecWriter(Scribe scribe, CPPASTVisitor visitor, ModificationScopeStack stack, NodeCommentMap commentMap) { super(scribe, visitor, commentMap); - this.modificationHelper = new ASTModificationHelper(modificationStore); + this.modificationHelper = new ASTModificationHelper(stack); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclarationWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclarationWriter.java new file mode 100644 index 00000000000..83bbc255d37 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclarationWriter.java @@ -0,0 +1,25 @@ +package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator; + +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; +import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.DeclarationWriter; +import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.Scribe; +import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; + +public class ModifiedASTDeclarationWriter extends DeclarationWriter { + + private final ASTModificationHelper modificationHelper; + + public ModifiedASTDeclarationWriter(Scribe scribe, CPPASTVisitor visitor, ModificationScopeStack stack, NodeCommentMap commentMap) { + super(scribe, visitor, commentMap); + this.modificationHelper = new ASTModificationHelper(stack); + } + + @Override + protected void writeDeclarationsInNamespace(ICPPASTNamespaceDefinition namespaceDefinition, IASTDeclaration[] declarations) { + IASTDeclaration[] modifiedDeclarations = modificationHelper.createModifiedChildArray(namespaceDefinition, declarations, IASTDeclaration.class); + super.writeDeclarationsInNamespace(namespaceDefinition, modifiedDeclarations); + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java index 1a3db3621af..04b45a16afd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java @@ -25,7 +25,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; -import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.DeclaratorWriter; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.Scribe; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; @@ -35,9 +34,9 @@ public class ModifiedASTDeclaratorWriter extends DeclaratorWriter { private final ASTModificationHelper modificationHelper; - public ModifiedASTDeclaratorWriter(Scribe scribe, CPPASTVisitor visitor, ASTModificationStore modificationStore, NodeCommentMap commentMap) { + public ModifiedASTDeclaratorWriter(Scribe scribe, CPPASTVisitor visitor, ModificationScopeStack stack, NodeCommentMap commentMap) { super(scribe, visitor, commentMap); - this.modificationHelper = new ASTModificationHelper(modificationStore); + this.modificationHelper = new ASTModificationHelper(stack); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java index 9940c0fdc6f..00eb6ddcf81 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java @@ -18,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification; -import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification.ModificationKind; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ExpressionWriter; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.MacroExpansionHandler; @@ -30,9 +29,9 @@ public class ModifiedASTExpressionWriter extends ExpressionWriter { private final ASTModificationHelper modificationHelper; public ModifiedASTExpressionWriter(Scribe scribe, CPPASTVisitor visitor, - MacroExpansionHandler macroHandler, ASTModificationStore modStore, NodeCommentMap commentMap) { + MacroExpansionHandler macroHandler, ModificationScopeStack stack, NodeCommentMap commentMap) { super(scribe, visitor, macroHandler, commentMap); - this.modificationHelper = new ASTModificationHelper(modStore); + this.modificationHelper = new ASTModificationHelper(stack); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTStatementWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTStatementWriter.java index 156a84ffd5a..11de14f18f9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTStatementWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTStatementWriter.java @@ -15,7 +15,6 @@ import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; -import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.Scribe; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.StatementWriter; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; @@ -24,9 +23,9 @@ public class ModifiedASTStatementWriter extends StatementWriter { private final ASTModificationHelper modificationHelper; - public ModifiedASTStatementWriter(Scribe scribe, CPPASTVisitor visitor, ASTModificationStore modStore, NodeCommentMap commentMap) { + public ModifiedASTStatementWriter(Scribe scribe, CPPASTVisitor visitor, ModificationScopeStack stack, NodeCommentMap commentMap) { super(scribe, visitor, commentMap); - this.modificationHelper = new ASTModificationHelper(modStore); + this.modificationHelper = new ASTModificationHelper(stack); } @Override