How to add an expression to an array initializer?
I'm trying to change
String[] a = {"un"};
into
String[] a = {"un","deux"};
Problem : I need to add
- a token : COMMA
- an expression
, and
initializer.addXXX(newExp);
only accepts PsiElement, and the token COMMA is not a PsiElement.
It must be stupidly simple, but I can't find it.
TIA
Alain
Please sign in to leave a comment.
Hmm, I didn't try this myself, but I can think of two ways:
1. PsiVariableInitializer.add() takes care of the commas itself, so simply calling
initializer.addXXX(newExp);
should be enough. But I think you probably already tried that :)
2. A nasty one: create the comma yourself by e.g. doing a
dummy = elementFactory.createFieldFromText("Object[] dummy = {null, null}");
and traverse the dummy element until you find the PsiJavaToken that represents the
comma and use this (or a copy of itself) where you need it.
Just a guess though, I've got no idea how the 'official' way to do this looks like :)
Sascha
Alain Ravet wrote:
>
>
>
>
>
>
>
>
>
>
>
Alain,
I am afraid there is no 'official' way to do it :(
(which is one of the hugest problem with our PSI, the other being
null values).
It would be great if PsiArrayInitializer either took care of commas in
'add' method or provided a specific 'addInitializer'.
Unfortunately we have never had to do it in IDEA, hence it does neither.
The best (TM) way to it is to create an initilizer of length you need
from text and then populate its values from your old initializer and
from your new expression.
Friendly,
Dmitry
Alain Ravet wrote:
--
Dmitry Lomov
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"
Sascha Weinrenuter wrote:
> Hmm, I didn't try this myself, but I can think of two ways:
> 1. PsiVariableInitializer.add()
Nope. Doesn't work.
> 2. A nasty one:
Look like the only possible way (see Dmitry's reply).
Thanks.
Alain
Dmitry Lomov (JetBrains) wrote:
> I am afraid there is no 'official' way to do it :(
Too bad.
> Unfortunately we have never had to do it in IDEA, hence
> it does neither.
In case you wonder why on earth I need it, I'm adding microrefactorings,
to transform :
String[] days = {"Monday"};
..
String newDay = "Tuesday" ;
into
String[] days = {"Monday", "Tuesday"};
..
String newDay = days[1] ;
Alain
Actually, I just need to turn a token into an element.
Something very basic, like :
PsiElement reusedComma = PsiMagic.convert(PsiJavaToken.COMMA) ;
How can I do that?
Alain
Alain Ravet wrote:
No way. Sorry.
Friendly,
Dmitry
--
Dmitry Lomov
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"
Dmitry Lomov (JetBrains) wrote:
>> PsiElement reusedComma = PsiMagic.convert(PsiJavaToken.COMMA) ;
>> How can I do that?
> No way. Sorry.
You mean no 'published' way?!
The simplest way I could find is
PsiElement comma = factory
.createFieldFromText("String[]a={null,null};", null)
.getChildren()[4]
.getChildren()[2];
It's almost funny.
Alain
If you're still watching this programme, here is one solution to the
challenge :
Transform
fieldFromText = String[]a={null,null};
into
fieldFromText = String[]a={null,null, "the end"};
Solution :
-
public class Test extends LightCodeInsightTestCase
{
public void test1_insertIntoInitializer() throws Exception
{
PsiElementFactory factory = getPsiManager().getElementFactory();
String textBefore = "String[]a={null,null};",
toAdd = "\"the end\"";
PsiField field = factory
.createFieldFromText(textBefore, null);
PsiElement
initializers = field.getChildren()[4],
lastChild = initializers
.getChildren()[initializers.getChildren().length-1];
PsiElement
COMMA = makeComma(factory),
addee = factory
.createExpressionFromText(toAdd, null) ;
lastChild.getParent().addBefore(COMMA, lastChild);
lastChild.getParent().addBefore(addee, lastChild);
}
public static PsiElement makeComma(final PsiElementFactory i_factory)
{
try {
return i_factory
.createFieldFromText("String[]a={null,null};", null)
.getChildren()[4]
.getChildren()[2];
} catch (IncorrectOperationException e1) {
e1.printStackTrace();
return null ;
}
}
}
Alain Ravet wrote:
Please please please do not abuse PSI API - it is extemely vulnerable
to abuse, and abused enough already :)
General consensus in IDEA team is that one shouldn't add tokens to
PSIElement.
Friendly,
Dmitry
--
Dmitry Lomov
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"
Dmitry Lomov (JetBrains) wrote:
> Please please please do not abuse PSI API - it is extemely
> vulnerable to abuse, and abused enough already :)
I didn't see it as an abuse, but as the only way I could find.
> General consensus in IDEA team is that one shouldn't add
> tokens to PSIElement.
Now you tell me!
:(
Alain
Alain Ravet wrote:
Sorry - this is why PSI is not yet an official OpenAPI.
Anyway, the best you can do is to create an initializer from text,
as I suggested in the other message.
Friendly,
Dmitry
--
Dmitry Lomov
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"