eclipse-archived/ceylon-ide-intellij

bug in IntelliJ model loader

Opened this issue · 7 comments

I'm getting errors like:

the 'SupertypeVisitor' caused an exception visiting a 'ClassDefinition' node: '"com.redhat.ceylon.model.loader.ModelResolutionException: Failed to resolve com.redhat.ceylon.ide.common.refactoring.AbstractRefactoring.EditorData"' at 'com.redhat.ceylon.model.loader.AbstractModelLoader$7.call(AbstractModelLoader.java:2001)'

the 'ExpressionVisitor' caused an exception visiting a 'QualifiedMemberExpression' node: '"com.redhat.ceylon.model.loader.ModelResolutionException: Failed to resolve com.redhat.ceylon.ide.common.model.delta.DeltaBuilderFactory.MemberDeltaBuider"' at 'com.redhat.ceylon.model.loader.AbstractModelLoader$7.call(AbstractModelLoader.java:2001)'

the 'SupertypeVisitor' caused an exception visiting a 'ClassDefinition' node: '"com.redhat.ceylon.model.loader.ModelResolutionException: Failed to resolve com.redhat.ceylon.ide.common.refactoring.AbstractRefactoring.EditorData"' at 'com.redhat.ceylon.model.loader.AbstractModelLoader$7.call(AbstractModelLoader.java:2001)'

From inside the IDE, on the ceylon-ide-intellij project.

These errors don't occur on the command line. What they have in commit is the use of an inner interface coming from a binary dependency written in Ceylon.

Note that what is interesting about inner interfaces is that they are actually compiled to toplevel interfaces.

So the bug here is the following: AnnotationMirror.getValue() returns a TypeMirror in the case where the annotation member is of type java.lang.Class. Now, in, for example, the ReflectionModelLoader, the TypeMirror just wraps the java.lang.Class and returns the value foo.bar.Outer$Inner for the qualified name of the inner interface.

But in IntelliJ, the TypeMirror actually wraps a PsiType representing the class, and getting the qualified name actually somehow calls back to the model and gets the source name of the inner interface, i.e.foo.bar.Outer.Inner. What the model loader then tries to look up this name, it fails.

In 046a4d7 I have worked around the bug in AbstractModelLoader itself, at least in the simplest cases, by actually replacing the last . in the class name. But that solution is rubbish.

We need to figure out something better. Unfortunately I can't see where I can actually even get access to the "real" class name from the IntelliJ APis I have.

@bjansen I'll need your help.

IIRC, when IntelliJ loads PsiTypes from bytecode, it always replaces $ with ., so when we call psiType.canonicalText we actually get the wrong value, that's why we have to check in the index if it really exists, and do some black magic if it doesn't :(

@bjansen aaaaah. So, indeed, my workaround in the model loader is kinda almost sorta correct then.

Dunno, wouldn't it make more sense to move it to ceylon-ide-intellij? Also, why is this breaking now? I think it used to work correctly before?

Dunno, wouldn't it make more sense to move it to ceylon-ide-intellij?

Yes, definitely, I totally agree. I'm just not sure where to go to fix it.

Dunno, wouldn't it make more sense to move it to ceylon-ide-intellij?

I have no clue. I have not myself been fucking with model loaders.