reference injector - set return type

Hi - 

I have the following API:

Object getThing(String s)

Depending on the value of the argument, the return type will be a String or Integer etc. The problem is in usage, you need to work out what the actual return type would be, and cast the return value.

I am trying to make my idea plugin inject the correct return type based on the parameter.

I have a com.intellij.psi.injection.ReferenceInjector. In the reference I inject, I implement bindToElement like this, to make it appear to return a String:

JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_STRING, GlobalSearchScope.allScope(project))

Is this the right way to handle this scenario? (Clearly it's not, so any suggestions appreciated).

 

5 comments
Official comment

Do you intend to make Java compiler understand this dependent type mechanism? Java language specification doesn't seem to support that. So the IDE probably shouldn't as well, to avoid non-compilable code being green.

Good point, and my bad, I didn't provide enough info. The language is groovy so methods are dynamically dispatched... code compiles and runs fine, what I'm trying to do is when the user has:

getThing("with this param I return a String object").substring(..)

- this should be green, and also provide completions when caret is at: getThing("...").| 

Using a reference injector I can provide suggestions for the param of getThing, that works fine. 

I think I was on the wrong track trying to set the return type with a reference injector, I think I need a referenceTypeEnhancer or expressionTypeCalculator or callExpressionTypeCalculator...? Not sure which, but what I've tried so far I can't get to work.

The following was unclear:

The problem is in usage, you need to work out what the actual return type would be, and cast the return value

The only reason to cast the return value is to make the code green, and to get completions.

 

0

For Groovy, there's an extension called org.intellij.groovy.callExpressionTypeCalculator (GrCallExpressionTypeCalculator class), which you could implement in a plugin.

0

Thank you Peter, that worked - well, it did what I asked for.

I'm not sure if this is a separate question, maybe.

In my example above, the issue is that the object getThing is invoked on implements Map.

So the following both work

obj.get("should be a string").substring(..)
obj.getAt("should be a string").substring(..)

because they are handled by my GrCallExpressionTypeCalculator.

The problem is that subscript notation does not work:

obj["should be a string"].substring(..)

I have not even tried "dot" access yet but that needs to work too.

 

I think I want a GroovyMapContentProvider...? Problem is when debugging I am not even getting as far as the code that calls the extensions (namely org/jetbrains/plugins/groovy/configSlurper/GroovyMapValueTypeEnhancer.java:62) - is that even an extension for ConfigSlurper only?

I've also played with a GrReferenceTypeEnhancer, but I'm going round in circles.

cheers, jamie

0

I'm afraid there is no such API as for 2017.1.

`GroovyMapContentProvider` only works for expression like `foo.bar` or `foo().bar`, where `foo` type is an inheritor of `java.util.Map` and `bar` is a map key. 

I can add necessary API in 2017.2. Please submit a request https://youtrack.jetbrains.com/.

0

Please sign in to leave a comment.