protected ClassNode getType()

in src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java [5168:5294]


    protected ClassNode getType(final ASTNode node) {
        ClassNode type = node.getNodeMetaData(INFERRED_TYPE);
        if (type != null) {
            return type;
        }

        if (node instanceof ClassExpression) {
            type = ((ClassExpression) node).getType();
            return makeClassSafe0(CLASS_Type, new GenericsType(type));
        }

        if (node instanceof VariableExpression) {
            VariableExpression vexp = (VariableExpression) node;
            type = isTraitSelf(vexp);
            if (type != null) return makeSelf(type);
            if (vexp.isThisExpression()) return makeThis();
            if (vexp.isSuperExpression()) return makeSuper();

            Variable variable = vexp.getAccessedVariable();
            if (variable instanceof FieldNode) {
                FieldNode fieldNode = (FieldNode) variable;
                ClassNode fieldType = fieldNode.getOriginType();
                if (!fieldNode.isStatic() && GenericsUtils.hasUnresolvedGenerics(fieldType)) {
                    ClassNode declType = fieldNode.getDeclaringClass(), thisType = typeCheckingContext.getEnclosingClassNode();
                    fieldType = resolveGenericsWithContext(extractPlaceHolders(thisType, declType), fieldType);
                }
                return fieldType;
            }
            if (variable != vexp && variable instanceof VariableExpression) {
                return getType((VariableExpression) variable);
            }
            if (variable instanceof Parameter) {
                Parameter parameter = (Parameter) variable;
                // check if param part of control structure - but not if inside instanceof
                List<ClassNode> temporaryTypesForExpression = getTemporaryTypesForExpression(vexp);
                if (temporaryTypesForExpression == null || temporaryTypesForExpression.isEmpty()) {
                    type = typeCheckingContext.controlStructureVariables.get(parameter);
                }
                // now check for closure override
                if (type == null && temporaryTypesForExpression == null) {
                    type = getTypeFromClosureArguments(parameter);
                }
                if (type != null) {
                    storeType(vexp, type);
                    return type;
                }
                return getType((Parameter) variable);
            }
            return vexp.getOriginType();
        }

        if (node instanceof Parameter || node instanceof FieldNode || node instanceof PropertyNode) {
            return ((Variable) node).getOriginType();
        }

        if (node instanceof MethodNode) {
            type = ((MethodNode) node).getReturnType();
            return Optional.ofNullable(getInferredReturnType(node)).orElse(type);
        }

        if (node instanceof MethodCall) {
            if (node instanceof ConstructorCallExpression) {
                return ((ConstructorCallExpression) node).getType();
            }
            MethodNode target = node.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
            if (target != null) {
                return getType(target);
            }
        }

        if (node instanceof ClosureExpression) {
            type = CLOSURE_TYPE.getPlainNodeReference();
            ClassNode returnType = getInferredReturnType(node);
            if (returnType != null) {
                type.setGenericsTypes(new GenericsType[]{
                    new GenericsType(wrapTypeIfNecessary(returnType))
                });
            }
            Parameter[] parameters = ((ClosureExpression) node).getParameters();
            int nParameters = parameters == null ? 0
               : parameters.length == 0 ? -1 : parameters.length;
            type.putNodeMetaData(CLOSURE_ARGUMENTS, nParameters);
            return type;
        }

        if (node instanceof ListExpression) {
            return inferListExpressionType((ListExpression) node);
        }

        if (node instanceof MapExpression) {
            return inferMapExpressionType((MapExpression) node);
        }

        if (node instanceof RangeExpression) {
            RangeExpression re = (RangeExpression) node;
            ClassNode fromType = getType(re.getFrom());
            ClassNode toType = getType(re.getTo());
            if (fromType.equals(toType)) {
                type = wrapTypeIfNecessary(fromType);
            } else {
                type = wrapTypeIfNecessary(lowestUpperBound(fromType, toType));
            }
            return makeClassSafe0(RANGE_TYPE, new GenericsType(type));
        }

        if (node instanceof SpreadExpression) {
            type = getType(((SpreadExpression) node).getExpression());
            type = inferComponentType(type, null); // for list literal
            if (type == null) // GROOVY-11572: not an iterable
                type = UNKNOWN_PARAMETER_TYPE;
            return type;
        }

        if (node instanceof UnaryPlusExpression) {
            return getType(((UnaryPlusExpression) node).getExpression());
        }

        if (node instanceof UnaryMinusExpression) {
            return getType(((UnaryMinusExpression) node).getExpression());
        }

        if (node instanceof BitwiseNegationExpression) {
            return getType(((BitwiseNegationExpression) node).getExpression());
        }

        return ((Expression) node).getType();
    }