I'm aware of @ClosureParams
annotation. It seems to be covering more complex use cases only though. I'm looking for something like described here at the annotating closures section. Which is similar to the following snippet:
void doSomething(MyType src, @ClosureParams(MyType) Closure cl) { ... }
This example no longer compiles with more recent groovy versions unfortunately (I'm on 2.5.8 at the moment). I know I can achieve equivalent with:
void doSomething(MyType src, @ClosureParams(FirstParam) Closure cl) { ... }
My use case doesn't have any other argument than closure itself though:
void doSomething(@ClosureParams(/* how? */) Closure cl) { ... }
I can hack it like:
void doSomething(@ClosureParams(SecondParam) Closure cl, MyType ignore = null) { ... }
It's far from clean, is it not?
I can as well go:
void doSomething(@ClosureParams(value = SimpleType, options = ['com.somepackage.MyType']) Closure cl) { ... }
It's not only ugly and noisy but as well having type specified as string prevents some IDE features from working. For example MyType
refactor-rename or search for usages won't be picked up here.
I guess, there isn't any cleaner way of achieving this so type could be specified as a type not a string and without an extra unnecessary argument, is there?
Something like originally posted by Cédric Champeau in the blog post linked above would be ideal. Which in my case would look like:
void doSomething(@ClosureParams(MyType) Closure cl) { ... }
You may want to consider FromAbstractTypeMethods
signature hint instead of SimpleType
. It is quite verbose to use, but it gives you benefits that are missing from SimpleType
hint class - you can easily refactor types defined in the signatures class, as well as you can find usages of classes used in the signature hint. The main downside is that you need to create additional abstract class per closure signature hints, and the name of the class that contains signatures as abstract methods need to be defined as a constant string (the same problem exists with the SimpleType
signature hint.) However, you get a single parameter doSomething
method, without adding the second null
parameter just to be able to use SecondParam
signature hint.
package com.example
import groovy.transform.Immutable
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.FromAbstractTypeMethods
class MyClass {
static void doSomething(@ClosureParams(value = FromAbstractTypeMethods, options = ["com.example.MySignatures"]) Closure cl) {
cl.call()
}
static void main(String[] args) {
doSomething {
println it.name
}
}
}
@Immutable
class MyType {
String name
int x
int y
}
abstract class MySignatures {
abstract void firstSignature(MyType myType)
abstract void secondSignature(MyType myType, String str)
}
I guess the simple and clean @ClosureParams(String)
variant was removed to satisfy other more complex use cases. The API of ClosureParams
annotation is fixed and it limits options
to array of strings. Maybe it could be achieved by implementing own ClosureSignatureHint
- I have tried that several months ago, but I couldn't make IntelliJ IDEA to use my custom class to provide signature hints.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With