У меня есть следующий метод в Java:
public void myMethod(
@ClosureParams(
value = SimpleType.class,
options = {
"java.util.Map"
}
) Closure<String> closure
) {
...
}
, в котором есть @ClosureParams
для указания типов параметров замыкания для статической проверки типов и вывода типов в IDEA.
В скрипте Groovy этот метод вызывается следующим образом:
myMethod { Map<String, Object> doc ->
...
}
и работает нормально. Но когда я пытаюсь указать универсальные типы для java.util.Map
замыкания в моем методе java:
public void myMethod(
@ClosureParams(
value = SimpleType.class,
options = {
"java.util.Map<java.lang.String,java.lang.Object>" // <-- added here
}
) Closure<String> closure
) {
...
}
Статическая проверка типа groovy завершается с ошибкой:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
C:\myproject\script.groovy: 1: Expected parameter of type java.util.Map<java.lang.String,java.lang.Object> but got java.util.Map <String, Object>
@ line 1, column 8.
myMethod { Map<String, Object> doc ->
хотя IDEA выводит тип doc
без каких-либо Map
или Map<...>
, используя @ClosureParams
подсказку.
Когда я смотрю на источник класса groovy.transform.stc.SimpleType
, я вижу, что этот класс не дает возможности указывать универсальные типы, так как использует простой Class.forName
:
public class SimpleType extends SingleSignatureClosureHint {
@Override
public ClassNode[] getParameterTypes(final MethodNode node, final String[] options, final SourceUnit sourceUnit, final CompilationUnit unit, final ASTNode usage) {
ClassNode[] result = new ClassNode[options.length];
for (int i = 0; i < result.length; i++) {
result[i] = findClassNode(sourceUnit, unit, options[i]);
}
return result;
}
}
// findClassNode method:
protected ClassNode findClassNode(final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final String className) {
if (className.endsWith("[]")) {
return findClassNode(sourceUnit, compilationUnit, className.substring(0, className.length() - 2)).makeArray();
}
ClassNode cn = compilationUnit.getClassNode(className);
if (cn == null) {
try {
cn = ClassHelper.make(Class.forName(className, false, sourceUnit.getClassLoader()));
} catch (ClassNotFoundException e) {
cn = ClassHelper.make(className);
}
}
return cn;
}
Мой вопрос: как указать тип параметра замыкания с обобщениями в groovy? Желательно с поддержкой в IDEA.