Inferred type is null even if it shows in the IDE in tests

Answered

Hi folks, me again.

This is the code i write my test against

As you can see, the inferred type of the `it` element is found fine.

But when the test is run, it isn't found, and neither

if (element instanceof GrReferenceExpression) {
PsiType myType = (element as GrReferenceExpression).getType()

nor

TypeInferenceHelper.getInferredType(element)

can get the type., and  `myType` is null.

Is there a better way to get the inferred type ?

Is there a particuliar config to use for the fixture ?

thanks beforehand

i also asked in the IDEA Slack, but got no solution so far:

https://jetbrains-platform.slack.com/archives/C5U8BM1MK/p1646228941165679

9 comments
Comment actions Permalink

Hi Gaëtan,

Did you add the required dependencies to a test project? Please take a look at: https://plugins.jetbrains.com/docs/intellij/testing-faq.html#how-to-test-a-jvm-language

0
Comment actions Permalink

Hi Karol, thanks a lot for your answer, and sorry for my late reply.

I can't make it work so far. I think i tried most solutions i found on forums to add the groovy dependency in tests. I did and undid some things a lot.

Is there an idiomatic or prefered way of doing this that i can focus on ? through the `build.gradle` and `testDependency` property ?

I got errors with both PsyTestUtil and MavenDependencyUtil tools.

And I don't understand the "idea.home.path" (i run a Ubuntu, and i can't find the doc for the default location of the property). I read that i should set it, but the tests are supposed to run on a jenkins build later. So will this be ok ?

0
Comment actions Permalink

Hi Gaëtan,

It shouldn't be done via "build.gradle" and "testDependencies" - this is about your plugin project configuration and dependencies.

You should configure your test project, so the one that is created during the tests execution. You should override the "getProjectDescriptor()" method:
https://github.com/JetBrains/intellij-community/blob/master/java/testFramework/src/com/intellij/testFramework/fixtures/LightJavaCodeInsightFixtureTestCase.java#L144

and return your project descriptor which will override the "setUpMethod()" method:
https://github.com/JetBrains/intellij-community/blob/master/platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java#L165

by calling MavenDependencyUtil or PsiTestUtil adding required dependencies. You can extend DefaultLighProjectDescriptor which has most of the methods implemented. See also the "getSdk()" method which returns mocked JDK, you may want to override it to return another JDK version.

Regarding the idea.home.path and mockJDK in the context of CI, I would suggest copying the ones you need to your project's test directory, e.g. your project structure would look like:

your-project/
src/
test/
mockJDK/
java/
mockJDK-1.8/
jre/
lib/
... (files here)

and set system property in your Gradle build script to (of course this is your actual plugin build script, not the test one):

test {
 systemProperty "idea.home.path", "src/test/mockJDK"
}
0
Comment actions Permalink

Hi Carol, thanks again for your support.

So, i think i managed to load the groovy dependency :

systemProperty 'idea.home.path', project.getProjectDir()

and

class OfbizProjectDescriptor extends DefaultLightProjectDescriptor {
@Override
void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model, @NotNull ContentEntry contentEntry) {
/* Won't work, roots for groovy-all:2.5.14 not found */
// MavenDependencyUtil.addFromMaven(model, 'org.codehaus.groovy:groovy-all:2.5.14')
MavenDependencyUtil.addFromMaven(model, 'org.codehaus.groovy:groovy:2.5.14')
super.configureModule(module, model, contentEntry)
}

@Override
Sdk getSdk() {
return IdeaTestUtil.getMockJdk11()
}
}

I don't have any errors on tests exepts the one that still fails with the initial error (null type). But i assume the lib is correctly loaded, because i don't have setup errors anymore.

And i don't understand why i would need a different or custom JDK, if i have the groovy loaded ?

0
Comment actions Permalink

Hi Gaëtan,

If I understand correctly, you should also add the dependency to the library that contains GenericValue class, not only to Groovy.

Regarding JDK, I don't know Groovy, so I'm not sure if it requires JDK. It is required for languages that use Java Standard Library classes like java.lang.Object, or java.lang.String. If Groovy provides all the classes and does not depend on Java classes, then it can be skipped.

0
Comment actions Permalink

The Generic value is not added in a library or from a dependency.

The other tests are working, for example :

package org.apache.ofbiz

List<org.apache.ofbiz.entity.GenericValue> rings = from('Mordor')

rings.stream().filter({ org.apache.ofbiz.entity.GenericValue it ->
it.<caret>
})

This is a test file that works, and the completions is done, the test using this file is green

But from your comment, i think i understand that i should have the classes of OFBiz imported somehow (as libs or whatever) ?

0
Comment actions Permalink

Yes, if you need GenericValue type resolved in your plugin functionality, then you should add it to your test the same way as you did it with groovy.

0
Comment actions Permalink

I get that the class should be found. But how is it that is is found in the picture of the first message (using the fact that it is a list), and it ins't in the test ? That's quite confusing

PS : Sorry for the answer delay, busy weeks ^^

0
Comment actions Permalink

Hi Gaëtan,

The reason is that IDE creates an inline hint based on the class name even if it is unresolved. See another example:

0

Please sign in to leave a comment.