How to add an annotation and import to a Java class
已回答
I'm trying to add the @Entity javax persistence annotation to a class. My code is as follows:
PsiJavaFile psiJavaFile = (PsiJavaFile) psiClass.getContainingFile();
PsiImportList psiImportList = psiJavaFile.getImportList();
PsiAnnotation entityAnnotation = elementFactory.createAnnotationFromText("@javax.persistence.Entity", null);
psiJavaFile.addAfter(entityAnnotation, psiImportList);
// shortenClassReferences takes the fully qualified class name used in the annotation and shortens it, adding the import
javaCodeStyleManager.shortenClassReferences(psiJavaFile);
codeStyleManager.reformat(psiClass);
The annotation appears in the class, after the import list, but it is still fully qualified, no import has been added for it. Any ideas what I have got wrong here? In addition, there is one line of white space between it and the start of the class identifier, what is the correct way to position it so I don't get this extra line gap?
Thanks for any help.
Hedley
请先登录再写评论。
You can use com.intellij.psi.PsiAnnotationOwner#addAnnotation via PsiClass and then call JavaCodeStyleManager.getInstance(project).shortenClassReferences(inserted); on the return value
Thanks for the advice. I have replaced my code with:
When I run my unit test, the annotation is added at the correct place (no line of whitespace) but it still has a fully qualified class name. I've also tried calling shortenClassReferences on the psiJavaFile object, but that doesn't help either. Any ideas?
Please show the full method/context of this code.
Here is the section adding the annotation:
The code is inside an Action. i.e. extends AnAction and called from the actionPerformed method.
At the moment I'm running it from a test, which extends
I then create a new instance of the action, and call:
myFixture.testAction(myActionInstance)
Is the annotation class "javax.persistence.Entity" made available in test (e.g. added as "fake" or library added to ProjectDescriptor)?
Ahh..this will be the step I'm missing. Looking at the IntelliJ notes here:
https://www.jetbrains.org/intellij/sdk/docs/basics/testing_plugins/light_and_heavy_tests.html
It looks like I need to override the method to return the project descriptor:
How do I add a library into the project descriptor?
Thanks.
Override com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor#configureModule and use PsiTestUtil#add(Project)Library
alternatively just add a (dummy version) of annotation via com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture#addClass
Hmm. Still can't get this working. I've written a project descriptor like this:
And then in my test class use this like this:
However the fully qualified annotation name is still not being shortened when I run the test. Am I missing something? Is there any debug checks / output I can put into the test to check it is being set up correctly? Thanks.
Apologies, the test is working correctly now with the above code. Many thanks for your help!
Actually, I should clarify. I didn't get this working by overriding the project descriptor. Even though I had print statements in the project descriptor showing that code was being invoked, it only worked when the code was in the test setup() method.
i.e. test case extends LightCodeInsightFixtureTestCase and has the following:
That's most likely incorrect, because the added library can leak into unrelated light tests with the same descriptor. I'd suggest to investigate why adding it in the descriptor isn't working. I'd do it by putting breakpoints into the place where the libraries are added in your derscriptor, check whether they're really added (i.e. the root model contains them after the descriptor finishes). Then I'd also check if there are other ProjectRootListener#rootsChanged events after that that remove the library for any reason.