Search in sources :

Example 26 with ParameterList

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

the class TypeArgumentInference method getInferredTypeArgsForStaticReference.

/**
 * Infer type arguments for the qualifying type in a
 * static method reference that is directly invoked.
 * This method does not correctly handle stuff like
 * constructors or Java static methods.
 *
 * @param that the invocation
 * @param type the type whose type arguments we're
 *             inferring (the qualifying type)
 * @param receiverType
 */
List<Type> getInferredTypeArgsForStaticReference(Tree.InvocationExpression that, TypeDeclaration type, Type receiverType, Tree.MemberOrTypeExpression primary) {
    Tree.PositionalArgumentList pal = that.getPositionalArgumentList();
    Declaration invoked = primary.getDeclaration();
    if (pal == null) {
        return null;
    } else {
        if (invoked instanceof Functional) {
            List<PositionalArgument> args = pal.getPositionalArguments();
            Functional fun = (Functional) invoked;
            List<ParameterList> parameterLists = fun.getParameterLists();
            if (args.isEmpty() || parameterLists.isEmpty()) {
                return null;
            } else {
                // a static method ref invocation has exactly
                // one meaningful argument (the instance of
                // the receiving type)
                Tree.PositionalArgument arg = args.get(0);
                if (arg == null) {
                    return null;
                } else {
                    Type at = arg.getTypeModel();
                    Type tt = type.getType();
                    List<TypeParameter> typeParams = type.getTypeParameters();
                    List<Type> typeArgs = new ArrayList<Type>(typeParams.size());
                    for (TypeParameter tp : typeParams) {
                        Type it = inferTypeArg(tp, tt, at, // TODO: is this 100% correct?
                        false, arg);
                        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(typeParams, typeArgs, receiverType, invoked);
                }
            }
        } else {
            return null;
        }
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ArrayList(java.util.ArrayList) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) 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) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 27 with ParameterList

use of org.eclipse.ceylon.model.typechecker.model.ParameterList 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)

Example 28 with ParameterList

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

the class ExpressionVisitor method inferParameterTypesDirectly.

/**
 * Infer parameter types of anonymous function arguments
 * in a direct invocation with positional arguments.
 */
private boolean[] inferParameterTypesDirectly(Tree.PositionalArgumentList pal, Tree.MemberOrTypeExpression mte, Declaration dec, boolean error) {
    List<Tree.PositionalArgument> args = pal.getPositionalArguments();
    int argCount = args.size();
    boolean[] delayed = new boolean[argCount];
    Functional fun = (Functional) dec;
    List<ParameterList> pls = fun.getParameterLists();
    if (!pls.isEmpty()) {
        List<Parameter> params = pls.get(0).getParameters();
        Reference reference = getInvokedProducedReference(dec, mte);
        int paramsSize = params.size();
        for (int i = 0, j = 0; i < argCount && j < paramsSize; i++) {
            Parameter param = params.get(j);
            Tree.PositionalArgument arg = args.get(i);
            arg.setParameter(param);
            if (arg instanceof Tree.ListedArgument) {
                Tree.ListedArgument la = (Tree.ListedArgument) arg;
                delayed[i] = !inferParameterTypes(reference, param, la.getExpression(), param.isSequenced(), error);
            }
            if (!param.isSequenced()) {
                j++;
            }
        }
    }
    return delayed;
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) 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) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) 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) 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)

Example 29 with ParameterList

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

the class ExpressionVisitor method createAnonymousFunctionParameters.

/**
 * Create the parameter list of the given
 * anonymous function with a missing argument
 * list, from the given parameter list of a
 * functional parameter to which it is assigned.
 */
private void createAnonymousFunctionParameters(List<Parameter> parameters, Tree.Term term, Tree.FunctionArgument anon) {
    Function model = anon.getDeclarationModel();
    if (anon.getParameterLists().isEmpty()) {
        Tree.ParameterList pl = new Tree.ParameterList(null);
        ParameterList mpl = new ParameterList();
        for (Parameter parameter : parameters) {
            Tree.InitializerParameter ip = new Tree.InitializerParameter(null);
            CommonToken token = new CommonToken(LIDENTIFIER, parameter.getName());
            token.setStartIndex(term.getStartIndex());
            Token tok = term.getToken();
            token.setLine(tok.getLine());
            token.setCharPositionInLine(tok.getCharPositionInLine());
            Tree.Identifier id = new Tree.Identifier(token);
            ip.setIdentifier(id);
            pl.addParameter(ip);
            ip.setUnit(unit);
            ip.setScope(model);
            id.setUnit(unit);
            id.setScope(model);
            Parameter mp = new Parameter();
            mp.setDeclaration(model);
            mp.setName(parameter.getName());
            ip.setParameterModel(mp);
            mpl.getParameters().add(mp);
            pl.setModel(mpl);
        }
        pl.setUnit(unit);
        pl.setScope(model);
        model.addParameterList(mpl);
        anon.addParameterList(pl);
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) 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) CommonToken(org.antlr.runtime.CommonToken) Token(org.antlr.runtime.Token) CommonToken(org.antlr.runtime.CommonToken)

Example 30 with ParameterList

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

the class FunctionalUtil method getParameters.

@SuppressWarnings({ "unchecked", "rawtypes" })
public static Sequential<FunctionOrValueDeclaration> getParameters(Functional declaration) {
    ParameterList parameterList = ((Functional) declaration).getFirstParameterList();
    if (parameterList == null)
        return (Sequential) empty_.get_();
    List<Parameter> modelParameters = parameterList.getParameters();
    ceylon.language.meta.declaration.FunctionOrValueDeclaration[] parameters = new ceylon.language.meta.declaration.FunctionOrValueDeclaration[modelParameters.size()];
    int i = 0;
    for (Parameter modelParameter : modelParameters) {
        parameters[i] = (ceylon.language.meta.declaration.FunctionOrValueDeclaration) Metamodel.getOrCreateMetamodel(modelParameter.getModel());
        i++;
    }
    return Util.sequentialWrapper(ceylon.language.meta.declaration.FunctionOrValueDeclaration.$TypeDescriptor$, parameters);
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) FunctionOrValueDeclaration(ceylon.language.meta.declaration.FunctionOrValueDeclaration)

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