Search in sources :

Example 71 with ClassOrInterface

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

the class TestModuleManager method compareLanguageModules.

@Test
public void compareLanguageModules() {
    Assert.assertNotNull("langmod from source", srcmod);
    Assert.assertNotNull("langmod from js", jsmod);
    Assert.assertNotNull("clpack from source", srclang);
    Assert.assertNotNull("clpack from js", jslang);
    Assert.assertEquals(srclang.getMembers().size(), jslang.getMembers().size());
    for (Declaration d0 : srclang.getMembers()) {
        Declaration d1 = findMatchingDeclaration(d0, jslang.getMembers());
        Assert.assertNotNull(d0.getName() + " not found in js", d1);
        if (d0 instanceof ClassOrInterface && d1 instanceof Value) {
            d1 = ((Value) d1).getTypeDeclaration();
        }
        Assert.assertEquals(d0 + " wrong class!", d0.getClass(), d1.getClass());
        Assert.assertEquals(d0 + " wrong kind " + d1, d0.getDeclarationKind(), d1.getDeclarationKind());
        compareMembers(d0, d1);
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Test(org.junit.Test)

Example 72 with ClassOrInterface

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

the class MethodDefinitionBuilder method getFirstRefinedDeclaration.

private Declaration getFirstRefinedDeclaration(TypedDeclaration member) {
    if (!member.isActual() || Decl.equal(member, member.getRefinedDeclaration()))
        return null;
    // Taken pretty much straight from RefinementVisitor
    ClassOrInterface type = (ClassOrInterface) member.getContainer();
    java.util.List<Type> signature = ModelUtil.getSignature(member);
    boolean variadic = ModelUtil.isVariadic(member);
    Declaration root = type.getRefinedMember(name, signature, variadic);
    if (root == null)
        return null;
    TypeDeclaration rootType = (TypeDeclaration) root.getContainer();
    java.util.List<Declaration> interveningRefinements = getInterveningRefinements(member, root, type, rootType);
    for (Declaration refined : interveningRefinements) {
        TypeDeclaration interveningType = (TypeDeclaration) refined.getContainer();
        if (getInterveningRefinements(member, root, type, interveningType).size() > 1) {
            continue;
        }
        // first?
        return refined;
    }
    return null;
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Type(org.eclipse.ceylon.model.typechecker.model.Type) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 73 with ClassOrInterface

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

the class AbstractModelLoader method getLocalContainer.

private Scope getLocalContainer(Package pkg, ClassMirror classMirror, Declaration declaration) {
    AnnotationMirror localContainerAnnotation = classMirror.getAnnotation(CEYLON_LOCAL_CONTAINER_ANNOTATION);
    String qualifier = getAnnotationStringValue(classMirror, CEYLON_LOCAL_DECLARATION_ANNOTATION, "qualifier");
    // deal with types local to functions in the body of toplevel non-lazy attributes, whose container is ultimately the package
    Boolean isPackageLocal = getAnnotationBooleanValue(classMirror, CEYLON_LOCAL_DECLARATION_ANNOTATION, "isPackageLocal");
    if (BooleanUtil.isTrue(isPackageLocal)) {
        // make sure it still knows it's a local
        declaration.setQualifier(qualifier);
        return null;
    }
    LocalDeclarationContainer methodDecl = null;
    // we get a @LocalContainer annotation for local interfaces
    if (localContainerAnnotation != null) {
        methodDecl = (LocalDeclarationContainer) findLocalContainerFromAnnotationAndSetCompanionClass(pkg, (Interface) declaration, localContainerAnnotation);
    } else {
        // all the other cases stay where they belong
        MethodMirror method = classMirror.getEnclosingMethod();
        if (method == null)
            return null;
        // see where that method belongs
        ClassMirror enclosingClass = method.getEnclosingClass();
        while (enclosingClass.isAnonymous()) {
            // this gives us the method in which the anonymous class is, which should be the one we're looking for
            method = enclosingClass.getEnclosingMethod();
            if (method == null)
                return null;
            // and the method's containing class
            enclosingClass = method.getEnclosingClass();
        }
        // if we are in a setter class, the attribute is declared in the getter class, so look for its declaration there
        TypeMirror getterClass = (TypeMirror) getAnnotationValue(enclosingClass, CEYLON_SETTER_ANNOTATION, "getterClass");
        boolean isSetter = false;
        // we use void.class as default value
        if (getterClass != null && !getterClass.isPrimitive()) {
            enclosingClass = getterClass.getDeclaredClass();
            isSetter = true;
        }
        String javaClassName = enclosingClass.getQualifiedName();
        // make sure we don't go looking in companion classes
        if (javaClassName.endsWith(NamingBase.Suffix.$impl.name()))
            javaClassName = javaClassName.substring(0, javaClassName.length() - 5);
        // find the enclosing declaration
        Declaration enclosingClassDeclaration = convertToDeclaration(pkg.getModule(), javaClassName, DeclarationType.TYPE);
        if (enclosingClassDeclaration instanceof ClassOrInterface) {
            ClassOrInterface containerDecl = (ClassOrInterface) enclosingClassDeclaration;
            // now find the method's declaration
            // FIXME: find the proper overload if any
            String name = method.getName();
            if (method.isConstructor() || name.startsWith(NamingBase.Prefix.$default$.toString())) {
                methodDecl = (LocalDeclarationContainer) containerDecl;
            } else {
                // this is only for error messages
                String type;
                // lots of special cases
                if (isStringAttribute(method)) {
                    name = "string";
                    type = "attribute";
                } else if (isHashAttribute(method)) {
                    name = "hash";
                    type = "attribute";
                } else if (isGetter(method)) {
                    // simple attribute
                    name = getJavaAttributeName(method);
                    type = "attribute";
                } else if (isSetter(method)) {
                    // simple attribute
                    name = getJavaAttributeName(method);
                    type = "attribute setter";
                    isSetter = true;
                } else {
                    type = "method";
                }
                // it can be foo$priv$canonical so get rid of that one first
                if (name.endsWith(NamingBase.Suffix.$canonical$.toString())) {
                    name = name.substring(0, name.length() - 11);
                }
                name = JvmBackendUtil.strip(name, true, method.isPublic() || method.isProtected() || method.isDefaultAccess());
                if (name.indexOf('$') > 0) {
                    // may be a default parameter expression? get the method name which is first
                    name = name.substring(0, name.indexOf('$'));
                }
                methodDecl = (LocalDeclarationContainer) containerDecl.getDirectMember(name, null, false);
                if (methodDecl == null)
                    throw new ModelResolutionException("Failed to load outer " + type + " " + name + " for local type " + classMirror.getQualifiedName().toString());
                // if it's a setter we wanted, let's get it
                if (isSetter) {
                    LocalDeclarationContainer setter = (LocalDeclarationContainer) ((Value) methodDecl).getSetter();
                    if (setter == null)
                        throw new ModelResolutionException("Failed to load outer " + type + " " + name + " for local type " + classMirror.getQualifiedName().toString());
                    methodDecl = setter;
                }
            }
        } else if (enclosingClassDeclaration instanceof LazyFunction) {
            // local and toplevel methods
            methodDecl = (LazyFunction) enclosingClassDeclaration;
        } else if (enclosingClassDeclaration instanceof LazyValue) {
            // local and toplevel attributes
            if (enclosingClassDeclaration.isToplevel() && method.getName().equals(NamingBase.Unfix.set_.name()))
                isSetter = true;
            if (isSetter) {
                LocalDeclarationContainer setter = (LocalDeclarationContainer) ((LazyValue) enclosingClassDeclaration).getSetter();
                if (setter == null)
                    throw new ModelResolutionException("Failed to toplevel attribute setter " + enclosingClassDeclaration.getName() + " for local type " + classMirror.getQualifiedName().toString());
                methodDecl = setter;
            } else
                methodDecl = (LazyValue) enclosingClassDeclaration;
        } else {
            throw new ModelResolutionException("Unknown container type " + enclosingClassDeclaration + " for local type " + classMirror.getQualifiedName().toString());
        }
    }
    // we have the method, now find the proper local qualifier if any
    if (qualifier == null)
        return null;
    declaration.setQualifier(qualifier);
    methodDecl.addLocalDeclaration(declaration);
    return methodDecl;
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyValue(org.eclipse.ceylon.model.loader.model.LazyValue) LocalDeclarationContainer(org.eclipse.ceylon.model.loader.model.LocalDeclarationContainer) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction) ClassMirror(org.eclipse.ceylon.model.loader.mirror.ClassMirror) AnnotationMirror(org.eclipse.ceylon.model.loader.mirror.AnnotationMirror) MethodMirror(org.eclipse.ceylon.model.loader.mirror.MethodMirror) TypeMirror(org.eclipse.ceylon.model.loader.mirror.TypeMirror) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 74 with ClassOrInterface

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

the class AbstractModelLoader method setContainer.

private void setContainer(ClassMirror classMirror, Declaration d, LazyPackage pkg) {
    // add it to its package if it's not an inner class
    if (!classMirror.isInnerClass() && !classMirror.isLocalClass()) {
        d.setContainer(pkg);
        d.setScope(pkg);
        pkg.addCompiledMember(d);
        if (d instanceof LazyInterface && ((LazyInterface) d).isCeylon()) {
            setInterfaceCompanionClass(d, null, pkg);
        }
        ModelUtil.setVisibleScope(d);
    } else if (classMirror.isLocalClass() && !classMirror.isInnerClass()) {
        // set its container to the package for now, but don't add it to the package as a member because it's not
        Scope localContainer = getLocalContainer(pkg, classMirror, d);
        if (localContainer != null) {
            d.setContainer(localContainer);
            d.setScope(localContainer);
        // do not add it as member, it has already been registered by getLocalContainer
        } else {
            d.setContainer(pkg);
            d.setScope(pkg);
        }
        ((LazyElement) d).setLocal(true);
    } else if (d instanceof ClassOrInterface || d instanceof TypeAlias) {
        // we have to set that one first
        if (d instanceof Class == false || !((Class) d).isOverloaded()) {
            ClassOrInterface container = getContainer(pkg.getModule(), classMirror);
            if (d.isNativeHeader() && container.isNative()) {
                container = (ClassOrInterface) ModelUtil.getNativeHeader(container);
            } else if (d.isNativeImplementation() && // for every Java declaration, who don't have native headers
            container.isNativeHeader()) {
                container = (ClassOrInterface) ModelUtil.getNativeDeclaration(container, Backend.Java);
            }
            d.setContainer(container);
            d.setScope(container);
            if (d instanceof LazyInterface && ((LazyInterface) d).isCeylon()) {
                setInterfaceCompanionClass(d, container, pkg);
            }
            // let's not trigger lazy-loading
            ((LazyContainer) container).addMember(d);
            ModelUtil.setVisibleScope(d);
            // now we can do overloads
            if (d instanceof Class && ((Class) d).getOverloads() != null) {
                for (Declaration overload : ((Class) d).getOverloads()) {
                    overload.setContainer(container);
                    overload.setScope(container);
                    // let's not trigger lazy-loading
                    ((LazyContainer) container).addMember(overload);
                    ModelUtil.setVisibleScope(overload);
                }
            }
            // Adds extra members for annotation interop.
            if (d instanceof LazyInterface && !((LazyInterface) d).isCeylon() && ((LazyInterface) d).isAnnotationType()) {
                for (Declaration decl : makeInteropAnnotation((LazyInterface) d, container)) {
                    container.addMember(decl);
                }
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyContainer(org.eclipse.ceylon.model.loader.model.LazyContainer) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) LazyTypeAlias(org.eclipse.ceylon.model.loader.model.LazyTypeAlias) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) AnnotationProxyClass(org.eclipse.ceylon.model.loader.model.AnnotationProxyClass) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 75 with ClassOrInterface

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

the class AbstractModelLoader method setExtendedType.

private void setExtendedType(ClassOrInterface klass, ClassMirror classMirror) {
    // look at its super type
    TypeMirror superClass = classMirror.getSuperclass();
    Type extendedType;
    if (klass instanceof Interface) {
        // interfaces need to have their superclass set to Object
        if (superClass == null || superClass.getKind() == TypeKind.NONE)
            extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_OBJECT_TYPE, klass);
        else
            extendedType = getNonPrimitiveType(ModelUtil.getModule(klass), superClass, klass);
    } else if (klass instanceof Class && ((Class) klass).isOverloaded()) {
        // if the class is overloaded we already have it stored
        extendedType = klass.getExtendedType();
    } else {
        String className = classMirror.getQualifiedName();
        String superClassName = superClass == null ? null : superClass.getQualifiedName();
        if (className.equals("ceylon.language.Anything")) {
            // ceylon.language.Anything has no super type
            extendedType = null;
        } else if (className.equals("java.lang.Object")) {
            // we pretend its superclass is something else, but note that in theory we shouldn't
            // be seeing j.l.Object at all due to unerasure
            extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_BASIC_TYPE, klass);
        } else {
            // read it from annotation first
            String annotationSuperClassName = getAnnotationStringValue(classMirror, CEYLON_CLASS_ANNOTATION, "extendsType");
            if (annotationSuperClassName != null && !annotationSuperClassName.isEmpty()) {
                extendedType = decodeType(annotationSuperClassName, klass, ModelUtil.getModuleContainer(klass), "extended type");
            } else {
                // now deal with type erasure, avoid having Object as superclass
                if ("java.lang.Object".equals(superClassName)) {
                    extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_BASIC_TYPE, klass);
                } else if (superClass != null) {
                    try {
                        extendedType = getNonPrimitiveType(ModelUtil.getModule(klass), superClass, klass);
                    } catch (ModelResolutionException x) {
                        extendedType = logModelResolutionException(x, klass, "Error while resolving extended type of " + klass.getQualifiedNameString());
                    }
                } else {
                    // FIXME: should this be UnknownType?
                    extendedType = null;
                }
            }
        }
    }
    if (extendedType != null)
        klass.setExtendedType(extendedType);
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) TypeMirror(org.eclipse.ceylon.model.loader.mirror.TypeMirror) AnnotationProxyClass(org.eclipse.ceylon.model.loader.model.AnnotationProxyClass) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

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