Search in sources :

Example 16 with Reference

use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.

the class NamedArgumentInvocation method makeVarRefArgumentList.

// Make a list of ($arg0, $arg1, ... , $argN)
// or ($arg$this$, $arg0, $arg1, ... , $argN)
private List<JCExpression> makeVarRefArgumentList(Parameter param) {
    ListBuffer<JCExpression> names = new ListBuffer<JCExpression>();
    if (!Strategy.defaultParameterMethodStatic(getPrimaryDeclaration()) && Strategy.defaultParameterMethodTakesThis(param.getModel())) {
        names.append(varBaseName.suffixedBy(Suffix.$argthis$).makeIdent());
    }
    // put all the required reified type args too
    Reference ref = gen.resolveAliasesForReifiedTypeArguments(producedReference);
    int tpCount = gen.getTypeParameters(ref).size();
    for (int tpIndex = 0; tpIndex < tpCount; tpIndex++) {
        names.append(reifiedTypeArgName(tpIndex).makeIdent());
    }
    final int parameterIndex = parameterIndex(param);
    for (int ii = 0; ii < parameterIndex; ii++) {
        names.append(this.argsNamesByIndex.get(ii).makeIdent());
    }
    return names.toList();
}
Also used : JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)

Example 17 with Reference

use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.

the class TypeArgumentInference method inferFunctionRefTypeArgs.

/**
 * Infer the type arguments for a reference to a
 * generic function that occurs as a parameter in
 * an invocation. This implementation is used when
 * have an indirect ref whose type is a type
 * constructor. This version is also used for
 * static references.
 */
private List<Type> inferFunctionRefTypeArgs(Tree.StaticMemberOrTypeExpression smte, Type receiverType, boolean secondList, Declaration reference, List<TypeParameter> typeParameters, Type paramType, Declaration parameterizedDec) {
    Reference arg = appliedReference(smte);
    // this is the type of the parameter list
    // of the function ref itself, which
    // involves the type parameters we are
    // trying to infer
    Type parameterListType;
    Type fullType;
    Type argType;
    if (smte.getStaticMethodReferencePrimary()) {
        argType = arg.getType();
        parameterListType = appliedType(unit.getTupleDeclaration(), argType, argType, unit.getEmptyType());
        fullType = appliedType(unit.getCallableDeclaration(), argType, parameterListType);
    } else {
        fullType = arg.getFullType();
        if (secondList) {
            fullType = unit.getCallableReturnType(fullType);
        }
        parameterListType = unit.getCallableTuple(fullType);
        argType = unit.getCallableReturnType(fullType);
    }
    // this is the type of the parameter list
    // of the callable parameter that the
    // function ref is being passed to (these
    // parameters are going to be assigned to
    // the parameters of the function ref)
    Type argumentListType = unit.getCallableTuple(paramType);
    Type returnType = unit.getCallableReturnType(paramType);
    int argCount = unit.getTupleElementTypes(argumentListType).size();
    List<Type> inferredTypes = new ArrayList<Type>(typeParameters.size());
    for (TypeParameter tp : typeParameters) {
        boolean findUpperBounds = isEffectivelyContravariant(tp, fullType, argCount);
        Type type = inferFunctionRefTypeArg(smte, tp, parameterizedDec, parameterListType, argumentListType, argType, returnType, findUpperBounds);
        inferredTypes.add(type);
    }
    return constrainInferredTypes(typeParameters, inferredTypes, receiverType, reference);
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) ArrayList(java.util.ArrayList)

Example 18 with Reference

use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.

the class TypeArgumentInference method inferNullaryFunctionCallTypeArgs.

/**
 * Infer type arguments for the invocation of a
 * nullary function that occurs as an argument.
 * The parameter to which it is an argument isn't
 * a callable parameter.
 */
private List<Type> inferNullaryFunctionCallTypeArgs(Tree.StaticMemberOrTypeExpression smte, Type receiverType, Declaration reference, List<TypeParameter> typeParameters, Type paramType, Declaration parameterizedDec) {
    Reference arg = appliedReference(smte);
    List<Type> inferredTypes = new ArrayList<Type>(typeParameters.size());
    Type argType = arg.getType();
    TypeDeclaration ptd = paramType.getDeclaration();
    Type template = // all supertypes of argType?
    ptd instanceof ClassOrInterface ? argType.getSupertype(ptd) : argType;
    for (TypeParameter tp : typeParameters) {
        boolean covariant = template.occursCovariantly(tp) && !template.occursContravariantly(tp);
        boolean contravariant = template.occursContravariantly(tp) && !template.occursCovariantly(tp);
        Type it = inferNullaryFunctionCallTypeArg(smte, tp, paramType, parameterizedDec, template, covariant, contravariant);
        inferredTypes.add(it);
    }
    return constrainInferredTypes(typeParameters, inferredTypes, receiverType, reference);
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) ArrayList(java.util.ArrayList) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 19 with Reference

use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.

the class TypeArgumentInference method constrainInferredTypes.

private List<Type> constrainInferredTypes(List<TypeParameter> typeParameters, List<Type> inferredTypeArgs, Type qualifyingType, Declaration declaration) {
    int size = inferredTypeArgs.size();
    boolean found = false;
    for (int i = 0; i < size; i++) {
        TypeParameter tp = typeParameters.get(i);
        // if (!tp.isCovariant()) {
        List<Type> bounds = tp.getSatisfiedTypes();
        if (!bounds.isEmpty()) {
            found = true;
        }
    // }
    }
    if (found) {
        Reference ref;
        if (declaration instanceof Value) {
            Value value = (Value) declaration;
            if (value.getType().isTypeConstructor()) {
                if (qualifyingType == null) {
                    ref = declaration.appliedReference(null, NO_TYPE_ARGS);
                } else {
                    ref = qualifyingType.getTypedReference(declaration, NO_TYPE_ARGS);
                }
                TypeDeclaration dec = ref.getType().getDeclaration();
                ref = dec.appliedReference(null, inferredTypeArgs);
            } else {
                return inferredTypeArgs;
            }
        } else {
            if (qualifyingType == null) {
                ref = declaration.appliedReference(null, inferredTypeArgs);
            } else {
                ref = qualifyingType.getTypedReference(declaration, inferredTypeArgs);
            }
        }
        Map<TypeParameter, Type> args = ref.getTypeArguments();
        ArrayList<Type> result = new ArrayList<Type>(size);
        for (int i = 0; i < size; i++) {
            TypeParameter tp = typeParameters.get(i);
            Type arg = inferredTypeArgs.get(i);
            Type constrainedArg = // tp.isCovariant() ? arg :
            constrainInferredType(tp, arg, args);
            result.add(constrainedArg);
        }
        return result;
    } else {
        return inferredTypeArgs;
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) ArrayList(java.util.ArrayList) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 20 with Reference

use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.

the class ExpressionVisitor method visitDirectInvocation.

/**
 * Typecheck a direct invocation.
 */
private void visitDirectInvocation(Tree.InvocationExpression that) {
    Tree.Term primary = unwrapExpressionUntilTerm(that.getPrimary());
    if (primary == null) {
        return;
    }
    Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) primary;
    Reference prf = mte.getTarget();
    Declaration dec = mte.getDeclaration();
    Functional fun = (Functional) dec;
    if (dec != null) {
        if (!(primary instanceof Tree.ExtendedTypeExpression)) {
            if (dec instanceof Class) {
                Class c = (Class) dec;
                if (c.isAbstract()) {
                    that.addError("abstract class may not be instantiated: '" + dec.getName(unit) + "'");
                }
            }
        }
        Tree.NamedArgumentList nal = that.getNamedArgumentList();
        if (nal != null && dec.isAbstraction()) {
            // TODO: this is not really right - it's the fact
            // that we're calling Java and don't have
            // meaningful parameter names that is the
            // real problem, not the overload
            that.addError("overloaded declarations may not be called using named arguments: '" + dec.getName(unit) + "'");
        }
        // that.setTypeModel(prf.getType());
        Type ct = primary.getTypeModel();
        if (ct != null) {
            List<Type> tal = ct.getTypeArgumentList();
            if (!tal.isEmpty()) {
                // pull the return type out of the Callable
                that.setTypeModel(tal.get(0));
            }
        }
        if (nal != null) {
            List<ParameterList> parameterLists = fun.getParameterLists();
            if (!parameterLists.isEmpty() && !parameterLists.get(0).isNamedParametersSupported()) {
                that.addError("named invocations of Java methods not supported");
            }
        }
        if (dec.isAbstraction()) {
        // nothing to check the argument types against
        // that.addError("no matching overloaded declaration");
        } else {
            // typecheck arguments using the parameter list
            // of the target declaration
            checkInvocationArguments(that, prf, fun);
        }
    }
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ModelUtil.findMatchingOverloadedClass(org.eclipse.ceylon.model.typechecker.model.ModelUtil.findMatchingOverloadedClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)

Aggregations

Reference (org.eclipse.ceylon.model.typechecker.model.Reference)42 TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)28 Type (org.eclipse.ceylon.model.typechecker.model.Type)25 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)22 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)21 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)20 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)20 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)17 Function (org.eclipse.ceylon.model.typechecker.model.Function)13 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)12 ArrayList (java.util.ArrayList)11 Functional (org.eclipse.ceylon.model.typechecker.model.Functional)11 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)11 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)10 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)10 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)10 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)9 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)9 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)8 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)8