Reputation: 10290
I'm implementing a plugin in which I need to add extends
clause for an existing class.
I have PsiClass
instance representing say MyClass
.
There is an API that allows to get all the classes that MyClass
extends:
PsiReferenceList extendsList = psiClass.getExtendsList()
And theoretically I can add something to it and that will work.
Problem: PsiReferenceList.add()
consumes PsiElement
and I don't know how to create an object of PsiElement
having fully qualified name of the class I want to use.
More specifically, how to transform string com.mycompany.MyAbstractClass
to PsiElement
representing this class?
Update: I managed to achieve the result using the following logic:
PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
PsiReferenceList extendsList = aClass.getExtendsList();
PsiShortNamesCache instance = PsiShortNamesCache.getInstance(project);
PsiClass[] abstractClasses = instance.getClassesByName(
"MyAbstractClass",
GlobalSearchScope.allScope(project)
);
PsiJavaCodeReferenceElement referenceElement = factory
.createClassReferenceElement(abstractClasses[0]);
extendsList.add(referenceElement);
It works but I guess there should be more optimal way.
Upvotes: 1
Views: 747
Reputation: 6569
You can make a String
which is the code you want to generate, like
String code = "class A extends B { }"
Then, use this code to convert text into PsiElement
:
PsiElement fromText(String code, Project project) {
return PsiFileFactory
.getInstance(project)
.createFileFromText(JavaLanguage.INSTANCE, code)
.getFirstChild()
}
And you'll get the corresponding PsiElement
.
Then, myClass.replace(fromText(code))
.
BTW you can also do classNamePsiElement.addAfter(fromText("extends Xxx"))
which is considered more efficient.
Upvotes: 1