Search in sources :

Example 31 with Reference

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

the class RefinementVisitor method refineAttribute.

private void refineAttribute(Value assignedAttribute, Tree.BaseMemberExpression bme, Tree.SpecifierStatement that, ClassOrInterface c) {
    if (!assignedAttribute.isFormal() && !assignedAttribute.isDefault() && !assignedAttribute.isShortcutRefinement()) {
        // this condition is here to squash a dupe message
        that.addError("inherited attribute may not be assigned in initializer and may not be refined: " + message(assignedAttribute) + " is declared neither 'formal' nor 'default'", 510);
    // return;
    } else if (assignedAttribute.isVariable()) {
        that.addError("inherited attribute may not be assigned in initializer and may not be refined by non-variable: " + message(assignedAttribute) + " is declared 'variable'");
    // return;
    }
    ClassOrInterface ci = (ClassOrInterface) assignedAttribute.getContainer();
    String name = assignedAttribute.getName();
    Declaration refined = ci.getRefinedMember(name, null, false);
    Value root = refined instanceof Value ? (Value) refined : assignedAttribute;
    Reference rv = getRefinedMemberReference(assignedAttribute, c);
    boolean lazy = that.getSpecifierExpression() instanceof Tree.LazySpecifierExpression;
    Value attribute = new Value();
    attribute.setName(name);
    attribute.setShared(true);
    attribute.setActual(true);
    attribute.getAnnotations().add(new Annotation("shared"));
    attribute.getAnnotations().add(new Annotation("actual"));
    attribute.setRefinedDeclaration(root);
    Unit unit = that.getUnit();
    attribute.setUnit(unit);
    attribute.setContainer(c);
    attribute.setScope(c);
    attribute.setShortcutRefinement(true);
    attribute.setTransient(lazy);
    Declaration rvd = rv.getDeclaration();
    if (rvd instanceof TypedDeclaration) {
        TypedDeclaration rvtd = (TypedDeclaration) rvd;
        attribute.setUncheckedNullType(rvtd.hasUncheckedNullType());
    }
    ModelUtil.setVisibleScope(attribute);
    c.addMember(attribute);
    that.setRefinement(true);
    that.setDeclaration(attribute);
    that.setRefined(assignedAttribute);
    unit.addDeclaration(attribute);
    setRefiningType(c, ci, name, null, false, root, attribute, unit, NO_SUBSTITUTIONS);
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) 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) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) 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) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Annotation(org.eclipse.ceylon.model.typechecker.model.Annotation)

Example 32 with Reference

use of org.eclipse.ceylon.model.typechecker.model.Reference 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 33 with Reference

use of org.eclipse.ceylon.model.typechecker.model.Reference 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 34 with Reference

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

the class TypeHierarchyVisitor method addUnimplementedFormal.

private void addUnimplementedFormal(Class clazz, Declaration member) {
    Reference unimplemented = member.appliedReference(clazz.getType(), NO_TYPE_ARGS);
    List<Reference> list = clazz.getUnimplementedFormals();
    if (list.isEmpty()) {
        list = new ArrayList<Reference>();
        clazz.setUnimplementedFormals(list);
    }
    list.add(unimplemented);
}
Also used : Reference(org.eclipse.ceylon.model.typechecker.model.Reference)

Example 35 with Reference

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

the class ClassImpl method getDeclaredConstructor.

@Override
@TypeParameters(@TypeParameter(value = "Arguments", satisfies = "ceylon.language::Sequential<ceylon.language::Anything>"))
@TypeInfo("ceylon.language.meta.model::CallableConstructor<Type,Arguments>|ceylon.language.meta.model::ValueConstructor<Type>|ceylon.language::Null")
public <Arguments extends Sequential<? extends Object>> java.lang.Object getDeclaredConstructor(@Ignore TypeDescriptor $reified$Arguments, @Name("name") String name) {
    checkInit();
    final ceylon.language.meta.declaration.Declaration ctor = ((ClassDeclarationImpl) declaration).getConstructorDeclaration(name);
    if (ctor == null)
        return null;
    if (ctor instanceof CallableConstructorDeclaration) {
        if (ctor instanceof ClassWithInitializerDeclarationConstructor) {
            TypeDescriptor actualReifiedArguments = Metamodel.getTypeDescriptorForArguments(declaration.declaration.getUnit(), (Functional) ((ClassWithInitializerDeclarationConstructor) ctor).declaration, this.producedType);
            Metamodel.checkReifiedTypeArgument("getDeclaredConstructor", "CallableConstructor<$1,$2>", // // this line is bullshit since it's always true, but otherwise we can't substitute the error message above :(
            Variance.OUT, this.producedType, $reifiedType, Variance.IN, Metamodel.getProducedType(actualReifiedArguments), $reified$Arguments);
            ClassInitializerConstructor c = new ClassInitializerConstructor<>(this);
            return c;
        }
        CallableConstructorDeclarationImpl callableCtor = (CallableConstructorDeclarationImpl) ctor;
        org.eclipse.ceylon.model.typechecker.model.Type constructorType = callableCtor.constructor.appliedType(this.producedType, Collections.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList());
        // return new AppliedConstructor<Type,Args>(this.$reifiedType, actualReifiedArguments, this, constructorType, ctor, this.instance);
        // Reference reference = ((Function)callableCtor.declaration).getReference();
        Reference reference;
        if (callableCtor.declaration instanceof Function) {
            reference = ((Function) callableCtor.declaration).appliedTypedReference(producedType, null);
        } else if (callableCtor.declaration instanceof org.eclipse.ceylon.model.typechecker.model.Class) {
            reference = ((org.eclipse.ceylon.model.typechecker.model.Class) callableCtor.declaration).appliedReference(producedType, null);
        } else if (callableCtor.declaration instanceof org.eclipse.ceylon.model.typechecker.model.Constructor) {
            reference = ((org.eclipse.ceylon.model.typechecker.model.Constructor) callableCtor.declaration).appliedReference(producedType, null);
        } else {
            throw Metamodel.newModelError("Unexpect declaration " + callableCtor.declaration);
        }
        // anonymous classes don't have parameter lists
        TypeDescriptor actualReifiedArguments = Metamodel.getTypeDescriptorForArguments(declaration.declaration.getUnit(), (Functional) callableCtor.declaration, reference);
        // This is all very ugly but we're trying to make it cheaper and friendlier than just checking the full type and showing
        // implementation types to the user, such as AppliedMemberClass
        Metamodel.checkReifiedTypeArgument("getConstructor", "Constructor<$1,$2>", // this line is bullshit since it's always true, but otherwise we can't substitute the error message above :(
        Variance.OUT, this.producedType, $reifiedType, Variance.IN, Metamodel.getProducedType(actualReifiedArguments), $reified$Arguments);
        CallableConstructorImpl<Type, Sequential<? extends Object>> appliedConstructor = new CallableConstructorImpl<Type, Sequential<? extends java.lang.Object>>(this.$reifiedType, $reified$Arguments, reference, callableCtor, this, instance);
        Metamodel.checkReifiedTypeArgument("apply", "CallableConstructor<$1,$2>", Variance.OUT, producedType, $reifiedType, Variance.IN, Metamodel.getProducedTypeForArguments(declaration.declaration.getUnit(), (Functional) callableCtor.declaration, reference), $reified$Arguments);
        return appliedConstructor;
    } else if (ctor instanceof ValueConstructorDeclaration) {
        ValueConstructorDeclarationImpl callableCtor = (ValueConstructorDeclarationImpl) ctor;
        org.eclipse.ceylon.model.typechecker.model.Type constructorType = callableCtor.constructor.appliedType(this.producedType, Collections.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList());
        TypedDeclaration val = (TypedDeclaration) callableCtor.constructor.getContainer().getDirectMember(callableCtor.constructor.getName(), null, false);
        return new ValueConstructorImpl<Type>(this.$reifiedType, callableCtor, val.getTypedReference(), this, instance);
    } else {
        throw new AssertionError("Constructor neither CallableConstructorDeclaration nor ValueConstructorDeclaration");
    }
}
Also used : CallableConstructorDeclarationImpl(org.eclipse.ceylon.compiler.java.runtime.metamodel.decl.CallableConstructorDeclarationImpl) ValueConstructorDeclaration(ceylon.language.meta.declaration.ValueConstructorDeclaration) Function(org.eclipse.ceylon.model.typechecker.model.Function) Sequential(ceylon.language.Sequential) ClassWithInitializerDeclarationConstructor(org.eclipse.ceylon.compiler.java.runtime.metamodel.decl.ClassWithInitializerDeclarationConstructor) AssertionError(ceylon.language.AssertionError) ClassDeclarationImpl(org.eclipse.ceylon.compiler.java.runtime.metamodel.decl.ClassDeclarationImpl) CallableConstructorImpl(org.eclipse.ceylon.compiler.java.runtime.metamodel.meta.CallableConstructorImpl) Metamodel(org.eclipse.ceylon.compiler.java.runtime.metamodel.Metamodel) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) CallableConstructorDeclaration(ceylon.language.meta.declaration.CallableConstructorDeclaration) ClassInitializerConstructor(org.eclipse.ceylon.compiler.java.runtime.metamodel.meta.ClassInitializerConstructor) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) CallableConstructor(ceylon.language.meta.model.CallableConstructor) ValueConstructor(ceylon.language.meta.model.ValueConstructor) ClassWithInitializerDeclarationConstructor(org.eclipse.ceylon.compiler.java.runtime.metamodel.decl.ClassWithInitializerDeclarationConstructor) ClassInitializerConstructor(org.eclipse.ceylon.compiler.java.runtime.metamodel.meta.ClassInitializerConstructor) Class(org.eclipse.ceylon.model.typechecker.model.Class) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) TypeDescriptor(org.eclipse.ceylon.compiler.java.runtime.model.TypeDescriptor) ValueConstructorDeclarationImpl(org.eclipse.ceylon.compiler.java.runtime.metamodel.decl.ValueConstructorDeclarationImpl) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeParameters(org.eclipse.ceylon.compiler.java.metadata.TypeParameters) TypeInfo(org.eclipse.ceylon.compiler.java.metadata.TypeInfo)

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