Home » Language IDEs » ServerTools (WTP) » JSDT multiple modifications with single ASTRewrite
JSDT multiple modifications with single ASTRewrite [message #556741] |
Thu, 02 September 2010 13:45 |
Harald Finster Messages: 37 Registered: July 2009 |
Member |
|
|
Hello,
are there any problems and/or restrictions on the number/kind
of modifications which may be performed with a single ASTRewrite
when editing JavaScript documents using JSDT?
To be more specific, I have the following problem.
I create an ASTRewrite with the following snippet:
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(document.get().toCharArray());
JavaScriptUnit unit = (JavaScriptUnit) parser.createAST(null);
ASTRewrite rewrite = ASTRewrite.create(unit.getAST());
then I perform several modifications using the rewrite
(see below for details) and apply the modifications as
follows:
TextEdit edits = rewrite.rewriteAST(document, null);
edits.apply(document);
The following cases work fine with the code below
if applied in isolation
1) replacing a VariableDeclarationFragment (see code below)
2) adding a TextElement to the fragments of the comment (see code below)
However, the modification of the comment (2) is ignored
if I try to combine it with (1). The order does not
seem to make any difference.
This is the test code:
package test;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.wst.jsdt.core.dom.AST;
import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.ASTParser;
import org.eclipse.wst.jsdt.core.dom.JSdoc;
import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit;
import org.eclipse.wst.jsdt.core.dom.TagElement;
import org.eclipse.wst.jsdt.core.dom.TextElement;
import org.eclipse.wst.jsdt.core.dom.VariableDeclarationFragment;
import org.eclipse.wst.jsdt.core.dom.VariableDeclarationStatement;
import org.eclipse.wst.jsdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.wst.jsdt.core.dom.rewrite.ListRewrite;
public class TestRewrite {
/**
* @param args
* @throws BadLocationException
* @throws MalformedTreeException
*/
public static void main(String[] args) throws MalformedTreeException,
BadLocationException {
System.out.println("TestRewrite");
Document document = new Document(
"/**\n* @tag1 value1\n*/\nvar x;\nvar y;");
System.out.println("initial document\n" + document.get());
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(document.get().toCharArray());
JavaScriptUnit unit = (JavaScriptUnit) parser.createAST(null);
System.out.println("initial AST\n" + unit);
ASTRewrite rewrite = ASTRewrite.create(unit.getAST());
// case 1
substituteVariableDeclaration(rewrite, unit);
// case 2
addDocumentFragment(rewrite, unit);
TextEdit edits = rewrite.rewriteAST(document, null);
System.out.println("edits\n" + edits);
edits.apply(document);
System.out.println("modified document\n" + document.get());
}
/**
* substitute the 0th VariableDeclarationFragment of the 0th Statement
* ("var x;") with a new VariableDeclarationFragment ("var newX")
*/
private static void substituteVariableDeclaration(ASTRewrite rewrite,
JavaScriptUnit unit) {
// get the old fragment (var x;)
//
VariableDeclarationStatement stmt = (VariableDeclarationStatement) unit
.statements().get(0);
VariableDeclarationFragment oldFragment = (VariableDeclarationFragment) stmt
.fragments().get(0);
// create a new fragment (var newX)
//
VariableDeclarationFragment newFragment = unit.getAST()
.newVariableDeclarationFragment();
newFragment.setName(unit.getAST().newSimpleName("newX"));
rewrite.replace(oldFragment, newFragment, null);
}
private static void addDocumentFragment(ASTRewrite rewrite,
JavaScriptUnit unit) {
//
// get the 0th comment fragment of the 0th comment
//
JSdoc doc = (JSdoc) unit.getCommentList().get(0);
TagElement tag = (TagElement) doc.tags().get(0);
TextElement fragment = (TextElement) tag.fragments().get(0);
// append new text element
//
ListRewrite listRewrite = rewrite.getListRewrite(tag,
TagElement.FRAGMENTS_PROPERTY);
TextElement text = (TextElement) rewrite.createStringPlaceholder(
"new-fragment", ASTNode.TEXT_ELEMENT);
listRewrite.insertLast(text, null);
}
}
if I use substituteVariableDeclaration(rewrite, unit); only the output is
TestRewrite
initial document
/**
* @tag1 value1
*/
var x;
var y;
initial AST
var x;
var y;
edits
{MultiTextEdit} [26,1] [undefined]
{InsertEdit} [26,0] <<newX
{DeleteEdit} [26,1]
modified document
/**
* @tag1 value1
*/
var newX;
var y;
(correct)
if I use addDocumentFragment(rewrite, unit); only the output is
....
edits
{MultiTextEdit} [18,0] [undefined]
{InsertEdit} [18,0] <<
{InsertEdit} [18,0] <<new-fragment
modified document
/**
* @tag1 value1 new-fragment
*/
var x;
var y;
(correct)
if I use both methods, i.e.
substituteVariableDeclaration(rewrite, unit);
addDocumentFragment(rewrite, unit);
the output is
....
edits
{MultiTextEdit} [26,1] [undefined]
{InsertEdit} [26,0] <<newX
{DeleteEdit} [26,1]
modified document
/**
* @tag1 value1
*/
var newX;
var y;
which is not correct (well, at least not what I would expect),
as the "new-fragment" text is missing.
Note: I also tried to add a VariableDeclarationStatement in
conjunction with the replacement operation and it worked fine.
So, performing multiple edits with a single rewrite does
not seem to be a problem in principle. (?)
Thanks for your feedback in advance!
Kind regards
Harald Finster
P.S. I am using
JavaScript Developer Tools
Version: 1.1.1.v200906091427-77-FGBCcNBC-BeMcEeOm
Build id: 20090616035105
|
|
| | |
Re: (solved/work around) JSDT multiple modifications with single ASTRewrite [message #556995 is a reply to message #556988] |
Fri, 03 September 2010 14:24 |
Harald Finster Messages: 37 Registered: July 2009 |
Member |
|
|
Hello,
I found the following workaround:
Create a new MultiTextEdit
Create a new rewrite for each modification of the AST
Add the edits retreived from the rewriter as children to the MultiTextEdit
after all modifications have been done:
Apply the edits 'collected' in the MultiTextEdit to the document.
Harald
P.S.
anyways:
could one of the JSDT gurus please check, if there is a bug in the (JSDT) AST rewrite mechanism?
Harald Finster schrieb:
> Hello,
>
> further nvestigation of the matter reveals the following:
>
> The problem seems to occur only, if the comment in question
> is a child of the modified statement.
>
> The following modification works fine:
>
> original document:
> /**
> * @tag value
> */
> var x;
> var y;
>
> modifications:
> - add text element "newValue" to jsdoc fragment
> - modify 1st VariableDeclarationStatement (var y;)
>
> modified document:
> /**
> * @tag value newValue
> */
> var x;
> var newY;
>
>
> This one does not work (same original document):
>
> modifications:
> - add text element "newValue" to jsdoc fragment
> - modify 0th VariableDeclarationStatement (var x;)
>
> modified document:
> /**
> * @tag value (*** nothin happens ***)
> */
> var newX;
> var y;
>
>
>
> I did some debugging in ASTRewriterAnalyser and found some
> 'suspicious' code in visit(VariableDeclarationStatement node):
>
> doVisitUnchaged seems to make the visitor visit the JSdoc
> comments. However this seems to be executed only, if the node
> does not have any children changes.
> Thus, if "var x;" is modified to "var newX;" the node has
> children changes (the VariableDeclarationStatement) and the
> child JSdoc comment is not visited.
>
> A quick-and-probably-extremely-dirty hack would be to
> call "doVisitUnchangedChildren()" in any case.
> (At least this solsves my problem.) However, I suspect, that
> this might cause some bad side effects.
>
>
> Any thoughts?
>
> Greetings Harald
>
>
>
>
>
>
>
>
>
>
> Harald Finster schrieb:
>> Hello,
>>
>> addditional info:
>> I tested the same with a target platform based on
>> Helios, namely
>>
>> JavaScript Development Tools
>> Version: 1.2.0.v201005270528-7C78FGDF9JgLWLMBWz-Ose6
>> Build id: 20100615235519
>>
>>>
>>> JavaScript Developer Tools
>>> Version: 1.1.1.v200906091427-77-FGBCcNBC-BeMcEeOm
>>> Build id: 20090616035105
>>>
|
|
|
Goto Forum:
Current Time: Thu Sep 26 03:17:22 GMT 2024
Powered by FUDForum. Page generated in 0.06050 seconds
|