Generete annotation and methods/code in method in already existing java file.

Hi,

How can I (correct way) generate code (annotations, new methods and code inside eg. class constructor) in already existing java file? I will appreciate any kind of help or ideas.

13 comments
Comment actions Permalink
Official comment

Do you want to generate source code visible in the file or something like lombok generated members which are in the classfiles but not in the source files?

Anna

Comment actions Permalink

Yes, i want generate source code visible in file. Something like that.

@Myannotations(something = {myannotationtype = {
@Myannotation(parameters) @Myannotation(parameters)})
public class A {
0
Comment actions Permalink

Use `com.intellij.psi.PsiJavaParserFacade#createXXXFromText` to create elements from text. (To get the factory, use `com.intellij.psi.JavaPsiFacade#getElementFactory(com.intellij.openapi.project.Project)`)

0
Comment actions Permalink

Ok it works fine, but i have one problem. Im adding it with:

file.addAfter(annotationFromText, file.getFirstChild());

After adding annotation and imports first time it works like i want it to:

Element 0 import list (all imports)
Element 1:@MyAnnotations(type= {
@MyAnnotation(parameters) })
Element 2:
 
Element 3:public class MyClass {
public static void methods(){
}
}
Element 4:

but when i add second time my annotation it merges with Element 3 and it looks like this. Why it merge and how can I prevent it?

@MyAnnotations(type= {
@MyAnnotation(parameters) })

public class MyClass {
public static void methods(){
}
}
0
Comment actions Permalink

I'd suggest to `addBefore` with your class as anchor. Otherwise your code would be broken by package statement/import statement, etc.

0
Comment actions Permalink

I changed it like you suggested but it still merge into class when i try to add second annotation and looks like:

@MyAnnotations(type= {
@MyAnnotation(parameters) })

public class MyClass {
public static void methods(){
}
}
I don't know why it works when I add for first time (my annotation as different element) and next time it merge into class element.
0
Comment actions Permalink

It merges inside previous annotation as far as I can see. Please check what element is added and that anchor is still valid after you added the first element.

0
Comment actions Permalink

After adding first annotation: (Element 2 is added)

Element 0: import list (all imports)
Element 1:
Element 2:@MyAnnotations(type= {
@MyAnnotation(parameters) })
Element 3:public class MyClass {
public static void methods(){
}
}

When I try to add annotation again: (it automatic merge into next element?)

Element 0: import list (all imports)
Element 1:
Element 2:@MyAnnotations(type= {
@MyAnnotation(parameters) })
public class MyClass {
public static void methods(){
}
}

 

0
Comment actions Permalink

annotations belong to class's modifier list.

0
Comment actions Permalink

I want to add next annotation like this:

before second annotation:

@MyAnnotations(type= {
@MyAnnotation(parameters) })

after adding second annotation:

@MyAnnotations(type= {
@MyAnnotation(parameters), @MyAnnotation(parameters) })

My idea was to replace annotation element with new element (created from text) with new annotation but I guess it is not possible because i will replace class as well. Do you know how can i change it like that?

0
Comment actions Permalink

You want to add next annotation inside added annotation. Thus, you need to keep added annotation and add new element inside, like

```

PsiAnnotation anno = psiClass.add(firstAnnoFromText);

anno.addAfter(secondAnnoFromText, anchor);

```

where anchor need to be found among the `anno` children according to your rules.

 

0
Comment actions Permalink

How can I generate code inside the method i focus on now ?

0
Comment actions Permalink

If you have a caret inside the method, then AnAction will provide you with `com.intellij.openapi.actionSystem.DataContext` from which you may get psiElement (`com.intellij.openapi.actionSystem.CommonDataKeys#PSI_ELEMENT`). This element will correspond to the leaf element under caret. Then you would need to check the tree above the element and perform your transformations.

0

Please sign in to leave a comment.