From ce5aae6649a7ae16ed5fe8e2df2889bc3a4ccb0c Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 9 Apr 2008 15:48:37 +0000 Subject: [PATCH] Change generator for nested AST-modifications, by Emanuel Graf, bug 226306. --- .../rewrite/astwriter/StatementWriter.java | 6 +- .../ChangeGeneratorWriterVisitor.java | 47 +++++--- .../ModificationScopeStack.java | 103 ++++++++++++++++++ .../ModifiedASTExpressionWriter.java | 12 +- .../ModifiedASTStatementWriter.java | 8 ++ 5 files changed, 156 insertions(+), 20 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModificationScopeStack.java diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/StatementWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/StatementWriter.java index cfddc858cb6..36238a1cd51 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/StatementWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/StatementWriter.java @@ -376,7 +376,7 @@ public class StatementWriter extends NodeWriter{ private void writeCompoundStatement(IASTCompoundStatement compoundStatement) { scribe.printLBrace(); scribe.newLine(); - for (IASTStatement statements : compoundStatement.getStatements()) { + for (IASTStatement statements : getNestedStatements(compoundStatement)) { statements.accept(visitor); } @@ -389,6 +389,10 @@ public class StatementWriter extends NodeWriter{ decrementIndentationLevelOneMore = false; } scribe.printRBrace(); + } + + protected IASTStatement[] getNestedStatements(IASTCompoundStatement compoundStatement) { + return compoundStatement.getStatements(); } protected void writeBodyStatement(IASTStatement statement, boolean isDoStatement) { 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 7fbfc286b04..b34302feed7 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 @@ -31,25 +31,32 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; 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.ASTModificationMap; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; +/** + * + * Visits the nodes in consideration of {@link ASTModification}s. + * + * @since 5.0 + * @author Emanuel Graf IFS + * + */ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { private static final String DEFAULT_INDENTATION = ""; //$NON-NLS-1$ private final ASTModificationStore modificationStore; - private ASTModificationMap modificationsForScope; private final String fileScope; + private ModificationScopeStack stack; public ChangeGeneratorWriterVisitor(CPPASTVisitor delegateVisitor, ASTModificationStore modificationStore, String fileScope, NodeCommentMap commentMap) { super(commentMap); this.modificationStore = modificationStore; - this.modificationsForScope = modificationStore.getRootModifications(); this.fileScope = fileScope; + this.stack = new ModificationScopeStack(modificationStore); shouldVisitExpressions = delegateVisitor.shouldVisitExpressions; shouldVisitStatements = delegateVisitor.shouldVisitStatements; @@ -83,9 +90,9 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { declSpecWriter = new ModifiedASTDeclSpecWriter(scribe, this, modStore, commentMap); this.modificationStore = modStore; - this.modificationsForScope = modificationStore.getRootModifications(); this.fileScope = fileScope; this.shouldVisitTranslationUnit = true; + this.stack = new ModificationScopeStack(modificationStore); } @Override @@ -133,72 +140,84 @@ 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; } @@ -303,9 +322,12 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { } return PROCESS_SKIP; } + + protected void doAfterEveryNode(IASTNode node) { + stack.popScope(node); + } protected int doBeforeEveryNode(IASTNode node) { - if (fileScope != null) { String file = getCorrespondingFile(node); if (!fileScope.equals(file)) { @@ -313,9 +335,8 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { } } - if (modificationsForScope != null - && modificationsForScope.getModifiedNodes().contains(node)) { - List modificationList = modificationsForScope + if (stack.getModifiedNodes().contains(node)) { + List modificationList = stack .getModificationsForNode(node); if (modificationList == null) { return PROCESS_CONTINUE; @@ -324,19 +345,19 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { 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; } - - ASTModificationMap modificationsForThisScope = modificationsForScope; - modificationsForScope = modificationStore - .getNestedModifications(currentMod); + stack.pushScope(node); currentMod.getNewNode().accept(this); - modificationsForScope = modificationsForThisScope; + stack.popScope(node); break; } } 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 new file mode 100644 index 00000000000..f73f23bc043 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModificationScopeStack.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +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; + +public class ModificationScopeStack { + private LinkedList> scopeStack; + private ASTModificationStore modStore; + + public ModificationScopeStack(ASTModificationStore modificationStore) { + scopeStack = new LinkedList>(); + modStore = modificationStore; + ArrayList nullModList = new ArrayList(); + nullModList.add(null); + scopeStack.addFirst(nullModList); + } + + public void pushScope(IASTNode node) { + List newMods = new ArrayList(); + for(ASTModification peekMod : scopeStack.peek()) { + ASTModificationMap nestedMods = modStore.getNestedModifications(peekMod); + if (nestedMods != null) { + newMods.addAll(nestedMods.getModificationsForNode(node)); + } + } + + if (!newMods.isEmpty()) { + scopeStack.addFirst(newMods); + } + } + + private List getNestedModifikationsForNode(IASTNode node) { + ASTModificationMap rootModifications = modStore.getRootModifications(); + if (rootModifications == null) { + return Collections.emptyList(); + } + return rootModifications.getModificationsForNode(node); + } + + public void popScope(IASTNode node) { + List peek = scopeStack.peek(); + if (peek != null) { + if (!peek.isEmpty() && peek.get(0).getTargetNode() == node) { + scopeStack.removeFirst(); + } + } + } + + public Collection getModifiedNodes() { + List aktModList = scopeStack.peek(); + if (aktModList == null) { + return getNestedModifiedNodes(); + } + Collection nodes = new ArrayList(); + for (ASTModification modification : aktModList) { + ASTModificationMap nestedModifications = modStore.getNestedModifications(modification); + if (nestedModifications != null) { + nodes.addAll(nestedModifications.getModifiedNodes()); + } + } + return Collections.unmodifiableCollection(nodes); + } + + private Collection getNestedModifiedNodes() { + ASTModificationMap rootModifications = modStore.getRootModifications(); + if(rootModifications == null) { + return Collections.emptyList(); + } + return rootModifications.getModifiedNodes(); + } + + public List getModificationsForNode(IASTNode node) { + List aktModList = scopeStack.peek(); + if (aktModList == null) { + return getNestedModifikationsForNode(node); + } + List modForNodeList = new ArrayList(); + for (ASTModification modification : aktModList) { + modForNodeList.addAll(modStore.getNestedModifications(modification).getModificationsForNode(node)); + } + return Collections.unmodifiableList(modForNodeList); + } + +} 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 eb478953ae8..62dadb7858d 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 @@ -27,18 +27,18 @@ import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; public class ModifiedASTExpressionWriter extends ExpressionWriter { - private final ASTModificationHelper modificationHelpder; + private final ASTModificationHelper modificationHelper; public ModifiedASTExpressionWriter(Scribe scribe, CPPASTVisitor visitor, MacroExpansionHandler macroHandler, ASTModificationStore modStore, NodeCommentMap commentMap) { super(scribe, visitor, macroHandler, commentMap); - this.modificationHelpder = new ASTModificationHelper(modStore); + this.modificationHelper = new ASTModificationHelper(modStore); } @Override protected void writeExpressions(IASTExpressionList expList, IASTExpression[] expressions) { - IASTExpression[] modifiedExpressions = modificationHelpder.createModifiedChildArray(expList, expressions); + IASTExpression[] modifiedExpressions = modificationHelper.createModifiedChildArray(expList, expressions); super.writeExpressions(expList, modifiedExpressions); } @@ -49,7 +49,7 @@ public class ModifiedASTExpressionWriter extends ExpressionWriter { IASTExpression initializer = newExp.getNewInitializer(); if(initializer != null){ - for(ASTModification childModification : modificationHelpder.modificationsForNode(initializer)){ + for(ASTModification childModification : modificationHelper.modificationsForNode(initializer)){ switch(childModification.getKind()){ case REPLACE: if(childModification.getNewNode() instanceof IASTInitializer){ @@ -66,7 +66,7 @@ public class ModifiedASTExpressionWriter extends ExpressionWriter { } else { - for(ASTModification parentModification : modificationHelpder.modificationsForNode(newExp)){ + for(ASTModification parentModification : modificationHelper.modificationsForNode(newExp)){ if(parentModification.getKind() == ModificationKind.APPEND_CHILD){ IASTNode newNode = parentModification.getNewNode(); if(newNode instanceof IASTInitializer){ @@ -81,7 +81,7 @@ public class ModifiedASTExpressionWriter extends ExpressionWriter { @Override protected IASTExpression[] getNewTypeIdArrayExpressions( ICPPASTNewExpression newExp, IASTExpression[] expressions) { - IASTExpression[] modifiedExpressions = modificationHelpder.createModifiedChildArray(newExp, expressions); + IASTExpression[] modifiedExpressions = modificationHelper.createModifiedChildArray(newExp, expressions); return modifiedExpressions; } 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 e5d3b98d631..5232835d4c4 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 @@ -11,6 +11,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator; +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; @@ -40,4 +41,11 @@ public class ModifiedASTStatementWriter extends StatementWriter { IASTDeclaration replacementNode = modificationHelper.getNodeAfterReplacement(declaration); super.writeDeclarationWithoutSemicolon(replacementNode); } + + @Override + protected IASTStatement[] getNestedStatements(IASTCompoundStatement compoundStatement) { + return modificationHelper.createModifiedChildArray(compoundStatement, compoundStatement.getStatements()); + } + + }