Search in sources :

Example 6 with MethodMirror

use of org.eclipse.ceylon.model.loader.mirror.MethodMirror in project ceylon by eclipse.

the class AbstractModelLoader method getGetterMethodMirror.

private MethodMirror getGetterMethodMirror(Declaration value, ClassMirror classMirror, boolean toplevel) {
    MethodMirror meth = null;
    String getterName;
    if (toplevel) {
        // We do this to prevent calling complete() unnecessarily
        getterName = NamingBase.Unfix.get_.name();
    } else {
        getterName = NamingBase.getGetterName(value);
    }
    for (MethodMirror m : classMirror.getDirectMethods()) {
        // Do not skip members marked with @Ignore, because the getter is supposed to be ignored
        if (m.getName().equals(getterName) && (!toplevel || m.isStatic()) && m.getParameters().size() == 0) {
            meth = m;
            break;
        }
    }
    return meth;
}
Also used : MethodMirror(org.eclipse.ceylon.model.loader.mirror.MethodMirror)

Example 7 with MethodMirror

use of org.eclipse.ceylon.model.loader.mirror.MethodMirror in project ceylon by eclipse.

the class AbstractModelLoader method getClassConstructors.

private List<MethodMirror> getClassConstructors(ClassMirror instantiatedType, ClassMirror methodContainer, MethodMirrorFilter p) {
    LinkedList<MethodMirror> constructors = new LinkedList<MethodMirror>();
    boolean isFromJDK = isFromJDK(methodContainer);
    for (MethodMirror methodMirror : methodContainer.getDirectMethods()) {
        // We skip members marked with @Ignore, unless they value constructor getters
        if (methodMirror.getAnnotation(CEYLON_IGNORE_ANNOTATION) != null && methodMirror.getAnnotation(CEYLON_ENUMERATED_ANNOTATION) == null)
            continue;
        if (!p.accept(methodMirror))
            continue;
        // FIXME: tmp hack to skip constructors that have type params as we don't handle them yet
        if (!methodMirror.getTypeParameters().isEmpty())
            continue;
        // referenced in private methods but not available
        if (isFromJDK && !methodMirror.isPublic() && // classes in the jdk packages
        !methodMirror.isProtected())
            continue;
        // if we are expecting Ceylon code, check that we have enough reified type parameters
        if (methodContainer.getAnnotation(CEYLON_CEYLON_ANNOTATION) != null) {
            List<AnnotationMirror> tpAnnotations = getTypeParametersFromAnnotations(instantiatedType);
            int tpCount = tpAnnotations != null ? tpAnnotations.size() : instantiatedType.getTypeParameters().size();
            if (!checkReifiedTypeDescriptors(tpCount, instantiatedType.getQualifiedName(), methodMirror, true))
                continue;
        }
        constructors.add(methodMirror);
    }
    return constructors;
}
Also used : MethodMirror(org.eclipse.ceylon.model.loader.mirror.MethodMirror) AnnotationMirror(org.eclipse.ceylon.model.loader.mirror.AnnotationMirror) LinkedList(java.util.LinkedList)

Example 8 with MethodMirror

use of org.eclipse.ceylon.model.loader.mirror.MethodMirror 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 9 with MethodMirror

use of org.eclipse.ceylon.model.loader.mirror.MethodMirror in project ceylon by eclipse.

the class AbstractModelLoader method collectMethods.

private void collectMethods(List<MethodMirror> methodMirrors, Map<String, List<MethodMirror>> methods, boolean isCeylon, boolean isFromJDK) {
    for (MethodMirror methodMirror : methodMirrors) {
        // We skip members marked with @Ignore
        if (methodMirror.getAnnotation(CEYLON_IGNORE_ANNOTATION) != null)
            continue;
        if (skipPrivateMember(methodMirror))
            continue;
        if (methodMirror.isStaticInit())
            continue;
        // these are not relevant for our caller
        if (methodMirror.isConstructor() || isInstantiator(methodMirror)) {
            continue;
        }
        // referenced in private methods but not available
        if (isFromJDK && !methodMirror.isPublic() && !methodMirror.isProtected())
            continue;
        String methodName = methodMirror.getName();
        List<MethodMirror> homonyms = methods.get(methodName);
        if (homonyms == null) {
            homonyms = new LinkedList<MethodMirror>();
            methods.put(methodName, homonyms);
        }
        homonyms.add(methodMirror);
    }
}
Also used : MethodMirror(org.eclipse.ceylon.model.loader.mirror.MethodMirror)

Example 10 with MethodMirror

use of org.eclipse.ceylon.model.loader.mirror.MethodMirror in project ceylon by eclipse.

the class AbstractModelLoader method createClass.

private Declaration createClass(Declaration container, ClassMirror classMirror, List<Declaration> decls, boolean isCeylon, boolean isNativeHeaderMember) {
    Declaration decl;
    Declaration hdr = null;
    final List<MethodMirror> constructors = getClassConstructors(classMirror, classMirror, overloadedConstructorOnly);
    if (!constructors.isEmpty()) {
        Boolean hasConstructors = hasConstructors(classMirror);
        if (constructors.size() > 1) {
            // only handle overloads here, the named constructors will be added to the abstraction
            // class on completion
            decl = makeOverloadedConstructor(constructors, classMirror, decls, isCeylon);
        } else {
            if (hasConstructors == null || !hasConstructors) {
                // single constructor
                MethodMirror constructor = constructors.get(0);
                // Same for coercion
                if (isCeylon || (getJavaVisibility(classMirror) == getJavaVisibility(constructor) && !isCoercedMethod(constructor))) {
                    decl = makeLazyClass(classMirror, null, constructor, isNativeHeaderMember);
                    setNonLazyDeclarationProperties(decl, classMirror, classMirror, classMirror, isCeylon);
                    if (isCeylon && shouldCreateNativeHeader(decl, container)) {
                        hdr = makeLazyClass(classMirror, null, constructor, true);
                        setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
                    }
                } else {
                    decl = makeOverloadedConstructor(constructors, classMirror, decls, isCeylon);
                }
            } else {
                decl = makeLazyClass(classMirror, null, null, isNativeHeaderMember);
                setNonLazyDeclarationProperties(decl, classMirror, classMirror, classMirror, isCeylon);
                if (isCeylon && shouldCreateNativeHeader(decl, container)) {
                    hdr = makeLazyClass(classMirror, null, null, true);
                    setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
                }
            }
        }
    } else if (isCeylon && classMirror.getAnnotation(CEYLON_OBJECT_ANNOTATION) != null) {
        // objects don't need overloading stuff
        decl = makeLazyClass(classMirror, null, null, isNativeHeaderMember);
        setNonLazyDeclarationProperties(decl, classMirror, classMirror, classMirror, isCeylon);
        if (isCeylon && shouldCreateNativeHeader(decl, container)) {
            hdr = makeLazyClass(classMirror, null, null, true);
            setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
        }
    } else {
        // no visible constructors
        decl = makeLazyClass(classMirror, null, null, isNativeHeaderMember);
        setNonLazyDeclarationProperties(decl, classMirror, classMirror, classMirror, isCeylon);
        if (isCeylon && shouldCreateNativeHeader(decl, container)) {
            hdr = makeLazyClass(classMirror, null, null, true);
            setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
        }
    }
    if (!isCeylon) {
        setSealedFromConstructorMods(decl, constructors);
    }
    return addHeaderAndDeclaration(decls, decl, hdr);
}
Also used : MethodMirror(org.eclipse.ceylon.model.loader.mirror.MethodMirror) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Aggregations

MethodMirror (org.eclipse.ceylon.model.loader.mirror.MethodMirror)15 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)6 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)6 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)6 AnnotationProxyClass (org.eclipse.ceylon.model.loader.model.AnnotationProxyClass)4 LazyClass (org.eclipse.ceylon.model.loader.model.LazyClass)4 Class (org.eclipse.ceylon.model.typechecker.model.Class)4 LinkedList (java.util.LinkedList)3 FieldValue (org.eclipse.ceylon.model.loader.model.FieldValue)3 JavaBeanValue (org.eclipse.ceylon.model.loader.model.JavaBeanValue)3 LazyFunction (org.eclipse.ceylon.model.loader.model.LazyFunction)3 LazyValue (org.eclipse.ceylon.model.loader.model.LazyValue)3 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 AnnotationMirror (org.eclipse.ceylon.model.loader.mirror.AnnotationMirror)2 ClassMirror (org.eclipse.ceylon.model.loader.mirror.ClassMirror)2 FunctionalInterfaceType (org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType)2 TypeMirror (org.eclipse.ceylon.model.loader.mirror.TypeMirror)2