simplest way to remove an element from a Psi tree?

Is there a simple way to remove an element from a psi tree?

For example,

public fi]]>nal int foo;

once I have theFinalToken, and theField, I need something like:

theFieldElement.remove(theFinalTokenElement)


Alain

25 comments
Comment actions Permalink

You can simply call theFinalToken.delete(). It's unintuitive, like
replace(), I see why you missed it.

I'm curious, what is your naming convention for "the" prefix?

Alain Ravet wrote:

Is there a simple way to remove an element from a psi tree?

For example,

public fi<caret_here>nal int foo;

once I have theFinalToken, and theField, I need something like:

theFieldElement.remove(theFinalTokenElement)


Alain

0
Comment actions Permalink

Indeed, you can always call PsiElement.delete().
However for your example it is better to call more semantic rich
PsiModifierList.setModifierProperty.
There are some other cases where additional methods are provided,
e.g.PsiIfStatement.setElseBranch

Eugene.

"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:d7616u$ke8$1@is.intellij.net...

You can simply call theFinalToken.delete(). It's unintuitive, like
replace(), I see why you missed it.

>

I'm curious, what is your naming convention for "the" prefix?

>

Alain Ravet wrote:

Is there a simple way to remove an element from a psi tree?

>

For example,

>

public fi<caret_here>nal int foo;

>

once I have theFinalToken, and theField, I need something like:

>

theFieldElement.remove(theFinalTokenElement)

>
>

Alain



0
Comment actions Permalink

Keith

You can simply call theFinalToken.delete(). It's unintuitive, like
replace(), I see why you missed it.

>
Thanks.

I'm curious, what is your naming convention for "the" prefix?

>

It's not a convention. I just wanted to show that I already had extract
the objects, of the given type, to avoid people showing me how to.

Alain

0
Comment actions Permalink

Eugene

>Indeed, you can always call PsiElement.delete().
>However for your example it is better to call more semantic rich
>PsiModifierList.setModifierProperty.

>

Why is it better, if the simplest solution works as well?

It looks like the "better' solution will force me to reset all the
modifiers (? potentially changing the formatting, if it's not standard?)


Alain

0
Comment actions Permalink

The solution I proposed is equivalent to yours for deleting modifers (at
least at first glance), but in general, PSI is capable of handling some
errors that are the result of modifying the code.
Consider e.g. setElseBranch() method. Without having it, it would be a
tedious task to maintain all braces needed. Thus we provide support from PSI
itself.
As for formatting, it is changed (automatically) when performing any PSI
write operation.

Eugene.


"Alain Ravet" <alain.ravet@biz.tiscali.be> wrote in message
news:d76duu$813$1@is.intellij.net...

Eugene

>

>Indeed, you can always call PsiElement.delete().
>However for your example it is better to call more semantic rich
>PsiModifierList.setModifierProperty.
>
>

>

Why is it better, if the simplest solution works as well?

>

It looks like the "better' solution will force me to reset all the
modifiers (? potentially changing the formatting, if it's not standard?)

>
>

Alain



0
Comment actions Permalink

Eugene

>The solution I proposed is equivalent to yours for deleting modifers (at
>least at first glance), but in general, PSI is capable of handling some
>errors that are the result of modifying the code.

>

Not sure it's related, but when I add an annotation before the field, it
"works" in the editor - I get the expected code -, but it produces a
stacktrace.

java.lang.Throwable
at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:64)
at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:72)
at
com.intellij.psi.impl.source.tree.ChangeUtil.addChild(ChangeUtil.java:59)
at
com.intellij.psi.impl.source.tree.CompositeElement.addChild(CompositeElement.java:23)
at
com.intellij.psi.impl.source.codeStyle.CodeEditUtil.addChildren(CodeEditUtil.java:169)
at
com.intellij.psi.impl.source.tree.CompositeElement.addInternal(CompositeElement.java:40)
at
com.intellij.psi.impl.source.TreeWrapperPsiElement.addBefore(TreeWrapperPsiElement.java:21)


Am I mistaking "addBefore(theField)" with some kind of
addAtBeginOf(theField)?
Does it create a sibling, rather than add a component at the begin of
the object tree?



>As for formatting, it is changed (automatically) when performing any PSI
>write operation.
>

>
Do you mean I don't need to perform a

final CodeStyleManager codeStyleManager = mgr.getCodeStyleManager();
codeStyleManager.reformat(theField);

, after modifying the field?

0
Comment actions Permalink


"> Not sure it's related, but when I add an annotation before the field, it

"works" in the editor - I get the expected code -, but it produces a
stacktrace.

>

java.lang.Throwable
at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:64)
at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:72)
at
com.intellij.psi.impl.source.tree.ChangeUtil.addChild(ChangeUtil.java:59)
at

>
com.intellij.psi.impl.source.tree.CompositeElement.addChild(CompositeElement
.java:23)

at

>
com.intellij.psi.impl.source.codeStyle.CodeEditUtil.addChildren(CodeEditUtil
.java:169)

at

>
com.intellij.psi.impl.source.tree.CompositeElement.addInternal(CompositeElem
ent.java:40)

at

>
com.intellij.psi.impl.source.TreeWrapperPsiElement.addBefore(TreeWrapperPsiE
lement.java:21)
>
>

Am I mistaking "addBefore(theField)" with some kind of
addAtBeginOf(theField)?
Does it create a sibling, rather than add a component at the begin of
the object tree?


add() adds a child to psiElement;
What you want to do is to add an annotation to field's modifier list:
field.getModifierList().add(annotation) (or addBefore/addAfter).

In general it is useful to know how the syntax tree looks like, that's where
PsiViewer plugin comes.


>
>
>

>As for formatting, it is changed (automatically) when performing any PSI
>write operation.
>
>
>
Do you mean I don't need to perform a

>

final CodeStyleManager codeStyleManager =

mgr.getCodeStyleManager();

codeStyleManager.reformat(theField);

>

, after modifying the field?

>
If you alter modifier list of the field, then only modifier list is
reformatted, not the whole field,
on the other hand, do you really need to reformat the field?:)

Eugene.



0
Comment actions Permalink


>What you want to do is to add an annotation to field's modifier list:
>field.getModifierList().add(annotation) (or addBefore/addAfter).
>

>


I'm almost there:
modifierList.addBefore (annot, modifierList.getFirstChild ());

correctly produced
@AlmostFinal public int ss = 1;

, but I'm thriving for:
@AlmostFinal
public int ss = 1;

I couldn't find the way to fabricate a simple white space, so even less
a line break!

Question:
How can I have it span over 2 lines, like theField.addBefore(annot)
would do (with an error stacktrace, though):


Alain

0
Comment actions Permalink


Alain Ravet wrote:

I couldn't find the way to fabricate a simple white space, so even less
a line break!


Perhaps the source to the Tabifier plugin contains some hints to the
formatting of elements?
http://www.intellij.org/twiki/pub/Main/TabifierPlugin/tabifier-5.0-src.zip

Bas

0
Comment actions Permalink

Bas Leijdekkers wrote:

Perhaps the source to the Tabifier plugin contains some hints to the
formatting of elements?
http://www.intellij.org/twiki/pub/Main/TabifierPlugin/tabifier-5.0-src.zip

>
>

You're right. Thanks

Alain

0
Comment actions Permalink

Alain, you should not bother with fabricating whitespaces, formatting will
done automatically in the next EAP build.
I'm not sure though that the formatter does not have bugs with annotations:(
Try ctrl-alt-L, and if it fails, please report a request.

Eugene.

"Alain Ravet" <alain.ravet@biz.tiscali.be> wrote in message
news:d773do$k0n$1@is.intellij.net...
>

>What you want to do is to add an annotation to field's modifier list:
>field.getModifierList().add(annotation) (or addBefore/addAfter).
>
>
>

>
>

I'm almost there:
modifierList.addBefore (annot, modifierList.getFirstChild ());

>

correctly produced
@AlmostFinal public int ss = 1;

>

, but I'm thriving for:
@AlmostFinal
public int ss = 1;

>

I couldn't find the way to fabricate a simple white space, so even less
a line break!

>

Question:
How can I have it span over 2 lines, like theField.addBefore(annot)
would do (with an error stacktrace, though):

>
>

Alain



0
Comment actions Permalink

Bas Leijdekkers wrote:

Perhaps the source to the Tabifier plugin contains some hints to the
formatting of elements?



Unfortunately, from what I've seen, it does reformat code by working on
the document, and not the psi tree.

Alain

0
Comment actions Permalink

Eugene

>Alain, you should not bother with fabricating whitespaces, formatting will
>done automatically in the next EAP build.

>


There are other legitimate cases where one could want to insert a line
break. Or two.
Is there a pure psi-based way to do that, or do we need to work on the
document?



Alain

0
Comment actions Permalink

Alain,
all whitespaces/ line breaks needed will be added by the formatter itself,
that will be called when adding/removing or replacing children.
Just wait for the next build to come out:)

And no, please, do not work with document, unless you really need to.
Working with documents requires calling commit() and all PSI gets
invalidated.

Eugene.

"Alain Ravet" <alain.ravet@biz.tiscali.be> wrote in message
news:d77adh$2if$1@is.intellij.net...

Eugene

>

>Alain, you should not bother with fabricating whitespaces, formatting

will

>done automatically in the next EAP build.
>
>

>
>

There are other legitimate cases where one could want to insert a line
break. Or two.
Is there a pure psi-based way to do that, or do we need to work on the
document?

>
>
>

Alain



0
Comment actions Permalink

Eugene

>all whitespaces/ line breaks needed will be added by the formatter itself,
>that will be called when adding/removing or replacing children.
>Just wait for the next build to come out:)
>

>

Once again, there are VERY LEGITIMATE cases where the standard format is
not good enough/won't do.
In the editor, you would add breaks, tabs, and spaces, and this info
would be stored in the psi tree, so it's possible.

My question: to do with code - by a plugin -, is there a pure psi way,
or do we need to modify the document directly.


Alain

0
Comment actions Permalink

Once again, there are VERY LEGITIMATE cases where the standard format is
not good enough/won't do.

And those cases are?
I've never heard of anyone saying he needs nonstandard
whitespaces. Even if you do insert them, they'll be removed on the next
formatting action/ psi modification.
So what are those VERY LEGITIMATE CASES?


0
Comment actions Permalink

Eugene

I've never heard of anyone saying he needs nonstandard
whitespaces. Even if you do insert them, they'll be removed on the next
formatting action/ psi modification.

>

So what are those VERY LEGITIMATE CASES?

>

(view with non-proportional font: )


Board winningBoard = new Board ("0X0" +
"XO." +
"XXO" );


Alain

0
Comment actions Permalink

Eugene

>So what are those VERY LEGITIMATE CASES?
>

>

Don't you consider the TabifierPlugin legitimate?
I find aligned code ways more readable. Who wouldn't?

(view with non-proportional font:)

String a,medium, extraLong;

public String getA () { return a ; }
public String getMedium () { return medium ; }
public String getExtraLong () { return extraLong; }

public void doA ()
{
a = "999999999999";
medium = "4444" ;
extraLong = "1" ;
}
public void doMedium () { ... }
public void doVeryLong () { ... }

0
Comment actions Permalink

Alain, you are good with ASCII-art ;)

Tom

0
Comment actions Permalink

Tom

Alain, you are good with ASCII-art ;)

>


Seriously, carefully aligned code is more readable => more
understandable => more maintainable. The only reason not to align is
that it takes time, when you have to do it by hand. Too bad JB didn't
integrate the Tabifier, and improved on it.
I almost never use code reformat on an entire class I wrote, because it
messes up my lines and columns.

Alain

0
Comment actions Permalink

Alain,
good news is that with the new version of formatter we (mostly Olesya) are
working on, writing code for alignment aka Tabifier will be an easy thing.
Eugene.

"Alain Ravet" <alain.ravet@biz.tiscali.be> wrote in message
news:d79sqm$lnf$1@is.intellij.net...

Tom

>

Alain, you are good with ASCII-art ;)

>

>
>

Seriously, carefully aligned code is more readable => more
understandable => more maintainable. The only reason not to align is
that it takes time, when you have to do it by hand. Too bad JB didn't
integrate the Tabifier, and improved on it.
I almost never use code reformat on an entire class I wrote, because it
messes up my lines and columns.

>

Alain



0
Comment actions Permalink

There is another good reason to not align fields:
- added/removing a field might might affect a large number of lines making
it hard to merge changes

Tom

0
Comment actions Permalink

Tom

There is another good reason to not align fields:
- added/removing a field might might affect a large number of lines
making
it hard to merge changes

>

You're saying
"I don't do it because it's difficult, or could be difficult, later.
(wherever or not it's useful)"
A few years ago - pre-IDEA -, you would have used the same argument to
justify not renaming an object, in a medium sized project.

It's difficult only if it is not automated.


Alain

0
Comment actions Permalink

No, Alain, I don' do any more advanced than IDEA can do, because I can read
our code the way it is. But that was not my complain.

Tom

0
Comment actions Permalink

Hi Eugene,

Alain was kind enough to point out this forum thread to me.

I maintain the tabifier plugin. One function I was never able to do (or at least to figure out how to do) was to control whitespace through psi tree modification. This is why the tabifier today (and the rearranger plugin also) do all their analysis with the psi tree but modify the document. I would like to use the psi tree exclusively; it seems it would be much more efficient. Any information you can provide on how to modify whitespace via psi API would be appreciated.

Secondly, you wrote:
>good news is that with the new version of formatter we (mostly Olesya) are
>working on, writing code for alignment aka Tabifier will be an easy thing.

Does this mean that the functionality of the tabifier will be included in Irida's code formatter (and hence the tabifier plugin becomes obsolete)? Or does it mean that the API hooks into the new formatter will make the tabifier's job easier (so I have more work to do :-)?

Finally, people have mentioned it before, but I never asked anyone at JB about the possibility of integrating tabifier with IDEA's code reformatter. I have some ideas about making the configuration easier, and the plugin is probably due for a rewrite. At least, I'd like to work more closely with JB to use new PSI functionality properly, and integrate with IDEA's reformatter as much as possible. Whom should I contact about this?

Thanks,
-Dave

0

Please sign in to leave a comment.