1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Fix for nested modifications in ChangeGenerator by Emanuel Graf, bug 232255.

This commit is contained in:
Markus Schorn 2008-05-15 14:19:36 +00:00
parent fb6b4d9509
commit 2ce7d65442
11 changed files with 222 additions and 106 deletions

View file

@ -35,7 +35,7 @@ public class ASTModificationMap {
* Adds a modification to this modification map. * Adds a modification to this modification map.
*/ */
public void addModification(ASTModification mod) { 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<ASTModification> mods= fModifications.get(targetNode); List<ASTModification> mods= fModifications.get(targetNode);
if (mods == null || mods.isEmpty()) { if (mods == null || mods.isEmpty()) {
mods= new ArrayList<ASTModification>(); mods= new ArrayList<ASTModification>();

View file

@ -159,7 +159,7 @@ public class DeclarationWriter extends NodeWriter{
templateSpecialization.getDeclaration().accept(visitor); templateSpecialization.getDeclaration().accept(visitor);
} }
private void writeTemplateDeclaration(ICPPASTTemplateDeclaration templateDeclaration) { protected void writeTemplateDeclaration(ICPPASTTemplateDeclaration templateDeclaration) {
if(templateDeclaration.isExported()){ if(templateDeclaration.isExported()){
scribe.print(EXPORT); scribe.print(EXPORT);
} }
@ -190,9 +190,7 @@ public class DeclarationWriter extends NodeWriter{
} }
scribe.printLBrace(); scribe.printLBrace();
scribe.newLine(); scribe.newLine();
for (IASTDeclaration declarations : namespaceDefinition.getDeclarations()) { writeDeclarationsInNamespace(namespaceDefinition, namespaceDefinition.getDeclarations());
declarations.accept(visitor);
}
if(hasFreestandingComments(namespaceDefinition)) { if(hasFreestandingComments(namespaceDefinition)) {
writeFreeStandingComments(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) { private void writeNamespaceAlias(ICPPASTNamespaceAlias namespaceAliasDefinition) {
scribe.print(NAMESPACE); scribe.print(NAMESPACE);
namespaceAliasDefinition.getAlias().accept(visitor); namespaceAliasDefinition.getAlias().accept(visitor);

View file

@ -14,23 +14,22 @@ package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.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.ASTModification.ModificationKind;
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ContainerNode; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ContainerNode;
public class ASTModificationHelper { public class ASTModificationHelper {
private final ASTModificationStore modificationStore; private final ModificationScopeStack modificationStore;
public ASTModificationHelper(ASTModificationStore modificationStore) { public ASTModificationHelper(ModificationScopeStack stack) {
this.modificationStore = modificationStore; this.modificationStore = stack;
} }
@ -48,13 +47,8 @@ public class ASTModificationHelper {
modifiedChildren.remove(childModification.getTargetNode()); modifiedChildren.remove(childModification.getTargetNode());
break; break;
case INSERT_BEFORE: case INSERT_BEFORE:
if (newNode != null) {
modifiedChildren.add(modifiedChildren.indexOf(childModification.getTargetNode()), newNode);
}
break;
case APPEND_CHILD: case APPEND_CHILD:
throw new UnhandledASTModificationException(childModification); throw new UnhandledASTModificationException(childModification);
} }
}catch(ClassCastException e){ }catch(ClassCastException e){
throw new UnhandledASTModificationException(childModification); throw new UnhandledASTModificationException(childModification);
@ -63,11 +57,12 @@ public class ASTModificationHelper {
} }
for(ASTModification parentModification : modificationsForNode(parent)){ for(ASTModification parentModification : modificationsForNode(parent)){
if(parentModification.getKind() == ModificationKind.APPEND_CHILD){ switch(parentModification.getKind()){
case APPEND_CHILD:
IASTNode newNode = parentModification.getNewNode(); IASTNode newNode = parentModification.getNewNode();
T newTNode= cast(newNode, clazz); T appendedTNode = cast(newNode, clazz);
if (newTNode != null) { if (appendedTNode != null) {
modifiedChildren.add(newTNode); modifiedChildren.add(appendedTNode);
} }
else if (newNode instanceof ContainerNode){ else if (newNode instanceof ContainerNode){
ContainerNode nodeContainer = (ContainerNode) newNode; 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<ASTModification> modificationsForNode( public List<ASTModification> modificationsForNode(
IASTNode targetNode) { IASTNode targetNode) {
ASTModificationMap rootModifications = modificationStore.getRootModifications(); List<ASTModification> modificationsForNode;
if(rootModifications == null){ if(modificationStore.getModifiedNodes().contains(targetNode)){
rootModifications = new ASTModificationMap(); modificationsForNode = modificationStore.getModificationsForNode(targetNode);
} }
List<ASTModification> modificationsForNode = rootModifications.getModificationsForNode(targetNode); else{
return modificationsForNode; modificationsForNode = Collections.emptyList();
}
return modificationsForNode;
} }

View file

@ -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.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; 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.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.ASTModification;
import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationMap; 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.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.commenthandler.NodeCommentMap;
import org.eclipse.cdt.internal.core.dom.rewrite.util.FileContentHelper; 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.dom.rewrite.util.FileHelper;
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
@ -52,6 +54,7 @@ import org.eclipse.text.edits.TextEditGroup;
public class ChangeGenerator extends CPPASTVisitor { public class ChangeGenerator extends CPPASTVisitor {
private final LinkedHashMap<String, Integer> sourceOffsets = new LinkedHashMap<String, Integer>(); private final LinkedHashMap<String, Integer> sourceOffsets = new LinkedHashMap<String, Integer>();
public LinkedHashMap<IASTNode, List<ASTModification>> modificationParent = new LinkedHashMap<IASTNode, List<ASTModification>>(); public LinkedHashMap<IASTNode, List<ASTModification>> modificationParent = new LinkedHashMap<IASTNode, List<ASTModification>>();
private final LinkedHashMap<IFile, MultiTextEdit> changes = new LinkedHashMap<IFile, MultiTextEdit>(); private final LinkedHashMap<IFile, MultiTextEdit> changes = new LinkedHashMap<IFile, MultiTextEdit>();
@ -117,25 +120,58 @@ public class ChangeGenerator extends CPPASTVisitor {
for (IASTNode modifiedNode : rootModifications.getModifiedNodes()) { for (IASTNode modifiedNode : rootModifications.getModifiedNodes()) {
List<ASTModification> modificationsForNode = rootModifications List<ASTModification> modificationsForNode = rootModifications
.getModificationsForNode(modifiedNode); .getModificationsForNode(modifiedNode);
modificationParent.put(modifiedNode.getParent(), IASTNode modifiedNodeParent = determineParentToBeRewritten(modifiedNode, modificationsForNode);
modificationParent.put(modifiedNodeParent != null ? modifiedNodeParent : modifiedNode,
modificationsForNode); modificationsForNode);
} }
} }
} }
private IASTNode determineParentToBeRewritten(IASTNode modifiedNode, List<ASTModification> 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 @Override
public int visit(IASTTranslationUnit translationUnit) { public int visit(IASTTranslationUnit translationUnit) {
if (hasChangedChild(translationUnit)) { if (hasChangedChild(translationUnit)) {
synthTreatment(translationUnit); synthTreatment(translationUnit);
} }
final IASTFileLocation fileLocation = translationUnit.getFileLocation(); IASTFileLocation location = getFileLocationOfEmptyTranslationUnit(translationUnit);
if (fileLocation != null) { sourceOffsets.put(location.getFileName(),
sourceOffsets.put(fileLocation.getFileName(), Integer.valueOf(location.getNodeOffset()));
Integer.valueOf(fileLocation.getNodeOffset()));
}
return super.visit(translationUnit); 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 @Override
public int leave(IASTTranslationUnit tu) { public int leave(IASTTranslationUnit tu) {
@ -164,7 +200,6 @@ public class ChangeGenerator extends CPPASTVisitor {
} }
private void synthTreatment(IASTNode synthNode, String fileScope) { private void synthTreatment(IASTNode synthNode, String fileScope) {
String indent = getIndent(synthNode); String indent = getIndent(synthNode);
ASTWriter synthWriter = new ASTWriter(indent); ASTWriter synthWriter = new ASTWriter(indent);
synthWriter.setModificationStore(modificationStore); synthWriter.setModificationStore(modificationStore);
@ -184,8 +219,9 @@ public class ChangeGenerator extends CPPASTVisitor {
synthWriter.setModificationStore(modificationStore); synthWriter.setModificationStore(modificationStore);
for (ASTModification modification : modificationParent.get(synthTU)) { for (ASTModification modification : modificationParent.get(synthTU)) {
IASTFileLocation targetLocation = modification.getTargetNode() IASTFileLocation targetLocation;
.getFileLocation();
targetLocation = getFileLocationOfEmptyTranslationUnit(modification.getTargetNode());
String currentFile = targetLocation.getFileName(); String currentFile = targetLocation.getFileName();
IPath implPath = new Path(currentFile); IPath implPath = new Path(currentFile);
IFile relevantFile = ResourcesPlugin.getWorkspace().getRoot() IFile relevantFile = ResourcesPlugin.getWorkspace().getRoot()
@ -209,8 +245,9 @@ public class ChangeGenerator extends CPPASTVisitor {
newNodeCode)); newNodeCode));
break; break;
case APPEND_CHILD: case APPEND_CHILD:
edit.addChild(new InsertEdit(targetLocation.getNodeOffset() String lineDelimiter = FileHelper.determineLineDelimiter(FileHelper.getIFilefromIASTNode(modification.getTargetNode()));
+ targetLocation.getNodeLength(), newNodeCode)); edit.addChild(new InsertEdit(targetLocation.getNodeOffset()
+ targetLocation.getNodeLength(),lineDelimiter + lineDelimiter + newNodeCode));
break; break;
} }
} }
@ -236,7 +273,7 @@ public class ChangeGenerator extends CPPASTVisitor {
.getFirstPositionOfCommonEndInSynthCode(lastCommonPositionInSynthCode, lastCommonPositionInOriginalCode); .getFirstPositionOfCommonEndInSynthCode(lastCommonPositionInSynthCode, lastCommonPositionInOriginalCode);
int firstPositionOfCommonEndInOriginalCode = codeComparer int firstPositionOfCommonEndInOriginalCode = codeComparer
.getFirstPositionOfCommonEndInOriginalCode(lastCommonPositionInSynthCode); .getFirstPositionOfCommonEndInOriginalCode(lastCommonPositionInOriginalCode, lastCommonPositionInSynthCode);
if (firstPositionOfCommonEndInSynthCode == -1) { if (firstPositionOfCommonEndInSynthCode == -1) {
formattedCode.append(synthSource formattedCode.append(synthSource
.substring(lastCommonPositionInSynthCode + 1)); .substring(lastCommonPositionInSynthCode + 1));
@ -300,6 +337,7 @@ public class ChangeGenerator extends CPPASTVisitor {
return modificationParent.containsKey(parent); return modificationParent.containsKey(parent);
} }
@Override @Override
public int visit(IASTDeclarator declarator) { public int visit(IASTDeclarator declarator) {
if (hasChangedChild(declarator)) { if (hasChangedChild(declarator)) {
@ -308,6 +346,16 @@ public class ChangeGenerator extends CPPASTVisitor {
} }
return super.visit(declarator); return super.visit(declarator);
} }
@Override
public int visit(ICPPASTNamespaceDefinition namespaceDefinition) {
if(hasChangedChild(namespaceDefinition)){
synthTreatment(namespaceDefinition);
return ASTVisitor.PROCESS_SKIP;
}
return super.visit(namespaceDefinition);
}
@Override @Override
public int visit(IASTDeclSpecifier declSpec) { public int visit(IASTDeclSpecifier declSpec) {
@ -413,7 +461,7 @@ public class ChangeGenerator extends CPPASTVisitor {
return lastCommonPosition; return lastCommonPosition;
} }
public int getFirstPositionOfCommonEndInOriginalCode(int limmit) { public int getFirstPositionOfCommonEndInOriginalCode(int originalLimit, int synthLimit) {
int lastCommonPosition = -1; int lastCommonPosition = -1;
int originalCodePosition = -1; int originalCodePosition = -1;
@ -431,8 +479,9 @@ public class ChangeGenerator extends CPPASTVisitor {
synthCodePosition = nextInterrestingPosition(reverseSynthCode, synthCodePosition = nextInterrestingPosition(reverseSynthCode,
synthCodePosition); synthCodePosition);
} while (originalCodePosition > -1 } while (originalCodePosition > -1
&& originalCodePosition < originalCode.length() - originalLimit
&& synthCodePosition > -1 && synthCodePosition > -1
&& synthCodePosition < synthCode.length() - limmit && synthCodePosition < synthCode.length() - synthLimit
&& reverseOriginalCode.charAt(originalCodePosition) == reverseSynthCode && reverseOriginalCode.charAt(originalCodePosition) == reverseSynthCode
.charAt(synthCodePosition)); .charAt(synthCodePosition));
@ -473,6 +522,7 @@ public class ChangeGenerator extends CPPASTVisitor {
synthCodePosition); synthCodePosition);
} while (originalCodePosition > -1 } while (originalCodePosition > -1
&& originalCodePosition < originalCode.length() - lastCommonPositionInOriginal
&& synthCodePosition > -1 && synthCodePosition > -1
&& synthCodePosition < synthCode.length() - limmit && synthCodePosition < synthCode.length() - limmit
&& reverseOriginalCode.charAt(originalCodePosition) == reverseSynthCode && reverseOriginalCode.charAt(originalCodePosition) == reverseSynthCode
@ -531,9 +581,9 @@ public class ChangeGenerator extends CPPASTVisitor {
private void createChange(MultiTextEdit edit, int changeOffset) { private void createChange(MultiTextEdit edit, int changeOffset) {
int lastCommonPositionInSynth = getLastCommonPositionInSynthCode();
int firstOfCommonEndInOriginal = getFirstPositionOfCommonEndInOriginalCode(lastCommonPositionInSynth);
int lastCommonPositionInOriginal = getLastCommonPositionInOriginalCode(); int lastCommonPositionInOriginal = getLastCommonPositionInOriginalCode();
int lastCommonPositionInSynth = getLastCommonPositionInSynthCode();
int firstOfCommonEndInOriginal = getFirstPositionOfCommonEndInOriginalCode(lastCommonPositionInOriginal, lastCommonPositionInSynth);
int firstOfCommonEndInSynth = getFirstPositionOfCommonEndInSynthCode( int firstOfCommonEndInSynth = getFirstPositionOfCommonEndInSynthCode(
lastCommonPositionInSynth, lastCommonPositionInOriginal); lastCommonPositionInSynth, lastCommonPositionInOriginal);

View file

@ -11,8 +11,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator; 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.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; 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.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification; 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.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.astwriter.ASTWriterVisitor;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
@ -82,17 +81,19 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor {
public ChangeGeneratorWriterVisitor(ASTModificationStore modStore, public ChangeGeneratorWriterVisitor(ASTModificationStore modStore,
String givenIndentation, String fileScope, NodeCommentMap commentMap) { String givenIndentation, String fileScope, NodeCommentMap commentMap) {
super(givenIndentation, 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.modificationStore = modStore;
this.fileScope = fileScope; this.fileScope = fileScope;
this.shouldVisitTranslationUnit = true; this.shouldVisitTranslationUnit = true;
this.stack = new ModificationScopeStack(modificationStore); 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 @Override
@ -140,84 +141,72 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor {
@Override @Override
public int leave(IASTDeclaration declaration) { public int leave(IASTDeclaration declaration) {
super.leave(declaration); super.leave(declaration);
doAfterEveryNode(declaration);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTDeclarator declarator) { public int leave(IASTDeclarator declarator) {
super.leave(declarator); super.leave(declarator);
doAfterEveryNode(declarator);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTDeclSpecifier declSpec) { public int leave(IASTDeclSpecifier declSpec) {
super.leave(declSpec); super.leave(declSpec);
doAfterEveryNode(declSpec);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTEnumerator enumerator) { public int leave(IASTEnumerator enumerator) {
super.leave(enumerator); super.leave(enumerator);
doAfterEveryNode(enumerator);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTExpression expression) { public int leave(IASTExpression expression) {
super.leave(expression); super.leave(expression);
doAfterEveryNode(expression);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTInitializer initializer) { public int leave(IASTInitializer initializer) {
super.leave(initializer); super.leave(initializer);
doAfterEveryNode(initializer);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTName name) { public int leave(IASTName name) {
super.leave(name); super.leave(name);
doAfterEveryNode(name);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTParameterDeclaration parameterDeclaration) { public int leave(IASTParameterDeclaration parameterDeclaration) {
super.leave(parameterDeclaration); super.leave(parameterDeclaration);
doAfterEveryNode(parameterDeclaration);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTProblem problem) { public int leave(IASTProblem problem) {
super.leave(problem); super.leave(problem);
doAfterEveryNode(problem);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTStatement statement) { public int leave(IASTStatement statement) {
super.leave(statement); super.leave(statement);
doAfterEveryNode(statement);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTTranslationUnit tu) { public int leave(IASTTranslationUnit tu) {
super.leave(tu); super.leave(tu);
doAfterEveryNode(tu);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@Override @Override
public int leave(IASTTypeId typeId) { public int leave(IASTTypeId typeId) {
super.leave(typeId); super.leave(typeId);
doAfterEveryNode(typeId);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -304,7 +293,7 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor {
@Override @Override
public int visit(IASTTranslationUnit tu) { public int visit(IASTTranslationUnit tu) {
ASTModificationHelper helper = new ASTModificationHelper( ASTModificationHelper helper = new ASTModificationHelper(
modificationStore); stack);
IASTDeclaration[] declarations = helper.createModifiedChildArray(tu, tu.getDeclarations(), IASTDeclaration.class); IASTDeclaration[] declarations = helper.createModifiedChildArray(tu, tu.getDeclarations(), IASTDeclaration.class);
for (IASTDeclaration currentDeclaration : declarations) { for (IASTDeclaration currentDeclaration : declarations) {
@ -321,48 +310,42 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor {
} }
return PROCESS_SKIP; return PROCESS_SKIP;
} }
protected void doAfterEveryNode(IASTNode node) {
stack.popScope(node);
}
protected int doBeforeEveryNode(IASTNode node) { protected int doBeforeEveryNode(IASTNode node) {
stack.clean(node);
if (fileScope != null) { if (fileScope != null) {
String file = getCorrespondingFile(node); String file = getCorrespondingFile(node);
if (!fileScope.equals(file)) { if (!fileScope.equals(file)) {
return PROCESS_SKIP; return PROCESS_SKIP;
} }
} }
if (stack.getModifiedNodes().contains(node)) { for (IASTNode currentModifiedNode : stack.getModifiedNodes()) {
List<ASTModification> modificationList = stack for (ASTModification currentMod : stack.getModificationsForNode(currentModifiedNode)) {
.getModificationsForNode(node); if(currentMod.getNewNode() == node){
if (modificationList == null) { if(currentMod.getKind() != ModificationKind.REPLACE) {
return PROCESS_CONTINUE; stack.pushScope(currentModifiedNode);
} 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;
} }
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; return PROCESS_CONTINUE;
} }

View file

@ -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.ASTModification;
import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationMap; 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.ASTModificationStore;
import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification.ModificationKind;
public class ModificationScopeStack { public class ModificationScopeStack {
private LinkedList<List<ASTModification>> scopeStack; private LinkedList<List<ASTModification>> scopeStack;
@ -59,8 +60,14 @@ public class ModificationScopeStack {
public void popScope(IASTNode node) { public void popScope(IASTNode node) {
List<ASTModification> peek = scopeStack.peek(); List<ASTModification> peek = scopeStack.peek();
if (peek != null) { if (peek != null) {
if (!peek.isEmpty() && peek.get(0).getTargetNode() == node) { if (!peek.isEmpty() && peek.get(0)!=null) {
scopeStack.removeFirst(); 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); 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<ASTModification> 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;
}
} }

View file

@ -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.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; 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.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.DeclSpecWriter;
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.Scribe; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.Scribe;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
@ -23,9 +22,9 @@ public class ModifiedASTDeclSpecWriter extends DeclSpecWriter {
private final ASTModificationHelper modificationHelper; 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); super(scribe, visitor, commentMap);
this.modificationHelper = new ASTModificationHelper(modificationStore); this.modificationHelper = new ASTModificationHelper(stack);
} }
@Override @Override

View file

@ -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);
}
}

View file

@ -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.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; 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.DeclaratorWriter;
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.Scribe; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.Scribe;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
@ -35,9 +34,9 @@ public class ModifiedASTDeclaratorWriter extends DeclaratorWriter {
private final ASTModificationHelper modificationHelper; 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); super(scribe, visitor, commentMap);
this.modificationHelper = new ASTModificationHelper(modificationStore); this.modificationHelper = new ASTModificationHelper(stack);
} }
@Override @Override

View file

@ -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.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; 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.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.ASTModification.ModificationKind;
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ExpressionWriter; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ExpressionWriter;
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.MacroExpansionHandler; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.MacroExpansionHandler;
@ -30,9 +29,9 @@ public class ModifiedASTExpressionWriter extends ExpressionWriter {
private final ASTModificationHelper modificationHelper; private final ASTModificationHelper modificationHelper;
public ModifiedASTExpressionWriter(Scribe scribe, CPPASTVisitor visitor, public ModifiedASTExpressionWriter(Scribe scribe, CPPASTVisitor visitor,
MacroExpansionHandler macroHandler, ASTModificationStore modStore, NodeCommentMap commentMap) { MacroExpansionHandler macroHandler, ModificationScopeStack stack, NodeCommentMap commentMap) {
super(scribe, visitor, macroHandler, commentMap); super(scribe, visitor, macroHandler, commentMap);
this.modificationHelper = new ASTModificationHelper(modStore); this.modificationHelper = new ASTModificationHelper(stack);
} }
@Override @Override

View file

@ -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.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; 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.Scribe;
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.StatementWriter; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.StatementWriter;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
@ -24,9 +23,9 @@ public class ModifiedASTStatementWriter extends StatementWriter {
private final ASTModificationHelper modificationHelper; 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); super(scribe, visitor, commentMap);
this.modificationHelper = new ASTModificationHelper(modStore); this.modificationHelper = new ASTModificationHelper(stack);
} }
@Override @Override