Can I use GDSL with generics?

Answered

I have following GDSL for my Groovy DSL.

contributor(apiCtx) {
// Non generic method definition
method name: 'foo', params: [cl: "java.util.function.Function<String, String>"]
// Generic method definition
method name: 'bar', params: [class: "java.lang.Class<T>", cl: "java.util.function.Function<T, String>"]
}

And this is my Groovy DSL file.

package dsl

foo { a ->
// a is recognized as String
a.substring(0)
}


bar(String) { a ->
// a is not recognized as String
a.substring(0)
}

 

It seems the generic method definition at GDSL is not working on my Groovy DSL, where the closure argument should be recognized as a String.

Are there any solutions? 

This is my test repository. https://github.com/kota65535/GDSLTest

0
6 comments

It's not possible to define method with generics at runtime, and gdsl is designed to support methods which are available at runtime. 
Why do you need it?

0

Thank you for replying. I simply want to create a method that takes two arguments.

- a class object

- a closure that takes an argument whose class is the first argument

 

Such methods can be easily defined by generic methods on Java source codes, and we can get the benefits of code completion based on the generic type.

I have another problem for delegating a closure to an any generic class. Is it possible to make "delegatesTo" method take a generic class as its argument like this?

contributor(apiCtx) {

def call = enclosingCall('baz')
if (call) {
// delegate to the generic class
delegatesTo(findClass("BazDelegate<String>"))
}
}

As far as I tried, the code above does not work because "findClass" method fails to find the class...

 

 

0

> It's not possible to define method with generics at runtime, and gdsl is designed to support methods which are available at runtime.

Yes, I know generics are all erased at runtime because of type erasure. I just want to define generic methods by GDSL for the purpose of code completion, as if they are directly written in the source file.

0

> It seems the generic method definition at GDSL is not working on my Groovy DSL, where the closure argument should be recognized as a String.
Are there any solutions? 

Currently there are no solutions via gdsl.

> I have another problem for delegating a closure to an any generic class. Is it possible to make "delegatesTo" method take a generic class as its argument like this?

Currently no.

 

You may want to try to define a base script super class `com.foo.MyScript` and use it as a base class to compile your script:

def configuration = new CompilerConfiguration()
configuration.scriptBaseClass = com.foo.MyScript.name
...

Then you can add all your top level DSL methods into this class. This way the generated script class would extend `com.foo.MyScript` and any method from this class will be available inside the script. Then you can have real methods there:

def <T> void bar(java.lang.Class<T> clazz, java.util.function.Function<T, String> f) { ... }

The only thing left is to let IntelliJ know that your script extends the class, this could be done in top level gdsl construct like this:

scriptSuperClass(pattern: "some regexp that will match file path", superClass: "com.foo.MyScript")

 

0

Please sign in to leave a comment.