Search in sources :

Example 61 with Scope

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

the class TypeVisitor method visit.

/*@Override 
    public void visit(Tree.TypeConstraint that) {
        super.visit(that);
        if (that.getSelfType()!=null) {
            TypeDeclaration td = (TypeDeclaration) that.getSelfType().getScope();
            TypeParameter tp = that.getDeclarationModel();
            td.setSelfType(tp.getType());
            if (tp.isSelfType()) {
                that.addError("type parameter may not act as self type for two different types");
            }
            else {
                tp.setSelfTypedDeclaration(td);
            }
        }
    }*/
@Override
public void visit(Tree.CaseTypes that) {
    super.visit(that);
    TypeDeclaration td = (TypeDeclaration) that.getScope();
    List<Tree.StaticMemberOrTypeExpression> bmes = that.getBaseMemberExpressions();
    List<Tree.StaticType> cts = that.getTypes();
    List<TypedDeclaration> caseValues = new ArrayList<TypedDeclaration>(bmes.size());
    List<Type> caseTypes = new ArrayList<Type>(bmes.size() + cts.size());
    if (td instanceof TypeParameter) {
        if (!bmes.isEmpty()) {
            that.addError("cases of type parameter must be a types");
        }
    } else {
        for (Tree.StaticMemberOrTypeExpression bme : bmes) {
            // bmes have not yet been resolved
            String name = name(bme.getIdentifier());
            TypedDeclaration od = bme instanceof Tree.BaseMemberExpression ? getTypedDeclaration(bme.getScope(), name, null, false, unit) : getPackageTypedDeclaration(name, null, false, unit);
            if (od != null) {
                caseValues.add(od);
                Type type = od.getType();
                if (type != null) {
                    caseTypes.add(type);
                }
            }
        }
    }
    for (Tree.StaticType ct : cts) {
        inheritedType(ct);
        Type type = ct.getTypeModel();
        if (!isTypeUnknown(type)) {
            if (type.isUnion() || type.isIntersection() || type.isNothing()) {
                // union/intersection types don't have equals()
                if (td instanceof TypeParameter) {
                    ct.addError("enumerated bound must be a class or interface type");
                } else {
                    ct.addError("case type must be a class, interface, or self type");
                }
            } else {
                TypeDeclaration ctd = type.getDeclaration();
                if (ctd.equals(td)) {
                    ct.addError("directly enumerates itself: '" + td.getName() + "'");
                } else if (type.isClassOrInterface()) {
                    caseTypes.add(type);
                } else if (type.isTypeParameter()) {
                    if (td instanceof TypeParameter) {
                        caseTypes.add(type);
                    } else {
                        TypeParameter tp = (TypeParameter) ctd;
                        td.setSelfType(type);
                        if (tp.isSelfType()) {
                            ct.addError("type parameter may not act as self type for two different types");
                        } else {
                            tp.setSelfTypedDeclaration(td);
                            caseTypes.add(type);
                        }
                        if (cts.size() > 1) {
                            ct.addError("a type may not have more than one self type");
                        }
                    }
                } else {
                    if (td instanceof TypeParameter) {
                        ct.addError("enumerated bound must be a class or interface type");
                    } else {
                        ct.addError("case type must be a class, interface, or self type");
                    }
                }
            }
        }
    }
    if (!caseTypes.isEmpty()) {
        TypeDeclaration first = caseTypes.get(0).getDeclaration();
        if (caseTypes.size() == 1 && first.isSelfType()) {
            // for a type family, the type that declares
            // the type parameter may not be the same
            // type for which it acts as a self type
            Scope scope = first.getContainer();
            if (scope instanceof ClassOrInterface) {
                ClassOrInterface ci = (ClassOrInterface) scope;
                if (!ci.isAbstract()) {
                    Tree.StaticType ct = cts.get(0);
                    if (ci.equals(td)) {
                        ct.addError("concrete class parameterized by self type: '" + ci.getName() + "' is not abstract but has the self type '" + first.getName() + "' (make '" + ci.getName() + "' abstract)", 905);
                    } else {
                        // type family
                        ct.addError("concrete class parameterized by self type: '" + ci.getName() + "' is not abstract but declares the self type '" + first.getName() + "' of '" + td.getName() + "' (make '" + ci.getName() + "' abstract)", 905);
                    }
                }
            }
        } else {
            if (td instanceof ClassOrInterface) {
                ClassOrInterface ci = (ClassOrInterface) td;
                if (!ci.isAbstract()) {
                    Class c = (Class) ci;
                    if (!c.hasEnumerated()) {
                        that.addError("concrete class has enumerated subtypes: " + "enumerated class '" + ci.getName() + "' is not abstract" + " (make '" + ci.getName() + "' abstract)", 905);
                    }
                }
            }
        }
        td.setCaseTypes(caseTypes);
        td.setCaseValues(caseValues);
    }
}
Also used : AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ArrayList(java.util.ArrayList) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) 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) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.isVeryAbstractClass(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.isVeryAbstractClass) 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 62 with Scope

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

the class TypeVisitor method visit.

@Override
public void visit(Tree.QualifiedType that) {
    boolean onl = inTypeLiteral;
    boolean oiea = inExtendsOrClassAlias;
    boolean oidc = inDelegatedConstructor;
    inTypeLiteral = false;
    inExtendsOrClassAlias = false;
    inDelegatedConstructor = false;
    super.visit(that);
    inExtendsOrClassAlias = oiea;
    inDelegatedConstructor = oidc;
    inTypeLiteral = onl;
    Tree.StaticType ot = that.getOuterType();
    Type pt = ot.getTypeModel();
    if (pt != null) {
        // if (pt.isTypeConstructor()) {
        // ot.addError("qualifying type may not be a type constructor");
        // }
        Tree.TypeArgumentList tal = that.getTypeArgumentList();
        if (that.getMetamodel() && tal != null && isTypeUnknown(pt) && !pt.isUnknown()) {
            tal.addError("qualifying type does not fully-specify type arguments");
        }
        TypeDeclaration d = pt.getDeclaration();
        Tree.Identifier id = that.getIdentifier();
        if (id != null) {
            String name = name(id);
            Scope scope = that.getScope();
            TypeDeclaration type = getTypeMember(d, name, null, false, unit, scope);
            if (type == null) {
                if (!isNativeForWrongBackend(scope, unit)) {
                    if (d.isMemberAmbiguous(name, unit, null, false)) {
                        that.addError("member type declaration is ambiguous: '" + name + "' for type '" + d.getName() + "'");
                    } else {
                        that.addError("member type is not defined: '" + name + "' in type '" + d.getName() + "'" + memberCorrectionMessage(name, d, null, unit, cancellable), 100);
                        unit.setUnresolvedReferences();
                    }
                }
            } else {
                visitSimpleType(that, pt, type);
                if (type.isStatic()) {
                    ot.setStaticTypePrimary(true);
                }
            }
        }
    }
}
Also used : NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) 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) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) 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 63 with Scope

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

the class ExpressionVisitor method handleNativeHeader.

private Declaration handleNativeHeader(Declaration dec, Node that, boolean error) {
    // really nasty workaround to get the "real" scope
    // in which an annotation occurs! (bug #7143)
    Scope scope = (that instanceof Tree.BaseMemberExpression ? ((Tree.BaseMemberExpression) that).getIdentifier() : that).getScope();
    Declaration impl = dec;
    Declaration hdr = null;
    Module ctxModule = unit.getPackage().getModule();
    Module decModule = dec.getUnit().getPackage().getModule();
    Backends decModuleBackends = getModuleBackends(decModule, unit);
    Backends inBackends = scope.getScopedBackends();
    if (dec.isNative()) {
        Backends backends = inBackends.none() ? unit.getSupportedBackends() : inBackends;
        if (dec.isNativeHeader()) {
            hdr = dec;
            impl = getNativeDeclaration(hdr, backends);
        } else {
            Declaration tmp = getNativeHeader(dec);
            if (tmp != dec) {
                hdr = tmp;
                if (hdr != null) {
                    if (backends.none() || !backends.supports(dec.getNativeBackends())) {
                        impl = getNativeDeclaration(hdr, backends);
                    }
                }
            }
        }
    }
    if (error && impl != null && (dec.isToplevel() || dec.isMember()) && declarationScope(scope) != null && (hdr == null || !isImplemented(hdr)) && (ctxModule != decModule && !decModuleBackends.none() || ctxModule == decModule && dec.isNative() && hdr == null) && (inBackends.none() || impl.isNative() && !isForBackend(impl.getNativeBackends(), inBackends) || !decModuleBackends.none() && !isForBackend(decModuleBackends, inBackends))) {
        Declaration d = declarationScope(scope);
        if (!inBackends.none()) {
            that.addError("illegal reference to native declaration '" + dec.getName(unit) + "': native declaration '" + d.getName(unit) + "' has a different backend");
        } else {
            that.addError("illegal reference to native declaration '" + dec.getName(unit) + "': declaration '" + d.getName(unit) + "' is not native (mark it or the module native)", 20010);
        }
    }
    if (dec.isNative()) {
        return inBackends.none() || impl == null ? dec : impl;
    }
    return dec;
}
Also used : NativeUtil.getBackends(org.eclipse.ceylon.compiler.typechecker.util.NativeUtil.getBackends) Backends(org.eclipse.ceylon.common.Backends) NativeUtil.declarationScope(org.eclipse.ceylon.compiler.typechecker.util.NativeUtil.declarationScope) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) 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) Module(org.eclipse.ceylon.model.typechecker.model.Module) AnalyzerUtil.importedModule(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.importedModule)

Example 64 with Scope

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

the class ValueDeclarationImpl method $getJavaAnnotations$.

@Override
@Ignore
public java.lang.annotation.Annotation[] $getJavaAnnotations$() {
    Class<?> javaClass = Metamodel.getJavaClass(declaration);
    ArrayList<java.lang.annotation.Annotation> result = new ArrayList<>();
    HashSet<Class<? extends java.lang.annotation.Annotation>> cls = new HashSet<>();
    if (javaClass != null) {
        // FIXME: pretty sure this doesn't work with interop and fields
        Method declaredGetter = Reflection.getDeclaredGetter(javaClass, NamingBase.getGetterName(declaration));
        if (declaredGetter != null) {
            addToList(result, cls, declaredGetter.getAnnotations());
        }
        if (!((Value) declaration).isTransient()) {
            // TODO only include those which are java annotations
            Field field = Reflection.getDeclaredField(javaClass, declaration.getName());
            if (field != null) {
                Annotation[] fieldAnnos = field.getAnnotations();
                addToList(result, cls, fieldAnnos);
            }
            Method setter = Reflection.getDeclaredSetter(javaClass, NamingBase.getSetterName(declaration.getName()));
            if (setter != null) {
                Annotation[] setterAnnos = setter.getAnnotations();
                addToList(result, cls, setterAnnos);
            }
        }
    }
    // one last chance
    if (parameter != null && !parameter.getModel().isShared()) {
        // get the annotations from the parameter itself
        Annotation[][] parameterAnnotations;
        Scope container = parameter.getModel().getContainer();
        if (container instanceof org.eclipse.ceylon.model.typechecker.model.Function) {
            parameterAnnotations = Metamodel.getJavaMethod((org.eclipse.ceylon.model.typechecker.model.Function) container).getParameterAnnotations();
        } else if (container instanceof org.eclipse.ceylon.model.typechecker.model.ClassAlias) {
            parameterAnnotations = Reflection.findClassAliasInstantiator(Metamodel.getJavaClass((org.eclipse.ceylon.model.typechecker.model.Class) container), (org.eclipse.ceylon.model.typechecker.model.ClassAlias) container).getParameterAnnotations();
        } else if (container instanceof org.eclipse.ceylon.model.typechecker.model.Class) {
            // FIXME: pretty sure that's wrong because of synthetic params. See ReflectionMethod.getParameters
            parameterAnnotations = Reflection.findConstructor(Metamodel.getJavaClass((org.eclipse.ceylon.model.typechecker.model.Class) container)).getParameterAnnotations();
        } else {
            throw Metamodel.newModelError("Unsupported parameter container");
        }
        // now find the right parameter
        List<Parameter> parameters = ((org.eclipse.ceylon.model.typechecker.model.Functional) container).getFirstParameterList().getParameters();
        int index = parameters.indexOf(parameter);
        if (index == -1)
            throw Metamodel.newModelError("Parameter " + parameter + " not found in container " + parameter.getModel().getContainer());
        if (index >= parameterAnnotations.length)
            throw Metamodel.newModelError("Parameter " + parameter + " index is greater than JVM parameters for " + parameter.getModel().getContainer());
        addToList(result, cls, parameterAnnotations[index]);
    }
    // nope
    return result.toArray(new java.lang.annotation.Annotation[result.size()]);
}
Also used : ArrayList(java.util.ArrayList) Field(java.lang.reflect.Field) Metamodel(org.eclipse.ceylon.compiler.java.runtime.metamodel.Metamodel) HashSet(java.util.HashSet) Method(java.lang.reflect.Method) Annotation(java.lang.annotation.Annotation) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.compiler.java.metadata.TypeParameter) Ignore(org.eclipse.ceylon.compiler.java.metadata.Ignore)

Example 65 with Scope

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

the class Metamodel method getMetamodel.

public static ceylon.language.meta.declaration.FunctionDeclaration getMetamodel(Function method) {
    // find its container
    Scope container = method.getContainer();
    if (container instanceof org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) {
        org.eclipse.ceylon.compiler.java.runtime.metamodel.decl.ClassOrInterfaceDeclarationImpl classOrInterface = (ClassOrInterfaceDeclarationImpl) getOrCreateMetamodel((org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) container);
        // now find the method
        ceylon.language.meta.declaration.FunctionDeclaration ret = classOrInterface.findMethod(method.getName());
        if (ret == null)
            throw Metamodel.newModelError("Failed to find method " + method.getName() + " in " + container);
        return ret;
    }
    if (container instanceof org.eclipse.ceylon.model.typechecker.model.Package) {
        ceylon.language.meta.declaration.Package pkg = getOrCreateMetamodel((org.eclipse.ceylon.model.typechecker.model.Package) container);
        ceylon.language.meta.declaration.FunctionDeclaration ret = pkg.getFunction(method.getName());
        if (ret == null)
            throw Metamodel.newModelError("Failed to find method " + method.getName() + " in " + container);
        return ret;
    }
    throw Metamodel.newModelError("Unsupported method container for " + method.getName() + ": " + container);
}
Also used : ClassOrInterface(ceylon.language.meta.model.ClassOrInterface) ClassOrInterfaceDeclarationImpl(org.eclipse.ceylon.compiler.java.runtime.metamodel.decl.ClassOrInterfaceDeclarationImpl) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ClassOrInterfaceDeclarationImpl(org.eclipse.ceylon.compiler.java.runtime.metamodel.decl.ClassOrInterfaceDeclarationImpl) Metamodel(org.eclipse.ceylon.compiler.java.runtime.metamodel.Metamodel) LazyPackage(org.eclipse.ceylon.model.loader.model.LazyPackage) Package(ceylon.language.meta.declaration.Package) Package(ceylon.language.meta.declaration.Package)

Aggregations

Scope (org.eclipse.ceylon.model.typechecker.model.Scope)142 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)71 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)57 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)50 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)44 Type (org.eclipse.ceylon.model.typechecker.model.Type)44 ConditionScope (org.eclipse.ceylon.model.typechecker.model.ConditionScope)35 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)34 Class (org.eclipse.ceylon.model.typechecker.model.Class)33 ModelUtil.getRealScope (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope)31 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)30 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)26 Value (org.eclipse.ceylon.model.typechecker.model.Value)26 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)25 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)24 Function (org.eclipse.ceylon.model.typechecker.model.Function)23 Package (org.eclipse.ceylon.model.typechecker.model.Package)22 ArrayList (java.util.ArrayList)21 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)20 NativeUtil.declarationScope (org.eclipse.ceylon.compiler.typechecker.util.NativeUtil.declarationScope)15