Search in sources :

Example 91 with GenericsType

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;
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) LinkedHashMap(java.util.LinkedHashMap) ListHashMap(org.codehaus.groovy.util.ListHashMap) HashMap(java.util.HashMap) GenericsType(org.codehaus.groovy.ast.GenericsType) Parameter(org.codehaus.groovy.ast.Parameter) ClosureSignatureHint(groovy.transform.stc.ClosureSignatureHint)

Example 92 with GenericsType

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;
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType)

Example 93 with GenericsType

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;
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType)

Example 94 with GenericsType

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;
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) GenericsType(org.codehaus.groovy.ast.GenericsType) ClosureSignatureHint(groovy.transform.stc.ClosureSignatureHint)

Example 95 with GenericsType

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;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) ParserException(org.codehaus.groovy.syntax.ParserException) IncorrectTypeHintException(groovy.transform.stc.IncorrectTypeHintException) AtomicReference(java.util.concurrent.atomic.AtomicReference) SourceUnit(org.codehaus.groovy.control.SourceUnit) TokenStreamException(antlr.TokenStreamException) Reduction(org.codehaus.groovy.syntax.Reduction) AntlrParserPlugin(org.codehaus.groovy.antlr.AntlrParserPlugin) GroovyLexer(org.codehaus.groovy.antlr.parser.GroovyLexer) StringReader(java.io.StringReader) GenericsType(org.codehaus.groovy.ast.GenericsType) GroovyRecognizer(org.codehaus.groovy.antlr.parser.GroovyRecognizer) RecognitionException(antlr.RecognitionException)

Aggregations

GenericsType (org.codehaus.groovy.ast.GenericsType)171 ClassNode (org.codehaus.groovy.ast.ClassNode)148 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)76 LowestUpperBoundClassNode (org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode)52 Parameter (org.codehaus.groovy.ast.Parameter)21 MethodNode (org.codehaus.groovy.ast.MethodNode)20 ClosureSignatureHint (groovy.transform.stc.ClosureSignatureHint)19 LinkedList (java.util.LinkedList)18 HashMap (java.util.HashMap)17 ArrayList (java.util.ArrayList)15 LinkedHashMap (java.util.LinkedHashMap)9 AST (antlr.collections.AST)8 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)8 ListHashMap (org.codehaus.groovy.util.ListHashMap)8 Map (java.util.Map)6 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 EnumConstantClassNode (org.codehaus.groovy.ast.EnumConstantClassNode)6 FieldNode (org.codehaus.groovy.ast.FieldNode)6 GroovyBugError (org.codehaus.groovy.GroovyBugError)5 DynamicVariable (org.codehaus.groovy.ast.DynamicVariable)4