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

0
11 comments

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:
>

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

>


0

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:


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


--
Dmitry Lomov
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"

0

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


0

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

0


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

0

Alain Ravet wrote:


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?


No way. Sorry.

Friendly,
Dmitry

--
Dmitry Lomov
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"

0

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

0


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 ;
}
}
}

0

Alain Ravet wrote:

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.


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!"

0

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

0

Alain Ravet wrote:

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!
:(


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!"

0

Please sign in to leave a comment.