Search in sources :

Example 76 with Scope

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

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

Example 78 with Scope

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

the class TypeParser method decodeType.

public Type decodeType(String type, Scope scope, Module moduleScope, Unit unit) {
    // save the previous state (this method is reentrant)
    char[] oldType = lexer.type;
    int oldIndex = lexer.index;
    int oldMark = lexer.mark;
    Scope oldScope = this.scope;
    Module oldModuleScope = this.moduleScope;
    Unit oldUnit = this.unit;
    try {
        // setup the new state
        lexer.setup(type);
        this.scope = scope;
        this.moduleScope = moduleScope;
        this.unit = unit;
        // do the parsing
        Type ret = parseType();
        if (!lexer.lookingAt(TypeLexer.EOT))
            throw new TypeParserException("Junk lexemes remaining: " + lexer.eatTokenString());
        return ret;
    } finally {
        // restore the previous state
        lexer.type = oldType;
        lexer.index = oldIndex;
        lexer.mark = oldMark;
        this.scope = oldScope;
        this.moduleScope = oldModuleScope;
        this.unit = oldUnit;
    }
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Module(org.eclipse.ceylon.model.typechecker.model.Module) Unit(org.eclipse.ceylon.model.typechecker.model.Unit)

Example 79 with Scope

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

the class Metamodel method checkQualifyingType.

public static void checkQualifyingType(Type qualifyingType, Declaration declaration) {
    Scope container = declaration.getContainer();
    if (container instanceof TypeDeclaration == false)
        throw new IncompatibleTypeException("Declaration container is not a type: " + container);
    TypeDeclaration typeDecl = (TypeDeclaration) container;
    Type supertype = qualifyingType.getSupertype(typeDecl);
    if (supertype == null)
        throw new IncompatibleTypeException("Invalid container type: " + qualifyingType + " is not a subtype of " + typeDecl);
}
Also used : ReifiedType(org.eclipse.ceylon.compiler.java.runtime.model.ReifiedType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) OpenClassOrInterfaceType(ceylon.language.meta.declaration.OpenClassOrInterfaceType) OpenType(ceylon.language.meta.declaration.OpenType) DeclarationType(org.eclipse.ceylon.model.loader.ModelLoader.DeclarationType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) IncompatibleTypeException(ceylon.language.meta.model.IncompatibleTypeException) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 80 with Scope

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

the class ExpressionVisitor method visitQualifiedMemberExpression.

private void visitQualifiedMemberExpression(Tree.QualifiedMemberExpression that, Type receivingType, TypedDeclaration member, List<Type> typeArgs, Tree.TypeArguments tal) {
    checkMemberOperator(receivingType, that);
    Tree.Primary primary = that.getPrimary();
    if (isConstructor(member) && !(primary instanceof Tree.BaseTypeExpression || primary instanceof Tree.QualifiedTypeExpression)) {
        primary.addError("constructor reference must be qualified by a type expression");
    }
    Type receiverType = accountForStaticReferenceReceiverType(that, unwrap(receivingType, that));
    if (acceptsTypeArguments(member, receiverType, typeArgs, tal, that) || true) {
        TypedReference ptr = receiverType.getTypedMember(member, typeArgs, that.getAssigned());
        /*if (ptr==null) {
                that.addError("method or attribute is not defined: " + 
                        member.getName(unit) + " of type " + 
                        receiverType.getDeclaration().getName(unit));
            }
            else {*/
        that.setTarget(ptr);
        checkSpread(member, that);
        boolean direct = that.getDirectlyInvoked();
        Type fullType = accountForGenericFunctionRef(direct, tal, receivingType, typeArgs, ptr.getFullType(wrap(ptr.getType(), receivingType, that)));
        Scope scope = that.getScope();
        if (!dynamic && !isNativeForWrongBackend(scope, unit) && !isAbstraction(member) && isTypeUnknown(fullType) && !hasError(that)) {
            // this occurs with an ambiguous reference
            // to a member of an intersection type
            String rtname = receiverType.getDeclaration().getName(unit);
            that.addError("could not determine type of method or attribute reference: '" + member.getName(unit) + "' of '" + rtname + "' is ambiguous" + getTypeUnknownError(fullType));
        }
        that.setTypeModel(accountForStaticReferenceType(that, member, fullType));
    // }
    }
    if (that.getStaticMethodReference()) {
        handleStaticReferenceImplicitTypeArguments(that);
    }
}
Also used : ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) NativeUtil.declarationScope(org.eclipse.ceylon.compiler.typechecker.util.NativeUtil.declarationScope) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Aggregations

Scope (org.eclipse.ceylon.model.typechecker.model.Scope)142 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)71 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)57 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)50 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)44 Type (org.eclipse.ceylon.model.typechecker.model.Type)44 ConditionScope (org.eclipse.ceylon.model.typechecker.model.ConditionScope)35 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)34 Class (org.eclipse.ceylon.model.typechecker.model.Class)33 ModelUtil.getRealScope (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope)31 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)30 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)26 Value (org.eclipse.ceylon.model.typechecker.model.Value)26 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)25 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)24 Function (org.eclipse.ceylon.model.typechecker.model.Function)23 Package (org.eclipse.ceylon.model.typechecker.model.Package)22 ArrayList (java.util.ArrayList)21 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)20 NativeUtil.declarationScope (org.eclipse.ceylon.compiler.typechecker.util.NativeUtil.declarationScope)15