Search in sources :

Example 6 with AnnotationMirror

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

the class AbstractModelLoader method hasConstructors.

/**
 * Returns:
 * <ul>
 * <li>true if the class has named constructors ({@code @Class(...constructors=true)}).</li>
 * <li>false if the class has an initializer constructor.</li>
 * <li>null if the class lacks {@code @Class} (i.e. is not a Ceylon class).</li>
 * </ul>
 * @param classMirror
 * @return
 */
private Boolean hasConstructors(ClassMirror classMirror) {
    AnnotationMirror a = classMirror.getAnnotation(CEYLON_CLASS_ANNOTATION);
    Boolean hasConstructors;
    if (a != null) {
        hasConstructors = (Boolean) a.getValue("constructors");
        if (hasConstructors == null) {
            hasConstructors = false;
        }
    } else {
        hasConstructors = null;
    }
    return hasConstructors;
}
Also used : AnnotationMirror(org.eclipse.ceylon.model.loader.mirror.AnnotationMirror)

Example 7 with AnnotationMirror

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

the class AbstractModelLoader method setParameters.

private void setParameters(Functional decl, ClassMirror classMirror, MethodMirror methodMirror, boolean isCeylon, Scope container, boolean isCoercedMethod) {
    ParameterList parameters = new ParameterList();
    parameters.setNamedParametersSupported(isCeylon);
    decl.addParameterList(parameters);
    int parameterCount = methodMirror.getParameters().size();
    int parameterIndex = 0;
    for (VariableMirror paramMirror : methodMirror.getParameters()) {
        // ignore some parameters
        if (paramMirror.getAnnotation(CEYLON_IGNORE_ANNOTATION) != null)
            continue;
        boolean isLastParameter = parameterIndex == parameterCount - 1;
        boolean isVariadic = isLastParameter && methodMirror.isVariadic();
        String paramName = getAnnotationStringValue(paramMirror, CEYLON_NAME_ANNOTATION);
        // use whatever param name we find as default
        if (paramName == null)
            paramName = paramMirror.getName();
        Parameter parameter = new Parameter();
        parameter.setName(paramName);
        TypeMirror typeMirror = paramMirror.getType();
        Scope scope = (Scope) decl;
        Module module = ModelUtil.getModuleContainer(scope);
        Type type;
        boolean coercedParameter = false;
        if (isVariadic) {
            // possibly make it optional
            TypeMirror variadicType = typeMirror.getComponentType();
            // we pretend it's toplevel because we want to get magic string conversion for variadic methods
            if (isCoercedMethod && isCoercedType(variadicType)) {
                type = applyTypeCoercion(variadicType, paramMirror, methodMirror, paramName, (Declaration) decl, module, scope);
                coercedParameter = true;
            } else {
                type = obtainType(module, variadicType, scope, TypeLocation.TOPLEVEL);
            }
            if (!isCeylon) {
                // Java parameters are all optional unless primitives or annotated as such
                if (getUncheckedNullPolicy(isCeylon, variadicType, paramMirror) != NullStatus.NonOptional) {
                    type = makeOptionalTypePreserveUnderlyingType(type, module);
                }
            }
            // turn it into a Sequential<T>
            type = typeFactory.getSequentialType(type);
        } else {
            if (isCoercedMethod && isCoercedType(typeMirror)) {
                type = applyTypeCoercion(typeMirror, paramMirror, methodMirror, paramName, (Declaration) decl, module, scope);
                coercedParameter = true;
            } else {
                type = obtainType(typeMirror, paramMirror, scope, module, "parameter '" + paramName + "' of method '" + methodMirror.getName() + "'", (Declaration) decl);
            }
            if (!isCeylon) {
                // Java parameters are all optional unless primitives or annotated as such
                if (getUncheckedNullPolicy(isCeylon, typeMirror, paramMirror) != NullStatus.NonOptional) {
                    type = makeOptionalTypePreserveUnderlyingType(type, module);
                }
            }
        }
        if (type.isCached()) {
            type = type.clone();
        }
        if (!type.isRaw())
            type.setRaw(isRaw(ModelUtil.getModuleContainer(container), typeMirror));
        FunctionOrValue value = null;
        boolean lookedup = false;
        if (isCeylon && decl instanceof Class) {
            // For a functional parameter to a class, we can just lookup the member
            value = (FunctionOrValue) ((Class) decl).getDirectMember(paramName, null, false);
            lookedup = value != null;
        }
        if (value == null) {
            // So either decl is not a Class,
            // or the method or value member of decl is not shared
            AnnotationMirror functionalParameterAnnotation = paramMirror.getAnnotation(CEYLON_FUNCTIONAL_PARAMETER_ANNOTATION);
            if (functionalParameterAnnotation != null) {
                // A functional parameter to a method
                Function method = loadFunctionalParameter((Declaration) decl, paramName, type, (String) functionalParameterAnnotation.getValue());
                value = method;
                parameter.setDeclaredAnything(method.isDeclaredVoid());
            } else if (coercedParameter && isFunctionCercion(typeMirror)) {
                Function method = loadFunctionCoercionParameter((Declaration) decl, paramName, typeMirror, module, scope);
                value = method;
                parameter.setDeclaredAnything(method.isDeclaredVoid());
            } else {
                // A value parameter to a method
                value = isCeylon ? new Value() : new JavaParameterValue();
                value.setType(type);
            }
            value.setContainer(scope);
            value.setScope(scope);
            ModelUtil.setVisibleScope(value);
            value.setUnit(scope.getUnit());
            value.setName(paramName);
        } else {
            // the method return type, so we try to detect this and fix it
            if (value instanceof Function && isCeylon1Dot1(classMirror)) {
                Type newType = getSimpleCallableReturnType(value.getType());
                if (!newType.isUnknown())
                    value.setType(newType);
            }
        }
        value.setInitializerParameter(parameter);
        value.setCoercionPoint(coercedParameter);
        parameter.setModel(value);
        if (paramMirror.getAnnotation(CEYLON_SEQUENCED_ANNOTATION) != null || isVariadic)
            parameter.setSequenced(true);
        if (paramMirror.getAnnotation(CEYLON_DEFAULTED_ANNOTATION) != null)
            parameter.setDefaulted(true);
        if (parameter.isSequenced() && // FIXME: store info in Sequenced
        "ceylon.language.Sequence".equals(paramMirror.getType().getQualifiedName())) {
            parameter.setAtLeastOne(true);
        }
        // unboxed is already set if it's a real method
        if (!lookedup) {
            // if it's variadic, consider the array element type (T[] == T...) for boxing rules
            markUnboxed(value, null, isVariadic ? paramMirror.getType().getComponentType() : paramMirror.getType());
            markSmall(value, paramMirror.getType());
        }
        parameter.setDeclaration((Declaration) decl);
        value.setDeprecated(value.isDeprecated() || isDeprecated(paramMirror));
        setAnnotations(value, paramMirror, false);
        parameters.getParameters().add(parameter);
        if (!lookedup) {
            parameter.getDeclaration().getMembers().add(parameter.getModel());
        }
        parameterIndex++;
    }
    if (decl instanceof Function) {
        // Multiple parameter lists
        AnnotationMirror functionalParameterAnnotation = methodMirror.getAnnotation(CEYLON_FUNCTIONAL_PARAMETER_ANNOTATION);
        if (functionalParameterAnnotation != null) {
            parameterNameParser.parseMpl((String) functionalParameterAnnotation.getValue(), ((Function) decl).getType().getFullType(), (Function) decl);
        }
    }
}
Also used : AnnotationMirror(org.eclipse.ceylon.model.loader.mirror.AnnotationMirror) Function(org.eclipse.ceylon.model.typechecker.model.Function) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) TypeMirror(org.eclipse.ceylon.model.loader.mirror.TypeMirror) VariableMirror(org.eclipse.ceylon.model.loader.mirror.VariableMirror) JavaParameterValue(org.eclipse.ceylon.model.loader.model.JavaParameterValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) LazyValue(org.eclipse.ceylon.model.loader.model.LazyValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) 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) Module(org.eclipse.ceylon.model.typechecker.model.Module) LazyModule(org.eclipse.ceylon.model.loader.model.LazyModule) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaParameterValue(org.eclipse.ceylon.model.loader.model.JavaParameterValue)

Example 8 with AnnotationMirror

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

the class AbstractModelLoader method isCeylon1Dot1.

private boolean isCeylon1Dot1(ClassMirror classMirror) {
    AnnotationMirror annotation = classMirror.getAnnotation(CEYLON_CEYLON_ANNOTATION);
    if (annotation == null)
        return false;
    Integer major = (Integer) annotation.getValue("major");
    if (major == null)
        major = 0;
    Integer minor = (Integer) annotation.getValue("minor");
    if (minor == null)
        minor = 0;
    return major == Versions.V1_1_BINARY_MAJOR_VERSION && minor == Versions.V1_1_BINARY_MINOR_VERSION;
}
Also used : AnnotationMirror(org.eclipse.ceylon.model.loader.mirror.AnnotationMirror)

Example 9 with AnnotationMirror

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

the class AbstractModelLoader method getContainer.

private ClassOrInterface getContainer(Module module, ClassMirror classMirror) {
    AnnotationMirror containerAnnotation = classMirror.getAnnotation(CEYLON_CONTAINER_ANNOTATION);
    if (containerAnnotation != null) {
        TypeMirror javaClassMirror = (TypeMirror) containerAnnotation.getValue("klass");
        String javaClassName = javaClassMirror.getQualifiedName();
        ClassOrInterface containerDecl = (ClassOrInterface) convertToDeclaration(module, javaClassName, DeclarationType.TYPE);
        if (containerDecl == null)
            throw new ModelResolutionException("Failed to load outer type " + javaClassName + " for inner type " + classMirror.getQualifiedName().toString());
        return containerDecl;
    } else {
        return (ClassOrInterface) convertToDeclaration(module, classMirror.getEnclosingClass(), DeclarationType.TYPE);
    }
}
Also used : AnnotationMirror(org.eclipse.ceylon.model.loader.mirror.AnnotationMirror) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeMirror(org.eclipse.ceylon.model.loader.mirror.TypeMirror)

Example 10 with AnnotationMirror

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

the class AbstractModelLoader method setTypeParametersFromAnnotations.

// from our annotation
private void setTypeParametersFromAnnotations(Scope scope, List<TypeParameter> params, AnnotatedMirror mirror, List<AnnotationMirror> typeParameterAnnotations, List<TypeParameterMirror> typeParameterMirrors) {
    // We must first add every type param, before we resolve the bounds, which can
    // refer to type params.
    String selfTypeName = getSelfTypeFromAnnotations(mirror);
    int i = 0;
    for (AnnotationMirror typeParamAnnotation : typeParameterAnnotations) {
        TypeParameter param = new TypeParameter();
        param.setUnit(scope.getUnit());
        param.setContainer(scope);
        param.setScope(scope);
        ModelUtil.setVisibleScope(param);
        param.setDeclaration((Declaration) scope);
        // let's not trigger the lazy-loading if we're completing a LazyClass/LazyInterface
        if (scope instanceof LazyContainer)
            ((LazyContainer) scope).addMember(param);
        else
            // must be a method
            scope.addMember(param);
        param.setName((String) typeParamAnnotation.getValue("value"));
        param.setExtendedType(typeFactory.getAnythingType());
        if (i < typeParameterMirrors.size()) {
            TypeParameterMirror typeParameterMirror = typeParameterMirrors.get(i);
            param.setNonErasedBounds(hasNonErasedBounds(typeParameterMirror));
        }
        String varianceName = (String) typeParamAnnotation.getValue("variance");
        if (varianceName != null) {
            if (varianceName.equals("IN")) {
                param.setContravariant(true);
            } else if (varianceName.equals("OUT"))
                param.setCovariant(true);
        }
        // If this is a self type param then link it to its type's declaration
        if (param.getName().equals(selfTypeName)) {
            param.setSelfTypedDeclaration((TypeDeclaration) scope);
        }
        params.add(param);
        i++;
    }
    Module moduleScope = ModelUtil.getModuleContainer(scope);
    // Now all type params have been set, we can resolve the references parts
    Iterator<TypeParameter> paramsIterator = params.iterator();
    for (AnnotationMirror typeParamAnnotation : typeParameterAnnotations) {
        TypeParameter param = paramsIterator.next();
        @SuppressWarnings("unchecked") List<String> satisfiesAttribute = (List<String>) typeParamAnnotation.getValue("satisfies");
        setListOfTypes(param.getSatisfiedTypes(), satisfiesAttribute, scope, moduleScope, "type parameter '" + param.getName() + "' satisfied types");
        @SuppressWarnings("unchecked") List<String> caseTypesAttribute = (List<String>) typeParamAnnotation.getValue("caseTypes");
        if (caseTypesAttribute != null && !caseTypesAttribute.isEmpty())
            param.setCaseTypes(new LinkedList<Type>());
        setListOfTypes(param.getCaseTypes(), caseTypesAttribute, scope, moduleScope, "type parameter '" + param.getName() + "' case types");
        String defaultValueAttribute = (String) typeParamAnnotation.getValue("defaultValue");
        if (defaultValueAttribute != null && !defaultValueAttribute.isEmpty()) {
            Type decodedType = decodeType(defaultValueAttribute, scope, moduleScope, "type parameter '" + param.getName() + "' defaultValue");
            param.setDefaultTypeArgument(decodedType);
            param.setDefaulted(true);
        }
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) LinkedList(java.util.LinkedList) AnnotationMirror(org.eclipse.ceylon.model.loader.mirror.AnnotationMirror) LazyContainer(org.eclipse.ceylon.model.loader.model.LazyContainer) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) TypeParameterMirror(org.eclipse.ceylon.model.loader.mirror.TypeParameterMirror) List(java.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Module(org.eclipse.ceylon.model.typechecker.model.Module) LazyModule(org.eclipse.ceylon.model.loader.model.LazyModule)

Aggregations

AnnotationMirror (org.eclipse.ceylon.model.loader.mirror.AnnotationMirror)25 LinkedList (java.util.LinkedList)6 LazyModule (org.eclipse.ceylon.model.loader.model.LazyModule)6 Module (org.eclipse.ceylon.model.typechecker.model.Module)6 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)6 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)6 ArrayList (java.util.ArrayList)5 List (java.util.List)5 TypeMirror (org.eclipse.ceylon.model.loader.mirror.TypeMirror)5 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)5 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)5 FunctionalInterfaceType (org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType)4 LazyClass (org.eclipse.ceylon.model.loader.model.LazyClass)4 Type (org.eclipse.ceylon.model.typechecker.model.Type)4 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)4 ClassMirror (org.eclipse.ceylon.model.loader.mirror.ClassMirror)3 AnnotationProxyClass (org.eclipse.ceylon.model.loader.model.AnnotationProxyClass)3 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)3 LazyValue (org.eclipse.ceylon.model.loader.model.LazyValue)3 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)3