Search in sources :

Example 11 with ClassOrInterface

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

the class ExpressionVisitor method getBaseReceivingType.

protected Type getBaseReceivingType(Tree.InvocationExpression that, Declaration dec) {
    Scope scope = that.getScope();
    if (dec.isClassOrInterfaceMember() && !dec.isStatic() && !dec.isDefinedInScope(scope)) {
        ClassOrInterface ci = (ClassOrInterface) dec.getContainer();
        Type qualifyingType = scope.getDeclaringType(dec);
        List<Type> inferredArgs = new TypeArgumentInference(unit).getInferredTypeArgsForReference(that, dec, ci, qualifyingType);
        return ci.appliedType(null, inferredArgs);
    } else {
        return null;
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ModelUtil.getOuterClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) 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) NativeUtil.declarationScope(org.eclipse.ceylon.compiler.typechecker.util.NativeUtil.declarationScope) Scope(org.eclipse.ceylon.model.typechecker.model.Scope)

Example 12 with ClassOrInterface

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

the class ExpressionVisitor method visitIndirectInvocation.

/**
 * Typecheck an indirect invocation.
 */
private void visitIndirectInvocation(Tree.InvocationExpression that) {
    Tree.Term primary = unwrapExpressionUntilTerm(that.getPrimary());
    if (primary == null) {
        return;
    }
    Type pt = primary.getTypeModel();
    if (!isTypeUnknown(pt)) {
        if (that.getNamedArgumentList() != null) {
            that.addError("named arguments not supported for indirect invocations");
            return;
        }
        Tree.PositionalArgumentList pal = that.getPositionalArgumentList();
        if (pal == null) {
            return;
        }
        if (pt.isNothing()) {
            that.setTypeModel(unit.getNothingType());
        } else if (checkCallable(pt, primary, "invoked expression must be callable")) {
            Interface cd = unit.getCallableDeclaration();
            Type ct = pt.getSupertype(cd);
            if (ct == null) {
                primary.addError("invoked expression must be callable: type '" + pt.asString(unit) + "' involves a type function");
                return;
            }
            List<Type> typeArgs = ct.getTypeArgumentList();
            if (!typeArgs.isEmpty()) {
                that.setTypeModel(typeArgs.get(0));
            }
            // typecheck arguments using the type args of Callable
            if (typeArgs.size() >= 2) {
                Type paramTypesAsTuple = typeArgs.get(1);
                if (paramTypesAsTuple != null) {
                    TypeDeclaration pttd = paramTypesAsTuple.getDeclaration();
                    if (pttd instanceof ClassOrInterface && (pttd.isEmpty() || pttd.isTuple() || pttd.isSequence() || pttd.isSequential())) {
                        // we have a plain tuple type so we can check the
                        // arguments individually
                        checkIndirectInvocationArguments(that, paramTypesAsTuple, unit.getTupleElementTypes(paramTypesAsTuple), unit.isTupleLengthUnbounded(paramTypesAsTuple), unit.isTupleVariantAtLeastOne(paramTypesAsTuple), unit.getTupleMinimumLength(paramTypesAsTuple));
                    } else {
                        // we have something exotic, a union of tuple types
                        // or whatever, so just check the whole argument tuple
                        Type tt = getTupleType(pal.getPositionalArguments(), unit, false);
                        checkAssignable(tt, paramTypesAsTuple, pal, "argument list type must be assignable to parameter list type");
                    }
                }
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ModelUtil.getOuterClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) 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) ArrayList(java.util.ArrayList) ModelUtil.typeParametersAsArgList(org.eclipse.ceylon.model.typechecker.model.ModelUtil.typeParametersAsArgList) Collections.emptyList(java.util.Collections.emptyList) List(java.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ModelUtil.getOuterClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)

Example 13 with ClassOrInterface

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

the class ExpressionVisitor method refineMethod.

private void refineMethod(Tree.SpecifierStatement that) {
    Function refinedMethod = (Function) that.getRefined();
    Function method = (Function) that.getDeclaration();
    ClassOrInterface ci = (ClassOrInterface) method.getContainer();
    Declaration root = method.getRefinedDeclaration();
    TypeDeclaration td = (TypeDeclaration) root.getContainer();
    List<Declaration> interveningRefinements = getInterveningRefinements(method, root, ci, td);
    if (interveningRefinements.isEmpty()) {
        that.getBaseMemberExpression().addError("shortcut refinement does not exactly refine any overloaded inherited member");
    } else {
        Reference refinedProducedReference = accountForIntermediateRefinements(that, refinedMethod, method, ci, interveningRefinements);
        List<Tree.ParameterList> parameterLists;
        Tree.Term me = that.getBaseMemberExpression();
        if (me instanceof Tree.ParameterizedExpression) {
            Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) me;
            parameterLists = pe.getParameterLists();
        } else {
            parameterLists = emptyList();
        }
        List<ParameterList> refinedParamLists = refinedMethod.getParameterLists();
        List<ParameterList> methodParamLists = method.getParameterLists();
        Map<TypeParameter, Type> subs = substitutions(refinedMethod, method);
        for (int i = 0; i < refinedParamLists.size() && i < methodParamLists.size(); i++) {
            ParameterList refinedParameters = refinedParamLists.get(i);
            ParameterList parameters = methodParamLists.get(i);
            Tree.ParameterList parameterList = parameterLists.size() <= i ? null : parameterLists.get(i);
            List<Parameter> rps = refinedParameters.getParameters();
            for (int j = 0; j < rps.size(); j++) {
                Parameter refinedParameter = rps.get(j);
                Type refinedParameterType = refinedProducedReference.getTypedParameter(refinedParameter).getFullType().substitute(subs, null);
                Parameter parameter;
                if (parameterList == null || parameterList.getParameters().size() <= j) {
                    parameter = parameters.getParameters().get(j);
                    parameter.getModel().setType(refinedParameterType);
                    parameter.setSequenced(refinedParameter.isSequenced());
                } else {
                    Tree.Parameter param = parameterList.getParameters().get(j);
                    parameter = param.getParameterModel();
                    Type parameterType = parameter.getModel().getTypedReference().getFullType();
                    Node typeNode = param;
                    if (param instanceof Tree.ParameterDeclaration) {
                        Tree.ParameterDeclaration pd = (Tree.ParameterDeclaration) param;
                        Tree.Type type = pd.getTypedDeclaration().getType();
                        if (type != null) {
                            typeNode = type;
                        }
                    }
                    checkIsExactlyIgnoringNull(refinedParameters.isNamedParametersSupported(), parameterType, refinedParameterType, typeNode, "type of parameter '" + parameter.getName() + "' of '" + method.getName() + "' declared by '" + ci.getName() + "' is different to type of corresponding parameter " + message(refinedMethod, refinedParameter), 9200);
                    if (refinedParameter.isSequenced() && !parameter.isSequenced()) {
                        param.addError("parameter must be variadic: parameter " + message(refinedMethod, refinedParameter) + " is variadic");
                    }
                    if (!refinedParameter.isSequenced() && parameter.isSequenced()) {
                        param.addError("parameter may not be variadic: parameter " + message(refinedMethod, refinedParameter) + " is not variadic");
                    }
                }
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ModelUtil.getOuterClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Node(org.eclipse.ceylon.compiler.typechecker.tree.Node) Function(org.eclipse.ceylon.model.typechecker.model.Function) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) 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) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint) 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) 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.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)

Example 14 with ClassOrInterface

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

the class AnnotationVisitor method checkServiceImplementation.

private void checkServiceImplementation(Class clazz, Declaration d, Node that) {
    if (d instanceof ClassOrInterface) {
        ClassOrInterface service = (ClassOrInterface) d;
        ParameterList pl = clazz.getParameterList();
        if (pl == null) {
            that.addError("service class must have a parameter list or default constructor");
        } else {
            List<Parameter> params = pl.getParameters();
            if (!params.isEmpty() && !params.get(0).isDefaulted()) {
                that.addError("service class must be instantiable with an empty argument list");
            }
        }
        if (clazz.inherits(service)) {
            ModelUtil.getModule(clazz).addService(service, clazz);
        } else {
            that.addError("service class does not implement service '" + service + "'");
        }
    } else {
        that.addError("service must be an interface or class");
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter)

Example 15 with ClassOrInterface

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

the class ExpressionVisitor method visit.

@Override
public void visit(Tree.Super that) {
    ClassOrInterface ci = getContainingClassOrInterface(that.getScope());
    if (inExtendsClause) {
        // supertype of the outer class
        if (ci != null) {
            if (ci.isClassOrInterfaceMember()) {
                ClassOrInterface cci = (ClassOrInterface) ci.getContainer();
                that.setDeclarationModel(cci);
                that.setTypeModel(intersectionOfSupertypes(cci));
            }
        }
    } else {
        // TODO: for consistency, move these errors to SelfReferenceVisitor
        if (ci == null) {
            that.addError("'super' occurs outside any type definition");
        } else {
            that.setDeclarationModel(ci);
            that.setTypeModel(intersectionOfSupertypes(ci));
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ModelUtil.getOuterClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)

Aggregations

ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)102 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)62 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)48 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)46 Type (org.eclipse.ceylon.model.typechecker.model.Type)44 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)27 Class (org.eclipse.ceylon.model.typechecker.model.Class)24 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)23 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)23 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)20 ModelUtil.getContainingClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)19 Value (org.eclipse.ceylon.model.typechecker.model.Value)19 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)18 ArrayList (java.util.ArrayList)17 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)17 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)16 Function (org.eclipse.ceylon.model.typechecker.model.Function)14 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)13 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)12 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)12