Search in sources :

Example 41 with ParameterList

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

the class ExpressionVisitor method setArgumentParameters.

/**
 * Set up references from positional arguments to
 * parameters for later use during type inference. This
 * is only necessary here because in the case of an
 * overloaded Java function or constructors, the
 * overload has not been resolved the first time we
 * visit the arguments. So we need to revisit them here
 * with the fully-resolved overloaded version.
 *
 * @param that an invocation
 * @param invoked the thing being invoked
 */
private void setArgumentParameters(Tree.InvocationExpression that, Declaration invoked) {
    if (invoked instanceof Functional) {
        Functional fun = (Functional) invoked;
        List<ParameterList> pls = fun.getParameterLists();
        if (!pls.isEmpty()) {
            ParameterList pl = pls.get(0);
            // no need to do named arg lists because
            // they can't be used with overloaded decs
            Tree.PositionalArgumentList pal = that.getPositionalArgumentList();
            if (pal != null) {
                List<Tree.PositionalArgument> args = pal.getPositionalArguments();
                List<Parameter> params = pl.getParameters();
                for (int i = 0, j = 0; i < args.size() && j < params.size(); i++) {
                    Tree.PositionalArgument arg = args.get(i);
                    Parameter param = params.get(j);
                    if (arg != null && param != null) {
                        arg.setParameter(param);
                    }
                    if (param == null || !param.isSequenced()) {
                        j++;
                    }
                }
            }
        }
    }
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) AnalyzerUtil.getUnspecifiedParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getUnspecifiedParameter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) AnalyzerUtil.getMatchingParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getMatchingParameter) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint)

Example 42 with ParameterList

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

the class ExpressionVisitor method checkClassAliasParameters.

private void checkClassAliasParameters(Class alias, Tree.ClassDeclaration that, Tree.InvocationExpression ie) {
    Tree.Primary primary = ie.getPrimary();
    Tree.ExtendedTypeExpression smte = (Tree.ExtendedTypeExpression) primary;
    Functional classOrConstructor = (Functional) smte.getDeclaration();
    ParameterList cpl = classOrConstructor.getFirstParameterList();
    ParameterList apl = alias.getParameterList();
    if (cpl != null && apl != null) {
        List<Parameter> cplps = cpl.getParameters();
        List<Parameter> aplps = apl.getParameters();
        int cps = cplps.size();
        int aps = aplps.size();
        if (cps != aps) {
            that.getParameterList().addUnsupportedError("wrong number of initializer parameters declared by class alias: '" + alias.getName() + "'");
        }
        for (int i = 0; i < cps && i < aps; i++) {
            Parameter ap = aplps.get(i);
            Parameter cp = cplps.get(i);
            Reference target = smte.getTarget();
            FunctionOrValue apm = ap.getModel();
            if (apm != null && target != null) {
                Type pt = target.getTypedParameter(cp).getFullType();
                Type apt = apm.getReference().getFullType();
                if (!isTypeUnknown(pt) && !isTypeUnknown(apt) && !apt.isSubtypeOf(pt)) {
                    that.addUnsupportedError("alias parameter '" + ap.getName() + "' must be assignable to corresponding class parameter '" + cp.getName() + "'" + notAssignableMessage(apt, pt, that));
                }
            }
        }
        // temporary restrictions
        checkAliasedClass(that, cpl, apl);
    }
}
Also used : 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) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) AnalyzerUtil.getUnspecifiedParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getUnspecifiedParameter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) AnalyzerUtil.getMatchingParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getMatchingParameter) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 43 with ParameterList

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

the class RefinementVisitor method refineMethod.

private void refineMethod(Function assignedMethod, Tree.BaseMemberExpression bme, Tree.SpecifierStatement that, ClassOrInterface c) {
    if (!assignedMethod.isFormal() && !assignedMethod.isDefault() && !assignedMethod.isShortcutRefinement()) {
        // this condition is here to squash a dupe message
        bme.addError("inherited method may not be refined: " + message(assignedMethod) + " is declared neither 'formal' nor 'default'", 510);
    // return;
    }
    ClassOrInterface ci = (ClassOrInterface) assignedMethod.getContainer();
    String name = assignedMethod.getName();
    List<Type> signature = getSignature(assignedMethod);
    boolean variadic = isVariadic(assignedMethod);
    Declaration refined = ci.getRefinedMember(name, signature, variadic);
    Function root = refined instanceof Function ? (Function) refined : assignedMethod;
    Reference rm = getRefinedMemberReference(assignedMethod, c);
    Function method = new Function();
    method.setName(name);
    List<Tree.ParameterList> paramLists;
    List<TypeParameter> typeParams;
    Tree.Term me = that.getBaseMemberExpression();
    if (me instanceof Tree.ParameterizedExpression) {
        Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) me;
        paramLists = pe.getParameterLists();
        Tree.TypeParameterList typeParameterList = pe.getTypeParameterList();
        if (typeParameterList != null) {
            typeParams = new ArrayList<TypeParameter>();
            for (Tree.TypeParameterDeclaration tpd : typeParameterList.getTypeParameterDeclarations()) {
                typeParams.add(tpd.getDeclarationModel());
            }
        } else {
            typeParams = null;
        }
    } else {
        paramLists = emptyList();
        typeParams = null;
    }
    Unit unit = that.getUnit();
    final Map<TypeParameter, Type> subs;
    if (typeParams != null) {
        // the type parameters are written
        // down in the shortcut refinement
        method.setTypeParameters(typeParams);
        // TODO: check 'em!!
        // no need to check them because
        // this case is actually disallowed
        // elsewhere (specification statements
        // may not have type parameters)
        subs = NO_SUBSTITUTIONS;
    } else if (assignedMethod.isParameterized()) {
        if (me instanceof Tree.ParameterizedExpression) {
            // we have parameters, but no type parameters
            bme.addError("refined method is generic: '" + assignedMethod.getName(unit) + "' declares type parameters");
            subs = NO_SUBSTITUTIONS;
        } else {
            // we're assigning a method reference
            // so we need to magic up some "fake"
            // type parameters
            subs = copyTypeParametersFromRefined(assignedMethod, method, unit);
        }
    } else {
        subs = NO_SUBSTITUTIONS;
    }
    int i = 0;
    for (ParameterList pl : assignedMethod.getParameterLists()) {
        Tree.ParameterList params = paramLists.size() <= i ? null : paramLists.get(i++);
        createRefiningParameterList(rm, method, params, unit, subs, pl);
    }
    method.setShared(true);
    method.setActual(true);
    method.getAnnotations().add(new Annotation("shared"));
    method.getAnnotations().add(new Annotation("actual"));
    method.setRefinedDeclaration(root);
    method.setUnit(unit);
    method.setContainer(c);
    method.setScope(c);
    method.setShortcutRefinement(true);
    method.setDeclaredVoid(assignedMethod.isDeclaredVoid());
    Declaration rmd = rm.getDeclaration();
    if (rmd instanceof TypedDeclaration) {
        TypedDeclaration rmtd = (TypedDeclaration) rmd;
        method.setUncheckedNullType(rmtd.hasUncheckedNullType());
    }
    ModelUtil.setVisibleScope(method);
    c.addMember(method);
    that.setRefinement(true);
    that.setDeclaration(method);
    that.setRefined(root);
    unit.addDeclaration(method);
    Scope scope = that.getScope();
    if (scope instanceof Specification) {
        Specification spec = (Specification) scope;
        spec.setDeclaration(method);
    }
    setRefiningType(c, ci, name, signature, variadic, root, method, unit, subs);
    inheritDefaultedArguments(method);
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Function(org.eclipse.ceylon.model.typechecker.model.Function) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) 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.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) ExpressionVisitor.getRefinedMemberReference(org.eclipse.ceylon.compiler.typechecker.analyzer.ExpressionVisitor.getRefinedMemberReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) Specification(org.eclipse.ceylon.model.typechecker.model.Specification) Annotation(org.eclipse.ceylon.model.typechecker.model.Annotation) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) LazyType(org.eclipse.ceylon.model.typechecker.model.LazyType) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.erasedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.erasedType) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ModelUtil.getRealScope(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList)

Example 44 with ParameterList

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

the class TypeArgumentInference method inferFunctionRefTypeArgs.

/**
 * Infer type arguments for a direct function
 * ref (i.e. not a value ref with a type
 * constructor type) that occurs as an argument
 * to a callable parameter.
 */
private List<Type> inferFunctionRefTypeArgs(Tree.StaticMemberOrTypeExpression smte, Type receiverType, boolean secondList, Declaration reference, List<TypeParameter> typeParameters, TypedReference paramTypedRef, Declaration paramDec, Declaration parameterizedDec) {
    Reference arg = appliedReference(smte);
    Functional fun = (Functional) reference;
    List<ParameterList> apls = fun.getParameterLists();
    Functional pfun = (Functional) paramDec;
    List<ParameterList> ppls = pfun.getParameterLists();
    if (apls.isEmpty() || ppls.isEmpty()) {
        // TODO: to give a nicer error
        return null;
    } else {
        ParameterList aplf = apls.get(secondList ? 1 : 0);
        ParameterList pplf = ppls.get(0);
        List<Parameter> apl = aplf.getParameters();
        List<Parameter> ppl = pplf.getParameters();
        boolean[] specifiedParams = specifiedParameters(apl.size(), ppl.size());
        List<Type> inferredTypes = new ArrayList<Type>(typeParameters.size());
        for (TypeParameter tp : typeParameters) {
            boolean findUpperBounds = isEffectivelyContravariant(tp, reference, specifiedParams, secondList);
            Type it = inferFunctionRefTypeArg(smte, tp, typeParameters, paramTypedRef, parameterizedDec, arg, apl, ppl, findUpperBounds);
            inferredTypes.add(it);
        }
        return constrainInferredTypes(typeParameters, inferredTypes, receiverType, reference);
    }
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) 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) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) AnalyzerUtil.getUnspecifiedParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getUnspecifiedParameter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) AnalyzerUtil.getMatchingParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getMatchingParameter)

Example 45 with ParameterList

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

the class TypeArgumentInference method getInferredTypeArgsForReference.

/**
 * Infer type arguments for a given generic declaration,
 * using the value arguments of an invocation of a given
 * declaration.
 *
 * @param that the invocation
 * @param invoked the thing actually being invoked
 * @param generic the thing we're inferring type
 *        arguments for, which may not be the thing
 *        actually being invoked
 * @param receiverType
 *
 * @return a list of inferred type arguments
 */
List<Type> getInferredTypeArgsForReference(Tree.InvocationExpression that, Declaration invoked, Declaration generic, Type receiverType) {
    if (invoked instanceof Functional) {
        Functional functional = (Functional) invoked;
        List<ParameterList> parameterLists = functional.getParameterLists();
        if (parameterLists.isEmpty()) {
            return null;
        } else {
            List<Type> typeArgs = new ArrayList<Type>();
            List<TypeParameter> typeParameters = generic.getTypeParameters();
            for (TypeParameter tp : typeParameters) {
                ParameterList pl = parameterLists.get(0);
                Type it = inferTypeArgument(that, receiverType, tp, pl, invoked);
                if (it == null || it.containsUnknowns()) {
                    that.addError("could not infer type argument from given arguments: type parameter '" + tp.getName() + "' could not be inferred");
                }
                typeArgs.add(it);
            }
            return constrainInferredTypes(typeParameters, typeArgs, receiverType, invoked);
        }
    } else {
        return null;
    }
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) 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) ArrayList(java.util.ArrayList) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList)

Aggregations

ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)69 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)47 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)44 Type (org.eclipse.ceylon.model.typechecker.model.Type)25 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)24 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)24 Functional (org.eclipse.ceylon.model.typechecker.model.Functional)23 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)22 Function (org.eclipse.ceylon.model.typechecker.model.Function)21 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)20 Value (org.eclipse.ceylon.model.typechecker.model.Value)20 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)19 ArrayList (java.util.ArrayList)16 AnalyzerUtil.getMatchingParameter (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getMatchingParameter)12 AnalyzerUtil.getUnspecifiedParameter (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getUnspecifiedParameter)12 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)12 FieldValue (org.eclipse.ceylon.model.loader.model.FieldValue)12 Class (org.eclipse.ceylon.model.typechecker.model.Class)11 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)10 HashMap (java.util.HashMap)9