Search in sources :

Example 1 with LazyFunction

use of org.eclipse.ceylon.model.loader.model.LazyFunction in project ceylon by eclipse.

the class Naming method quoteMethodNameIfProperty.

private static String quoteMethodNameIfProperty(Function method) {
    String name = method.getName();
    if (!method.isShared()) {
        name = suffixName(Suffix.$priv$, name);
    }
    // Toplevel methods keep their original name because their names might be mangled
    if (method instanceof LazyFunction) {
        return ((LazyFunction) method).getRealName();
    }
    // since local methods have a $getter suffix
    if (!method.isClassOrInterfaceMember())
        return name;
    // do not quote method names if we have a refined constraint
    Function refinedMethod = (Function) method.getRefinedDeclaration();
    if (refinedMethod instanceof JavaMethod) {
        return ((JavaMethod) refinedMethod).getRealName();
    }
    // get/is with at least one more letter, no parameter and non-void type
    if (((name.length() >= 4 && name.startsWith("get")) || name.length() >= 3 && name.startsWith("is")) && // not the total number of parameters
    method.getFirstParameterList().getParameters().isEmpty() && !AbstractTransformer.isAnything(method.getType()))
        return quote(name);
    // set with one parameter and void type
    if ((name.length() >= 4 && name.startsWith("set")) && // not the total number of parameters
    method.getFirstParameterList().getParameters().size() == 1 && AbstractTransformer.isAnything(method.getType()))
        return quote(name);
    return name;
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction) JavaMethod(org.eclipse.ceylon.model.loader.model.JavaMethod) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction)

Example 2 with LazyFunction

use of org.eclipse.ceylon.model.loader.model.LazyFunction in project ceylon by eclipse.

the class Metamodel method getTypeDescriptorForProducedType.

public static TypeDescriptor getTypeDescriptorForProducedType(org.eclipse.ceylon.model.typechecker.model.Type type) {
    TypeDeclaration declaration = type.getDeclaration();
    if (type.isNothing()) {
        return TypeDescriptor.NothingType;
    }
    if (type.isUnion()) {
        TypeDescriptor[] tdArgs = getTypeDescriptorsForProducedTypes(type.getCaseTypes());
        return TypeDescriptor.union(tdArgs);
    }
    if (type.isIntersection()) {
        TypeDescriptor[] tdArgs = getTypeDescriptorsForProducedTypes(type.getSatisfiedTypes());
        return TypeDescriptor.intersection(tdArgs);
    }
    if (declaration instanceof LazyClass) {
        ReflectionClass classMirror = (ReflectionClass) ((LazyClass) declaration).classMirror;
        TypeDescriptor[] tdArgs = getTypeDescriptorsForProducedTypes(type.getTypeArgumentList());
        TypeDescriptor ret = TypeDescriptor.klass(classMirror.klass, tdArgs);
        if (type.getQualifyingType() != null)
            return TypeDescriptor.member(getTypeDescriptorForProducedType(type.getQualifyingType()), ret);
        return ret;
    }
    if (declaration instanceof LazyInterface) {
        ReflectionClass classMirror = (ReflectionClass) ((LazyInterface) declaration).classMirror;
        TypeDescriptor[] tdArgs = getTypeDescriptorsForProducedTypes(type.getTypeArgumentList());
        TypeDescriptor ret = TypeDescriptor.klass(classMirror.klass, tdArgs);
        if (type.getQualifyingType() != null)
            return TypeDescriptor.member(getTypeDescriptorForProducedType(type.getQualifyingType()), ret);
        return ret;
    }
    if (declaration instanceof FunctionOrValueInterface) {
        TypedDeclaration underlyingDeclaration = ((FunctionOrValueInterface) declaration).getUnderlyingDeclaration();
        TypeDescriptor[] tdArgs = getTypeDescriptorsForProducedTypes(type.getTypeArgumentList());
        TypeDescriptor ret;
        if (underlyingDeclaration.isToplevel()) {
            ReflectionClass classMirror;
            // type arguments
            if (underlyingDeclaration instanceof Setter)
                underlyingDeclaration = ((Setter) underlyingDeclaration).getGetter();
            if (underlyingDeclaration instanceof LazyValue)
                classMirror = (ReflectionClass) ((LazyValue) underlyingDeclaration).classMirror;
            else if (underlyingDeclaration instanceof LazyFunction)
                classMirror = (ReflectionClass) ((LazyFunction) underlyingDeclaration).classMirror;
            else
                throw Metamodel.newModelError("Unsupported underlying declaration type: " + underlyingDeclaration);
            ret = TypeDescriptor.functionOrValue(classMirror.klass, tdArgs);
        } else
            ret = TypeDescriptor.functionOrValue(underlyingDeclaration.getPrefixedName(), tdArgs);
        if (type.getQualifyingType() != null)
            return TypeDescriptor.member(getTypeDescriptorForProducedType(type.getQualifyingType()), ret);
        return ret;
    }
    if (declaration instanceof UnknownType) {
        ((UnknownType) declaration).reportErrors();
    }
    throw Metamodel.newModelError("Unsupported declaration type: " + (declaration == null ? "null" : declaration.getClass()));
}
Also used : FunctionOrValueInterface(org.eclipse.ceylon.model.loader.model.FunctionOrValueInterface) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) LazyValue(org.eclipse.ceylon.model.loader.model.LazyValue) TypeDescriptor(org.eclipse.ceylon.compiler.java.runtime.model.TypeDescriptor) ReflectionClass(org.eclipse.ceylon.model.loader.impl.reflect.mirror.ReflectionClass) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 3 with LazyFunction

use of org.eclipse.ceylon.model.loader.model.LazyFunction in project ceylon by eclipse.

the class AbstractModelLoader method findLocalContainerFromAnnotationAndSetCompanionClass.

private Scope findLocalContainerFromAnnotationAndSetCompanionClass(Package pkg, Interface declaration, AnnotationMirror localContainerAnnotation) {
    @SuppressWarnings("unchecked") List<String> path = (List<String>) localContainerAnnotation.getValue("path");
    // we start at the package
    Scope scope = pkg;
    for (String name : path) {
        scope = (Scope) getDirectMember(scope, name);
    }
    String companionClassName = (String) localContainerAnnotation.getValue("companionClassName");
    if (companionClassName == null || companionClassName.isEmpty()) {
        declaration.setCompanionClassNeeded(false);
        return scope;
    }
    ClassMirror container;
    Scope javaClassScope;
    if (scope instanceof TypedDeclaration && ((TypedDeclaration) scope).isMember())
        javaClassScope = scope.getContainer();
    else
        javaClassScope = scope;
    if (javaClassScope instanceof LazyInterface) {
        container = ((LazyInterface) javaClassScope).companionClass;
    } else if (javaClassScope instanceof LazyClass) {
        container = ((LazyClass) javaClassScope).classMirror;
    } else if (javaClassScope instanceof LazyValue) {
        container = ((LazyValue) javaClassScope).classMirror;
    } else if (javaClassScope instanceof LazyFunction) {
        container = ((LazyFunction) javaClassScope).classMirror;
    } else if (javaClassScope instanceof SetterWithLocalDeclarations) {
        container = ((SetterWithLocalDeclarations) javaClassScope).classMirror;
    } else {
        throw new ModelResolutionException("Unknown scope class: " + javaClassScope);
    }
    String qualifiedCompanionClassName = container.getQualifiedName() + "$" + companionClassName;
    ClassMirror companionClassMirror = lookupClassMirror(pkg.getModule(), qualifiedCompanionClassName);
    if (companionClassMirror == null)
        throw new ModelResolutionException("Could not find companion class mirror: " + qualifiedCompanionClassName);
    ((LazyInterface) declaration).companionClass = companionClassMirror;
    return scope;
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) LazyValue(org.eclipse.ceylon.model.loader.model.LazyValue) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction) ClassMirror(org.eclipse.ceylon.model.loader.mirror.ClassMirror) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) SetterWithLocalDeclarations(org.eclipse.ceylon.model.loader.model.SetterWithLocalDeclarations) List(java.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass)

Example 4 with LazyFunction

use of org.eclipse.ceylon.model.loader.model.LazyFunction in project ceylon by eclipse.

the class AbstractModelLoader method makeToplevelMethod.

protected LazyFunction makeToplevelMethod(ClassMirror classMirror, boolean isNativeHeader) {
    LazyFunction method = new LazyFunction(classMirror, this);
    manageNativeBackend(method, getFunctionMethodMirror(method), isNativeHeader);
    return method;
}
Also used : LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction)

Example 5 with LazyFunction

use of org.eclipse.ceylon.model.loader.model.LazyFunction 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)

Aggregations

LazyFunction (org.eclipse.ceylon.model.loader.model.LazyFunction)5 LazyValue (org.eclipse.ceylon.model.loader.model.LazyValue)3 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)3 ClassMirror (org.eclipse.ceylon.model.loader.mirror.ClassMirror)2 LazyClass (org.eclipse.ceylon.model.loader.model.LazyClass)2 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)2 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)2 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 TypeDescriptor (org.eclipse.ceylon.compiler.java.runtime.model.TypeDescriptor)1 ReflectionClass (org.eclipse.ceylon.model.loader.impl.reflect.mirror.ReflectionClass)1 AnnotationMirror (org.eclipse.ceylon.model.loader.mirror.AnnotationMirror)1 MethodMirror (org.eclipse.ceylon.model.loader.mirror.MethodMirror)1 TypeMirror (org.eclipse.ceylon.model.loader.mirror.TypeMirror)1 FunctionOrValueInterface (org.eclipse.ceylon.model.loader.model.FunctionOrValueInterface)1 JavaMethod (org.eclipse.ceylon.model.loader.model.JavaMethod)1 LocalDeclarationContainer (org.eclipse.ceylon.model.loader.model.LocalDeclarationContainer)1 SetterWithLocalDeclarations (org.eclipse.ceylon.model.loader.model.SetterWithLocalDeclarations)1 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)1