| JSDT multiple modifications with single ASTRewrite [message #556741] |
Thu, 02 September 2010 09: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
|
|
|