Insert a new line and tabulation before new field in PsiClass.

Hi,

I am generating a new field for a PsiClass using PsiElement.addAfter() which works fine.
However, the new field's declaration is inserted on the same line than the PsiElement passed in addAfter() e.g.:

public static final String myExistingField = "myExistingField";public static final String myNewField = "myNewField";

I did browse this forum and the OpenAPI JavaDoc to find how to insert new line and tabulation before my field.
I tried psiElementFactory.createExpressionFromText("\n", myPsiClass) or psiElementFactory.createWhiteSpaceFromText("\n", myPsiClass) with no success.

Any help appreciated.

Thanks.

JR

5 comments
Comment actions Permalink

Hello Jean D'Amore,

You don't need to insert whitespace elements manually. Instead, you should
use CodeStyleManager to reformat the code fragment in which you've inserted
the elements.

I am generating a new field for a PsiClass using PsiElement.addAfter()
which works fine.

However, the new field's declaration is inserted on the same line than
the PsiElement passed in addAfter() e.g.:

public static final String myExistingField = "myExistingField";public
static final String myNewField = "myNewField";

I did browse this forum and the OpenAPI JavaDoc to find how to insert
new line and tabulation before my field.

I tried psiElementFactory.createExpressionFromText("\n", myPsiClass)
or psiElementFactory.createWhiteSpaceFromText("\n", myPsiClass) with
no success.


--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Dmitry,

Yes, I finally managed to figure out that after having inserted new fields and new method statements, calling CodeStyleManager.reformat() on my PsiClass as follows did the job wonderfully:

CodeStyleManager codeStyleManager = psiManager.getCodeStyleManager();
codeStyleManager.reformat(myPsiClass);

Thanks for you help.

JR

0
Comment actions Permalink

Hi Dmitry,

I have been using psiElementFactory.createWhiteSpaceFromText("\n") until now when I create a new annotation on a property or on a class in my JalapenoDev plugin. Apparently this API has been removed in IDEA 11 so in order to port my plugin to 11 I am trying to find a replacement. I found this thread.

My goal is to replace a block like:

// === START ====
    public List<Doctor> getDoctors ()
    {
        return doctors;
    }
// ==== END ====

with

// === START ====
    @Relationship(type = RelationshipType.ONE_TO_MANY, inverseClass = "javaTechDay.dbapp.data.Doctor",
            inverseProperty = "hospital")   
    public List<Doctor> getDoctors ()
     {
         return doctors;
     }
// ==== END ====

The code that used to do this was like:

PsiElement newline = mPsiElementFactory.createWhiteSpaceFromText ("\n");
PsiAnnotation a = mPsiElementFactory.createAnnotationFromText (text, element);
PsiElement anchor = element.getChildren ()[0];
ret = (PsiAnnotation) element.addBefore (a, anchor);
element.addAfter (newline, ret);

This code used to work up to 10.5. For v 11 I experimented with something else, e.g. I tried:

PsiAnnotation a = mPsiElementFactory.createAnnotationFromText (text + "\n", element);
PsiElement anchor = element.getChildren ()[0];
ret = (PsiAnnotation) element.addBefore (a, anchor);
CodeStyleManager.getInstance (element.getManager ()).reformat (element);

However what I get is the following block of code that in my opinion is not nice:

// === START ====
    @Relationship(type = RelationshipType.ONE_TO_MANY, inverseClass = "javaTechDay.dbapp.data.Doctor",
            inverseProperty = "hospital")public List<Doctor> getDoctors() {
        return doctors;
    }
// ==== END ====

Attempt to reformat the whole class does not help but anyway I can hardly force reformatting of the class while adding annotations - people are often override manually automatic formatting. I realize that you can argue that probably the code style defined says that annotation should be on the same line as member but in this case annotation is too long to be on the same line. Having no whitespace between the ending brace of the annotation and qualifier of the member does not look good. And this is just one example, I can give others too.

Do you have any suggestions how I should reslove this issue?

Thanks,

Misha Bouzinier

0
Comment actions Permalink

Hi Misha,

You can always check current white space elements processing processing at the formatter code - FormatProcessor.replaceWhiteSpace() which eventually brings us to the FormatterUtil.replaceWhiteSpace().

Regarding the mentioned use-case (long annotation before a field) - there is a dedicated code style setting - 'Code Style | Java | Wrapping and Braces | Field annotations'. You can set it to 'Wrap if long' to get the desired behavior.

Regards, Denis

0
Comment actions Permalink

Hi Denis,

Thank you for your reply. Unfortunately I am still stuck without an acceptable soultion.

You can always check current white space elements processing processing at the formatter code - FormatProcessor.replaceWhiteSpace() which eventually brings us to the FormatterUtil.replaceWhiteSpace().


Maybe I just do not see something obvious but it looks like FormatterUtil works on ASTNodes which is kind of parallel data structure to PsiElement.

My current approach when generating code in user classes is to create a set of PsiElements. If this is not the best one - what is the one?

Anyway looking at FormatterUtil I came up with some hack that seem to work but it is quite ugly and I hope you can advise me on a better way. Here is the code:

    private PsiWhiteSpace nl(PsiElement context)
    {
        if (newline == null)
            {
                while (!(context instanceof ASTNode))
                    {
                        context = context.getFirstChild ();
                        if (context == null)
                            return null;
                    }

                CharTable
                    charTable = SharedImplUtil.findCharTableByTree (
                    (ASTNode) context);
                newline = (PsiWhiteSpace) Factory
                    .createSingleLeafElement(TokenType.WHITE_SPACE, "\n",
                        charTable, PsiManager.getInstance (mProject));
                
            }
        return newline;
    }

As to setting code style - beside an obvious fact that I can not set code style in users IDE I still think that inability to add a whitespace hurts. Note that without explicitely inserted hietspace there are just no whistespace between right brace of the newly added annotation and the keyword "public". WHatever is the code style it does not look right, does it?

Thanks again,

Misha

0

Please sign in to leave a comment.