use of org.codehaus.groovy.ast.GenericsType in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method inferSAMTypeGenericsInAssignment.
private ClassNode inferSAMTypeGenericsInAssignment(ClassNode samUsage, MethodNode sam, ClassNode closureType, ClosureExpression closureExpression) {
// if the sam type or closure type do not provide generics information,
// we cannot infer anything, thus we simply return the provided samUsage
GenericsType[] samGt = samUsage.getGenericsTypes();
GenericsType[] closureGt = closureType.getGenericsTypes();
if (samGt == null || closureGt == null)
return samUsage;
// extract the generics from the return type
Map<String, GenericsType> connections = new HashMap<String, GenericsType>();
extractGenericsConnections(connections, closureType, sam.getReturnType());
// next we get the block parameter types and set the generics
// information just like before
// TODO: add vargs handling
Parameter[] closureParams = closureExpression.getParameters();
Parameter[] methodParams = sam.getParameters();
for (int i = 0; i < closureParams.length; i++) {
ClassNode fromClosure = closureParams[i].getType();
ClassNode fromMethod = methodParams[i].getType();
extractGenericsConnections(connections, fromClosure, fromMethod);
}
ClassNode result = applyGenericsContext(connections, samUsage.redirect());
return result;
}
use of org.codehaus.groovy.ast.GenericsType in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method getTypeForMapPropertyExpression.
private ClassNode getTypeForMapPropertyExpression(ClassNode testClass, ClassNode objectExpressionType, PropertyExpression pexp) {
if (!implementsInterfaceOrIsSubclassOf(testClass, MAP_TYPE))
return null;
ClassNode intf;
if (objectExpressionType.getGenericsTypes() != null) {
intf = GenericsUtils.parameterizeType(objectExpressionType, MAP_TYPE.getPlainNodeReference());
} else {
intf = MAP_TYPE.getPlainNodeReference();
}
// 0 is the key, 1 is the value
GenericsType[] types = intf.getGenericsTypes();
if (types == null || types.length != 2)
return OBJECT_TYPE;
if (pexp.isSpreadSafe()) {
// only "key" and "value" are allowed
if ("key".equals(pexp.getPropertyAsString())) {
ClassNode listKey = LIST_TYPE.getPlainNodeReference();
listKey.setGenericsTypes(new GenericsType[] { types[0] });
return listKey;
} else if ("value".equals(pexp.getPropertyAsString())) {
ClassNode listValue = LIST_TYPE.getPlainNodeReference();
listValue.setGenericsTypes(new GenericsType[] { types[1] });
return listValue;
} else {
addStaticTypeError("Spread operator on map only allows one of [key,value]", pexp);
}
} else {
return types[1].getType();
}
return null;
}
use of org.codehaus.groovy.ast.GenericsType in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method makeSuper.
private ClassNode makeSuper() {
ClassNode ret = typeCheckingContext.getEnclosingClassNode().getSuperClass();
if (typeCheckingContext.isInStaticContext) {
ClassNode staticRet = CLASS_Type.getPlainNodeReference();
GenericsType gt = new GenericsType(ret);
staticRet.setGenericsTypes(new GenericsType[] { gt });
ret = staticRet;
}
return ret;
}
use of org.codehaus.groovy.ast.GenericsType in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method resolveGenericsFromTypeHint.
private ClassNode[] resolveGenericsFromTypeHint(final ClassNode receiver, final Expression arguments, final MethodNode selectedMethod, final ClassNode[] signature) {
ClassNode dummyResultNode = new ClassNode("ClForInference$" + UNIQUE_LONG.incrementAndGet(), 0, OBJECT_TYPE).getPlainNodeReference();
final GenericsType[] genericTypes = new GenericsType[signature.length];
for (int i = 0; i < signature.length; i++) {
genericTypes[i] = new GenericsType(signature[i]);
}
dummyResultNode.setGenericsTypes(genericTypes);
MethodNode dummyMN = selectedMethod instanceof ExtensionMethodNode ? ((ExtensionMethodNode) selectedMethod).getExtensionMethodNode() : selectedMethod;
dummyMN = new MethodNode(dummyMN.getName(), dummyMN.getModifiers(), dummyResultNode, dummyMN.getParameters(), dummyMN.getExceptions(), EmptyStatement.INSTANCE);
dummyMN.setDeclaringClass(selectedMethod.getDeclaringClass());
dummyMN.setGenericsTypes(selectedMethod.getGenericsTypes());
if (selectedMethod instanceof ExtensionMethodNode) {
ExtensionMethodNode orig = (ExtensionMethodNode) selectedMethod;
dummyMN = new ExtensionMethodNode(dummyMN, dummyMN.getName(), dummyMN.getModifiers(), dummyResultNode, orig.getParameters(), orig.getExceptions(), EmptyStatement.INSTANCE, orig.isStaticExtension());
dummyMN.setDeclaringClass(orig.getDeclaringClass());
dummyMN.setGenericsTypes(orig.getGenericsTypes());
}
ClassNode classNode = inferReturnTypeGenerics(receiver, dummyMN, arguments);
ClassNode[] inferred = new ClassNode[classNode.getGenericsTypes().length];
for (int i = 0; i < classNode.getGenericsTypes().length; i++) {
GenericsType genericsType = classNode.getGenericsTypes()[i];
ClassNode value = createUsableClassNodeFromGenericsType(genericsType);
inferred[i] = value;
}
return inferred;
}
use of org.codehaus.groovy.ast.GenericsType in project groovy-core by groovy.
the class GenericsUtils method parseClassNodesFromString.
public static ClassNode[] parseClassNodesFromString(final String option, final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final MethodNode mn, final ASTNode usage) {
GroovyLexer lexer = new GroovyLexer(new StringReader("DummyNode<" + option + ">"));
final GroovyRecognizer rn = GroovyRecognizer.make(lexer);
try {
rn.classOrInterfaceType(true);
final AtomicReference<ClassNode> ref = new AtomicReference<ClassNode>();
AntlrParserPlugin plugin = new AntlrParserPlugin() {
@Override
public ModuleNode buildAST(final SourceUnit sourceUnit, final ClassLoader classLoader, final Reduction cst) throws ParserException {
ref.set(makeTypeWithArguments(rn.getAST()));
return null;
}
};
plugin.buildAST(null, null, null);
ClassNode parsedNode = ref.get();
// the returned node is DummyNode<Param1, Param2, Param3, ...)
GenericsType[] parsedNodeGenericsTypes = parsedNode.getGenericsTypes();
if (parsedNodeGenericsTypes == null) {
return null;
}
ClassNode[] signature = new ClassNode[parsedNodeGenericsTypes.length];
for (int i = 0; i < parsedNodeGenericsTypes.length; i++) {
final GenericsType genericsType = parsedNodeGenericsTypes[i];
signature[i] = resolveClassNode(sourceUnit, compilationUnit, mn, usage, genericsType.getType());
}
return signature;
} catch (RecognitionException e) {
sourceUnit.addError(new IncorrectTypeHintException(mn, e, usage.getLineNumber(), usage.getColumnNumber()));
} catch (TokenStreamException e) {
sourceUnit.addError(new IncorrectTypeHintException(mn, e, usage.getLineNumber(), usage.getColumnNumber()));
} catch (ParserException e) {
sourceUnit.addError(new IncorrectTypeHintException(mn, e, usage.getLineNumber(), usage.getColumnNumber()));
}
return null;
}
Aggregations