Community
Participate
Working Groups
While recording AST modifications and copySubtree is performed on a node from the same AST, eg: ASTNode x = ast.newXXX ... y = ASTNode.copySubtree(ast, x), when the edit is requested it fails to get the source from the original node with an Assertion exception. I'm not sure if it's my fault, but ASTNode.copySubtree javadoc implies that this is a legal operation. I get the following stack trace when running the attached unit test (irrelevant traces removed): org.eclipse.jface.text.Assert$AssertionFailedException: Assertion failed: at org.eclipse.jface.text.Assert.isTrue(Assert.java:177) at org.eclipse.jface.text.Assert.isTrue(Assert.java:162) at org.eclipse.text.edits.TextEdit.<init>(TextEdit.java:149) at org.eclipse.text.edits.CopySourceEdit.<init>(CopySourceEdit.java:96) at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.getCopySourceEdit (ASTRewriteAnalyzer.java:128) at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.doTextInsert (ASTRewriteAnalyzer.java:984) at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer$ListRewriter.rewrit eList(ASTRewriteAnalyzer.java:461) at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.rewriteParagraphLis t(ASTRewriteAnalyzer.java:837) at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.visit (ASTRewriteAnalyzer.java:1263) at org.eclipse.jdt.core.dom.TypeDeclaration.accept0 (TypeDeclaration.java:469) at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450) at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.doVisit (ASTRewriteAnalyzer.java:249) at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.doVisitList (ASTRewriteAnalyzer.java:280) at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.doVisitUnchangedChi ldren(ASTRewriteAnalyzer.java:298) at org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.visit (ASTRewriteAnalyzer.java:1151) at org.eclipse.jdt.core.dom.CompilationUnit.accept0 (CompilationUnit.java:287) at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450) at org.eclipse.jdt.core.dom.InternalASTRewrite.rewriteAST (InternalASTRewrite.java:71) at org.eclipse.jdt.core.dom.AST.rewrite(AST.java:2642) at org.eclipse.jdt.core.dom.CompilationUnit.rewrite (CompilationUnit.java:853) at jdt.tests.AstRewriteBug.testAstRewriteBug(AstRewriteBug.java:60)
Created attachment 20487 [details] JUnit testcase for the bug
I've found a workaround for this bug. Instead of copying the subtree, make the node orfan and use it. This might even save some bits of memory since copySubTree does not perform COW. This method does the kludge: public static void killParent(ASTNode node) { StructuralPropertyDescriptor locationInParent = node .getLocationInParent(); if (!locationInParent.isChildListProperty()) node.getParent().setStructuralProperty(locationInParent, node.getAST ().newNullLiteral()); else { List list = (List) node.getParent().getStructuralProperty( locationInParent); list.remove(node); } }
Martin, could you please check if this occurs in HEAD?
Bug is in the modifying ast rewrite: A close on a new (non-original) node should not create a copy event. New end original nodes can be distinguised with the 'ASTNode.ORIGINAL' flag. Moving to Daniel
+1 for RC2
Fixed and test added ASTRewritingModifyingCopyTest#test0007() Replaced void postCloneNodeEvent(ASTNode node, ASTNode clone) { this.clonedNodes.put(clone, node); this.cloneDepth--; } by void postCloneNodeEvent(ASTNode node, ASTNode clone) { if(node.ast == root.ast && clone.ast == root.ast) { if((node.getFlags() & ASTNode.ORIGINAL) != 0) { this.clonedNodes.put(clone, node); } else { // node can be a cloned node Object original = this.clonedNodes.get(node); if(original != null) { this.clonedNodes.put(clone, original); } } } this.cloneDepth--; }
Verified in N20050609-0010 + JDT/Core HEAD. Verified that the attached Junit test passed. Result in System.out is: package test; public class Test { void foo(){this.x;} }
Verified in I20050610-0010.