Search in sources :

Example 51 with Module

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

the class AbstractModelLoader method findLanguageModuleDeclarationForBootstrap.

private Declaration findLanguageModuleDeclarationForBootstrap(String name) {
    // make sure we don't return anything for ceylon.language
    if (name.equals(CEYLON_LANGUAGE))
        return null;
    // we're bootstrapping ceylon.language so we need to return the ProducedTypes straight from the model we're compiling
    Module languageModule = modules.getLanguageModule();
    int lastDot = name.lastIndexOf(".");
    if (lastDot == -1)
        return null;
    String pkgName = name.substring(0, lastDot);
    String simpleName = name.substring(lastDot + 1);
    // Nothing is a special case with no real decl
    if (name.equals("ceylon.language.Nothing"))
        return typeFactory.getNothingDeclaration();
    // find the right package
    Package pkg = languageModule.getDirectPackage(pkgName);
    if (pkg != null) {
        Declaration member = pkg.getDirectMember(simpleName, null, false);
        // if we get a value, we want its type
        if (JvmBackendUtil.isValue(member) && ((Value) member).getTypeDeclaration().getName().equals(simpleName)) {
            member = ((Value) member).getTypeDeclaration();
        }
        if (member != null)
            return member;
    }
    throw new ModelResolutionException("Failed to look up given type in language module while bootstrapping: " + name);
}
Also used : LazyPackage(org.eclipse.ceylon.model.loader.model.LazyPackage) Package(org.eclipse.ceylon.model.typechecker.model.Package) 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)

Example 52 with Module

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

the class AbstractModelLoader method addValue.

private JavaBeanValue addValue(ClassOrInterface klass, MethodMirror methodMirror, String methodName, boolean isCeylon, boolean isNativeHeader) {
    JavaBeanValue value = new JavaBeanValue(methodMirror);
    value.setGetterName(methodMirror.getName());
    value.setContainer(klass);
    value.setScope(klass);
    value.setUnit(klass.getUnit());
    Type type = null;
    try {
        setMethodOrValueFlags(klass, methodMirror, value, isCeylon);
    } catch (ModelResolutionException x) {
        // collect an error in its type
        type = logModelResolutionException(x, klass, "getter '" + methodName + "' (checking if it is an overriding method");
    }
    value.setName(JvmBackendUtil.strip(methodName, isCeylon, value.isShared()));
    Module module = ModelUtil.getModuleContainer(klass);
    // do not log an additional error if we had one from checking if it was overriding
    if (type == null)
        type = obtainType(methodMirror.getReturnType(), methodMirror, klass, module, "getter '" + methodName + "'", klass);
    if (type.isCached()) {
        type = type.clone();
    }
    // special case for hash attributes which we want to pretend are of type long internally
    if (value.isShared() && methodName.equals("hash"))
        type.setUnderlyingType("long");
    NullStatus nullPolicy = getUncheckedNullPolicy(isCeylon, methodMirror.getReturnType(), methodMirror);
    switch(nullPolicy) {
        case Optional:
            if (!isCeylon) {
                type = makeOptionalTypePreserveUnderlyingType(type, module);
            }
            break;
        case UncheckedNull:
            value.setUncheckedNullType(true);
            break;
    }
    value.setType(type);
    type.setRaw(isRaw(module, methodMirror.getReturnType()));
    markUnboxed(value, methodMirror, methodMirror.getReturnType());
    markSmall(value, methodMirror.getReturnType());
    markTypeErased(value, methodMirror, methodMirror.getReturnType());
    markUntrustedType(value, methodMirror, methodMirror.getReturnType());
    value.setDeprecated(isDeprecated(methodMirror));
    setAnnotations(value, methodMirror, isNativeHeader);
    klass.addMember(value);
    ModelUtil.setVisibleScope(value);
    return value;
}
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) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) Module(org.eclipse.ceylon.model.typechecker.model.Module) LazyModule(org.eclipse.ceylon.model.loader.model.LazyModule)

Example 53 with Module

use of org.eclipse.ceylon.model.typechecker.model.Module 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 54 with Module

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

the class AbstractModelLoader method setCaseTypes.

private void setCaseTypes(ClassOrInterface klass, ClassMirror classMirror) {
    if (classMirror.isEnum()) {
        ArrayList<Type> caseTypes = new ArrayList<Type>();
        for (Declaration member : klass.getMembers()) {
            if (member instanceof FieldValue && ((FieldValue) member).isEnumValue()) {
                caseTypes.add(((FieldValue) member).getType());
            }
        }
        klass.setCaseTypes(caseTypes);
    } else {
        String selfType = getSelfTypeFromAnnotations(classMirror);
        Module moduleScope = ModelUtil.getModuleContainer(klass);
        if (selfType != null && !selfType.isEmpty()) {
            Type type = decodeType(selfType, klass, moduleScope, "self type");
            if (!type.isTypeParameter()) {
                logError("Invalid type signature for self type of " + klass.getQualifiedNameString() + ": " + selfType + " is not a type parameter");
            } else {
                klass.setSelfType(type);
                List<Type> caseTypes = new LinkedList<Type>();
                caseTypes.add(type);
                klass.setCaseTypes(caseTypes);
            }
        } else {
            List<String> caseTypes = getCaseTypesFromAnnotations(classMirror);
            if (caseTypes != null && !caseTypes.isEmpty()) {
                klass.setCaseTypes(getTypesList(caseTypes, klass, moduleScope, "case types", klass.getQualifiedNameString()));
            }
        }
    }
}
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) ArrayList(java.util.ArrayList) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) Module(org.eclipse.ceylon.model.typechecker.model.Module) LazyModule(org.eclipse.ceylon.model.loader.model.LazyModule) LinkedList(java.util.LinkedList)

Example 55 with Module

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

the class AbstractModelLoader method addValue.

private Value addValue(ClassOrInterface klass, String ceylonName, FieldMirror fieldMirror, boolean isCeylon, boolean isNativeHeader) {
    // make sure it's a FieldValue so we can figure it out in the backend
    Value value = new FieldValue(fieldMirror.getName());
    value.setContainer(klass);
    value.setScope(klass);
    // use the name annotation if present (used by Java arrays)
    String nameAnnotation = getAnnotationStringValue(fieldMirror, CEYLON_NAME_ANNOTATION);
    value.setName(nameAnnotation != null ? nameAnnotation : ceylonName);
    value.setUnit(klass.getUnit());
    value.setShared(fieldMirror.isPublic() || fieldMirror.isProtected() || fieldMirror.isDefaultAccess());
    value.setProtectedVisibility(fieldMirror.isProtected());
    value.setPackageVisibility(fieldMirror.isDefaultAccess());
    value.setStatic(fieldMirror.isStatic());
    setDeclarationAliases(value, fieldMirror);
    setDeclarationRestrictions(value, fieldMirror);
    // field can't be abstract or interface, so not formal
    // can we override fields? good question. Not really, but from an external point of view?
    // FIXME: figure this out: (default)
    // FIXME: for the same reason, can it be an overriding field? (actual)
    value.setVariable(!fieldMirror.isFinal());
    // figure out if it's an enum subtype in a final static field
    if (fieldMirror.getType().getKind() == TypeKind.DECLARED && fieldMirror.getType().getDeclaredClass() != null && fieldMirror.getType().getDeclaredClass().isEnum() && fieldMirror.isFinal() && fieldMirror.isStatic())
        value.setEnumValue(true);
    Module module = ModelUtil.getModuleContainer(klass);
    Type type = obtainType(fieldMirror.getType(), fieldMirror, klass, module, "field '" + value.getName() + "'", klass);
    if (type.isCached()) {
        type = type.clone();
    }
    if (value.isEnumValue()) {
        Constructor enumValueType = new Constructor();
        enumValueType.setJavaEnum(true);
        enumValueType.setExtendedType(type);
        Scope scope = value.getContainer();
        enumValueType.setContainer(scope);
        enumValueType.setScope(scope);
        enumValueType.setDeprecated(value.isDeprecated());
        enumValueType.setName(value.getName());
        enumValueType.setUnit(value.getUnit());
        enumValueType.setStatic(value.isStatic());
        value.setType(enumValueType.getType());
        value.setUncheckedNullType(false);
    } else {
        NullStatus nullPolicy = getUncheckedNullPolicy(isCeylon, fieldMirror.getType(), fieldMirror);
        switch(nullPolicy) {
            case Optional:
                if (!isCeylon) {
                    type = makeOptionalTypePreserveUnderlyingType(type, module);
                }
                break;
            case UncheckedNull:
                value.setUncheckedNullType(true);
                break;
        }
        value.setType(type);
    }
    type.setRaw(isRaw(module, fieldMirror.getType()));
    markUnboxed(value, null, fieldMirror.getType());
    markSmall(value, fieldMirror.getType());
    markTypeErased(value, fieldMirror, fieldMirror.getType());
    markUntrustedType(value, fieldMirror, fieldMirror.getType());
    value.setDeprecated(isDeprecated(fieldMirror));
    setAnnotations(value, fieldMirror, isNativeHeader);
    klass.addMember(value);
    ModelUtil.setVisibleScope(value);
    return value;
}
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) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) 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) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) Module(org.eclipse.ceylon.model.typechecker.model.Module) LazyModule(org.eclipse.ceylon.model.loader.model.LazyModule)

Aggregations

Module (org.eclipse.ceylon.model.typechecker.model.Module)113 LazyModule (org.eclipse.ceylon.model.loader.model.LazyModule)37 Package (org.eclipse.ceylon.model.typechecker.model.Package)26 ModuleImport (org.eclipse.ceylon.model.typechecker.model.ModuleImport)25 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)20 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)19 ArrayList (java.util.ArrayList)18 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)16 File (java.io.File)14 Type (org.eclipse.ceylon.model.typechecker.model.Type)14 HashMap (java.util.HashMap)9 HashSet (java.util.HashSet)9 FunctionalInterfaceType (org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType)9 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)9 Test (org.junit.Test)9 Value (org.eclipse.ceylon.model.typechecker.model.Value)8 LinkedList (java.util.LinkedList)7 List (java.util.List)7 Backends (org.eclipse.ceylon.common.Backends)7 ClassMirror (org.eclipse.ceylon.model.loader.mirror.ClassMirror)7