JavaTreeCopyHandler discards information about outer class
Hi,
I am trying to add a PsiClass as superclass to another PsiClass. The superclass is contained within another class.
The usecase is actually making inner builder classes extend each other, so something like [1]. However, whenever I add an extending reference referencing B.Builder, the PsiElement:replace method shortens the reference to just Builder, which is ambiguous in this context.
Debugging this thing, I ended up in com.intellij.psi.impl.source.tree.JavaTreeCopyHandler, which throws away the original PsiElement and just resolves the whole class to the class it thinks it may fit. However, in the context of extending inner classes the behaviour is somewhat wrong.
Is there any chance to get IntelliJ not discard the information about inner classes?
Thanks,
Matthias
[1]:
class A {
class Builder extends B.Builder {
}
}
class B {
class Builder {}
}
will end up in
class A {
class Builder extends Builder {
}
}
Please sign in to leave a comment.
By the way - some more information on what I am doing currently:
I am creating a PsiJavaCodeReferenceElement via PsiElementFactory::createReferenceFromText. This is the extends $$ part.
Afterwards, I pick up the extends list via PsiClass::getExtendsList and replace the second child via the newly created PsiJavaCodeReferenceElement:
What I really want to achieve is just replace the superclass with the reference I created - incl. the class name I specified in the PsiJavaCodeReferenceElement and not the shortened one created by ::resolve in JavaTreeCopyHandler.
Matthias
Edit:
#decodeInformation gets as input parameters:
element.getPsi still returns MyAbstractClass.Builder
element is still MyAbstractClass.Builder
Edit 2: Digging deeper:
I'll stop here. I have no idea where to continue ... I really need help on resolving this issue.
Hi Matthias,
why do you need to replace extendsList.getChildren and not add reference to the extends list? How do you generate A.Builder class or is it already there?
Anna
Hi Anna,
Thanks for your answer.
Adding the reference to the extends list results in the same problem, as the TreeCopyHandler is still called and #resolve still throws away the prefix for the inner class.
Yes, you're right. The superclass already exists. However, the superclass has different parameters, so I throw them away and replace the superclass with a new one.
Thanks,
Matthias
Sorry, I don't understand the code snippet - too many PsiClasses, I am lost which one is which in the initial sample. Anyway, would you mind not to create reference from text but create it from the class, like com.intellij.psi.PsiElementFactory#createReferenceElementByType and create reference type by class and type arguments? This way you should not lost the "class information" as tree handler should remember the class where the reference resolved before?
Anna