Bug 93208 - [dom] CompilationUnit.rewrite throws AssertionFailedException with legal AST (bug in recoding ast modifications)
Summary: [dom] CompilationUnit.rewrite throws AssertionFailedException with legal AST ...
Status: CLOSED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.0.2   Edit
Hardware: PC Windows NT
: P3 normal (vote)
Target Milestone: 3.1 RC2   Edit
Assignee: David Audel CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-04-28 21:25 EDT by Rodrigo Kumpera CLA
Modified: 2005-06-10 12:10 EDT (History)
0 users

See Also:


Attachments
JUnit testcase for the bug (2.46 KB, text/plain)
2005-04-28 21:27 EDT, Rodrigo Kumpera CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rodrigo Kumpera CLA 2005-04-28 21:25:41 EDT
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)
Comment 1 Rodrigo Kumpera CLA 2005-04-28 21:27:33 EDT
Created attachment 20487 [details]
JUnit testcase for the bug
Comment 2 Rodrigo Kumpera CLA 2005-05-02 15:46:46 EDT
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);
        }
    }
Comment 3 Olivier Thomann CLA 2005-06-07 11:08:49 EDT
Martin, could you please check if this occurs in HEAD?
Comment 4 Martin Aeschlimann CLA 2005-06-07 11:28:33 EDT
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
Comment 5 Philipe Mulet CLA 2005-06-09 09:54:52 EDT
+1 for RC2
Comment 6 David Audel CLA 2005-06-09 09:59:27 EDT
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--;
}
Comment 7 Olivier Thomann CLA 2005-06-09 10:51:27 EDT
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;} }
Comment 8 Olivier Thomann CLA 2005-06-10 12:10:48 EDT
Verified in I20050610-0010.