1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Bug 427002. [ast rewrite] Comments originating from other translation

units are now automatically taken into consideration when rewriting.

Change-Id: If535ab6cdd1ec293a0d95a6f726d848f6348f0ed
Signed-off-by: Lukas Felber <l.felber@gmx.ch>
Reviewed-on: https://git.eclipse.org/r/21761
Reviewed-by: Thomas Corbat <tcorbat@hsr.ch>
IP-Clean: Thomas Corbat <tcorbat@hsr.ch>
Tested-by: Thomas Corbat <tcorbat@hsr.ch>
This commit is contained in:
Lukas Felber 2014-02-10 16:28:28 +01:00 committed by Thomas Corbat
parent 8000c7fe61
commit c558463abe
7 changed files with 129 additions and 12 deletions

View file

@ -97,15 +97,15 @@ public class CommentHandlingTest extends RewriteBaseTest {
for (String fileName : fileMap.keySet()) { for (String fileName : fileMap.keySet()) {
TestSourceFile file = fileMap.get(fileName); TestSourceFile file = fileMap.get(fileName);
NodeCommentMap nodeMap = ASTCommenter.getCommentedNodeMap(getUnit(fileName)); NodeCommentMap nodeMap = getNodeMapForFile(fileName);
assertEquals(buildExpectedResult(file).toString(), buildActualResult(nodeMap).toString());
StringBuilder expectedResultBuilder = buildExpectedResult(file);
StringBuilder actualResultBuilder = buildActualResult(nodeMap);
assertEquals(expectedResultBuilder.toString(), actualResultBuilder.toString());
} }
} }
protected NodeCommentMap getNodeMapForFile(String fileName) throws Exception {
return ASTCommenter.getCommentedNodeMap(getUnit(fileName));
}
private StringBuilder buildExpectedResult(TestSourceFile file) { private StringBuilder buildExpectedResult(TestSourceFile file) {
Matcher matcher = Pattern.compile(CommentHandlingTest.getSeparatingRegexp(), Matcher matcher = Pattern.compile(CommentHandlingTest.getSeparatingRegexp(),
Pattern.MULTILINE | Pattern.DOTALL).matcher(file.getExpectedSource()); Pattern.MULTILINE | Pattern.DOTALL).matcher(file.getExpectedSource());
@ -177,7 +177,7 @@ public class CommentHandlingTest extends RewriteBaseTest {
ANY_CHAR_REGEXP + FREESTANDING_COMMENT_SEPARATOR + ANY_CHAR_REGEXP; ANY_CHAR_REGEXP + FREESTANDING_COMMENT_SEPARATOR + ANY_CHAR_REGEXP;
} }
private IASTTranslationUnit getUnit(String fileName) throws CoreException { protected IASTTranslationUnit getUnit(String fileName) throws CoreException {
ITranslationUnit tu = (ITranslationUnit) CCorePlugin.getDefault().getCoreModel().create( ITranslationUnit tu = (ITranslationUnit) CCorePlugin.getDefault().getCoreModel().create(
project.getFile(fileName)); project.getFile(fileName));
return tu.getAST(); return tu.getAST();

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik * Copyright (c) 2008, 2014 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others * Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
@ -23,8 +23,8 @@ public class CommentHandlingTestSuite extends TestSuite {
public static Test suite() throws Exception { public static Test suite() throws Exception {
TestSuite suite = new TestSuite(CommentHandlingTestSuite.class.getName()); TestSuite suite = new TestSuite(CommentHandlingTestSuite.class.getName());
suite.addTest(RewriteTester.suite("CommentTests", suite.addTest(RewriteTester.suite("CommentTests", "resources/rewrite/CommentHandlingTestSource.rts")); //$NON-NLS-1$
"resources/rewrite/CommentHandlingTestSource.rts")); //$NON-NLS-1$ suite.addTest(RewriteTester.suite("CommentMultiFileTests", "resources/rewrite/CommentHandlingWithRewriteTest.rts")); //$NON-NLS-1$
suite.addTestSuite(NodeCommentMapTest.class); suite.addTestSuite(NodeCommentMapTest.class);
return suite; return suite;
} }

View file

@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2014 Institute for Software.
* 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:
* Lukas Felber (IFS) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.rewrite.comenthandler;
import java.lang.reflect.Field;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.cdt.core.parser.tests.rewrite.TestSourceFile;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
import org.eclipse.text.edits.TextEditGroup;
public class CommentHandlingWithRewriteTest extends CommentHandlingTest {
private ASTRewrite newRewrite;
public CommentHandlingWithRewriteTest(String name, List<TestSourceFile> files) {
super(name, files);
}
@Override
protected void runTest() throws Throwable {
IASTTranslationUnit tu = getUnit("main.cpp");
IASTTranslationUnit otherTu = getUnit("other.cpp");
IASTNodeSelector selector = tu.getNodeSelector(null);
IASTNodeSelector otherSelector = otherTu.getNodeSelector(null);
IASTNode fooBody = selector.findNode(11, 27);
IASTNode iNode = selector.findEnclosingNode(26, 10).getParent();
IASTNode jNode = otherSelector.findNode(20, 10);
ASTRewrite rewrite = ASTRewrite.create(tu);
newRewrite = rewrite.insertBefore(fooBody, iNode, jNode, new TextEditGroup("test group"));
super.runTest();
}
@Override
protected NodeCommentMap getNodeMapForFile(String fileName) throws Exception {
if (fileName.equals("main.cpp")) {
return getNodeMapFromRewrite(newRewrite);
}
return super.getNodeMapForFile(fileName);
}
private NodeCommentMap getNodeMapFromRewrite(ASTRewrite rewrite) throws Exception {
Field commentMapField = rewrite.getClass().getDeclaredField("fCommentMap");
commentMapField.setAccessible(true);
return (NodeCommentMap) commentMapField.get(rewrite);
}
}

View file

@ -0,0 +1,21 @@
//!Comment Handling Test - Rewrite with otherTu node
//#org.eclipse.cdt.core.parser.tests.rewrite.comenthandler.CommentHandlingWithRewriteTest
//@main.cpp
void foo() {
//comment1
int i = 0;
}
//=
=>leading
int j = 1; = //other.cpp comment
int i = 0; = //comment1
=>trailing
=>freestanding
//@other.cpp
//other.cpp comment
int j = 1;
//=
=>leading
int j = 1; = //other.cpp comment
=>trailing
=>freestanding

View file

@ -188,6 +188,7 @@ public final class ASTRewrite {
} }
mod= new ASTModification(ModificationKind.INSERT_BEFORE, insertionPoint, newNode, editGroup); mod= new ASTModification(ModificationKind.INSERT_BEFORE, insertionPoint, newNode, editGroup);
} }
ASTCommenter.addCommentsToMap(newNode.getTranslationUnit(), fCommentMap);
fModificationStore.storeModification(fParentMod, mod); fModificationStore.storeModification(fParentMod, mod);
return new ASTRewrite(newNode, fModificationStore, mod, fCommentMap); return new ASTRewrite(newNode, fModificationStore, mod, fCommentMap);
} }

View file

@ -179,6 +179,23 @@ public class ASTCommenter {
if (ast == null) { if (ast == null) {
return commentMap; return commentMap;
} }
addCommentsToMap(ast, commentMap);
return commentMap;
}
/**
* Adds all comments given in {@code ast} to the {@code commentMap}. Calling this twice will have no
* effect.
*
* @param ast
* the AST which contains the comments to add
* @param commentMap
* the comment map to which the comments are added to
*/
public static void addCommentsToMap(IASTTranslationUnit ast, NodeCommentMap commentMap) {
if (ast == null || commentMap.isASTCovered(ast)) {
return;
}
IASTComment[] commentsArray = ast.getComments(); IASTComment[] commentsArray = ast.getComments();
List<IASTComment> comments = new ArrayList<IASTComment>(commentsArray.length); List<IASTComment> comments = new ArrayList<IASTComment>(commentsArray.length);
for (IASTComment comment : commentsArray) { for (IASTComment comment : commentsArray) {
@ -189,8 +206,8 @@ public class ASTCommenter {
assignPreprocessorComments(commentMap, comments, ast); assignPreprocessorComments(commentMap, comments, ast);
CommentHandler commentHandler = new CommentHandler(comments); CommentHandler commentHandler = new CommentHandler(comments);
ASTCommenterVisitor commenter = new ASTCommenterVisitor(commentHandler, commentMap); ASTCommenterVisitor commenter = new ASTCommenterVisitor(commentHandler, commentMap);
commentMap.setASTCovered(ast);
ast.accept(commenter); ast.accept(commenter);
return commentMap;
} }
private static boolean isCommentDirectlyBeforePreprocessorStatement(IASTComment comment, private static boolean isCommentDirectlyBeforePreprocessorStatement(IASTComment comment,

View file

@ -19,6 +19,7 @@ import java.util.Map;
import org.eclipse.cdt.core.dom.ast.IASTComment; import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.rewrite.util.ASTNodes; import org.eclipse.cdt.internal.core.dom.rewrite.util.ASTNodes;
/** /**
@ -32,6 +33,7 @@ public class NodeCommentMap {
protected final Map<IASTNode, List<IASTComment>> leadingMap = new HashMap<IASTNode, List<IASTComment>>(); protected final Map<IASTNode, List<IASTComment>> leadingMap = new HashMap<IASTNode, List<IASTComment>>();
protected final Map<IASTNode, List<IASTComment>> trailingMap = new HashMap<IASTNode, List<IASTComment>>(); protected final Map<IASTNode, List<IASTComment>> trailingMap = new HashMap<IASTNode, List<IASTComment>>();
protected final Map<IASTNode, List<IASTComment>> freestandingMap = new HashMap<IASTNode, List<IASTComment>>(); protected final Map<IASTNode, List<IASTComment>> freestandingMap = new HashMap<IASTNode, List<IASTComment>>();
protected final List<IASTTranslationUnit> coveredUnits = new ArrayList<IASTTranslationUnit>();
/** /**
* Add a comment to the map with the trailing comments. * Add a comment to the map with the trailing comments.
@ -188,4 +190,19 @@ public class NodeCommentMap {
} }
return endOffset; return endOffset;
} }
/**
* Makes this comment map aware that comments of the given {@code ast} are already contained in the map.
* This can be used to make sure no-one accidentally tries to re-add already contained comments.
*/
public void setASTCovered(IASTTranslationUnit ast) {
coveredUnits.add(ast);
}
/**
* Checks whether comments of the {@code ast} are already present in the map.
*/
public boolean isASTCovered(IASTTranslationUnit ast) {
return coveredUnits.contains(ast);
}
} }