Search in sources :

Example 91 with Value

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

the class AbstractModelLoader method loadFunctionCoercionParameter.

@SuppressWarnings("incomplete-switch")
private Function loadFunctionCoercionParameter(Declaration decl, String paramName, TypeMirror typeMirror, Module moduleScope, Scope scope) {
    Function method = new Function();
    method.setName(paramName);
    method.setUnit(decl.getUnit());
    try {
        FunctionalInterfaceType functionalInterfaceType = getFunctionalInterfaceType(typeMirror);
        MethodMirror functionalMethod = functionalInterfaceType.getMethod();
        Type returnType = obtainType(moduleScope, functionalInterfaceType.getReturnType(), scope, TypeLocation.TOPLEVEL);
        switch(getUncheckedNullPolicy(false, functionalInterfaceType.getReturnType(), functionalMethod)) {
            case Optional:
            case UncheckedNull:
                returnType = makeOptionalTypePreserveUnderlyingType(returnType, moduleScope);
                break;
        }
        method.setType(returnType);
        ParameterList pl = new ParameterList();
        // List<VariableMirror> functionalParameters = functionalMethod.getParameters();
        List<TypeMirror> parameterTypes = functionalInterfaceType.getParameterTypes();
        Map<String, Integer> used = new HashMap<String, Integer>();
        for (TypeMirror parameterType : parameterTypes) {
            String name;
            if (parameterTypes.size() == 1) {
                name = "it";
            } else {
                switch(parameterType.getKind()) {
                    case ARRAY:
                        name = "array";
                        break;
                    case BOOLEAN:
                        name = "boolean";
                        break;
                    case CHAR:
                        name = "character";
                        break;
                    case BYTE:
                        name = "byte";
                        break;
                    case INT:
                    case LONG:
                    case SHORT:
                        name = "integer";
                        break;
                    case FLOAT:
                    case DOUBLE:
                        name = "float";
                        break;
                    case DECLARED:
                        String typeName = parameterType.getDeclaredClass().getName();
                        int first = typeName.codePointAt(0);
                        name = String.valueOf(Character.toChars(Character.toLowerCase(first))) + typeName.substring(Character.charCount(first));
                        break;
                    default:
                        name = "arg";
                }
                Integer count = used.get(name);
                if (count == null) {
                    used.put(name, 1);
                } else {
                    int next = count + 1;
                    used.put(name, next);
                    name += next;
                }
            }
            Type modelParameterType = obtainType(moduleScope, parameterType, scope, TypeLocation.TOPLEVEL);
            Parameter p = new Parameter();
            Value v = new Value();
            p.setName(name);
            v.setName(name);
            v.setContainer(method);
            v.setScope(method);
            p.setModel(v);
            v.setInitializerParameter(p);
            // Java parameters are all optional unless primitives or annotated as such
            switch(getUncheckedNullPolicy(false, parameterType, functionalMethod)) {
                case Optional:
                    modelParameterType = makeOptionalTypePreserveUnderlyingType(modelParameterType, moduleScope);
                    break;
                case UncheckedNull:
                    v.setUncheckedNullType(true);
                    break;
            }
            v.setType(modelParameterType);
            pl.getParameters().add(p);
            method.addMember(v);
        }
        method.addParameterList(pl);
    } catch (ModelResolutionException x) {
        method.setType(logModelResolutionException(x, scope, "Failure to turn functional interface to Callable type"));
    }
    return method;
}
Also used : FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Function(org.eclipse.ceylon.model.typechecker.model.Function) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction) MethodMirror(org.eclipse.ceylon.model.loader.mirror.MethodMirror) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) TypeMirror(org.eclipse.ceylon.model.loader.mirror.TypeMirror) 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)

Example 92 with Value

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

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

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

the class AbstractModelLoader method complete.

private void complete(AnnotationProxyMethod ctor, AnnotationProxyClass klass, LazyInterface iface) {
    ParameterList ctorpl = new ParameterList();
    ctorpl.setPositionalParametersSupported(false);
    ctor.addParameterList(ctorpl);
    List<Parameter> ctorParams = new ArrayList<Parameter>();
    for (Declaration member : iface.getMembers()) {
        boolean isValue = member.getName().equals("value");
        if (member instanceof JavaMethod) {
            JavaMethod m = (JavaMethod) member;
            Parameter ctorParam = new Parameter();
            ctorParams.add(ctorParam);
            Value value = new Value();
            ctorParam.setModel(value);
            value.setInitializerParameter(ctorParam);
            ctorParam.setDeclaration(ctor);
            value.setContainer(klass);
            value.setScope(klass);
            ctorParam.setDefaulted(m.isDefaultedAnnotation());
            value.setName(member.getName());
            ctorParam.setName(member.getName());
            value.setType(annotationParameterType(iface.getUnit(), m));
            value.setUnboxed(true);
            value.setUnit(iface.getUnit());
            if (isValue)
                ctorpl.getParameters().add(0, ctorParam);
            else
                ctorpl.getParameters().add(ctorParam);
            ctor.addMember(value);
        }
    }
    makeInteropAnnotationConstructorInvocation(ctor, klass, ctorParams);
}
Also used : ArrayList(java.util.ArrayList) 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) JavaMethod(org.eclipse.ceylon.model.loader.model.JavaMethod) 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 95 with Value

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

the class NamingBase method getSetterName.

public static String getSetterName(Declaration decl) {
    // use the refined decl except when the current declaration is variable and the refined isn't
    Declaration refinedDecl = decl.getRefinedDeclaration();
    if (isValue(decl) && isValue(refinedDecl)) {
        Value v = (Value) decl;
        Value rv = (Value) refinedDecl;
        if (!v.isVariable() || rv.isVariable()) {
            decl = refinedDecl;
        }
    } else {
        decl = refinedDecl;
    }
    if (decl instanceof FieldValue) {
        return ((FieldValue) decl).getRealName();
    }
    if (decl instanceof JavaBeanValue && // one it will not. This is also used for late setters...
    ((JavaBeanValue) decl).getSetterName() != null) {
        return ((JavaBeanValue) decl).getSetterName();
    } else if (decl.isClassOrInterfaceMember() && !isLocalToInitializer(decl) || decl.isStatic()) {
        String setterName = getSetterName(decl.getName());
        if (decl.isMember() && !decl.isShared()) {
            setterName = suffixName(Suffix.$priv$, setterName);
        }
        return setterName;
    } else if (decl instanceof TypedDeclaration && isBoxedVariable((TypedDeclaration) decl)) {
        return name(Unfix.ref);
    } else {
        return name(Unfix.set_);
    }
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Value(org.eclipse.ceylon.model.typechecker.model.Value) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) JvmBackendUtil.isValue(org.eclipse.ceylon.model.loader.JvmBackendUtil.isValue) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue)

Aggregations

Value (org.eclipse.ceylon.model.typechecker.model.Value)190 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)135 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)77 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)74 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)70 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)69 Type (org.eclipse.ceylon.model.typechecker.model.Type)68 Function (org.eclipse.ceylon.model.typechecker.model.Function)50 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)47 Class (org.eclipse.ceylon.model.typechecker.model.Class)46 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)42 JavaBeanValue (org.eclipse.ceylon.model.loader.model.JavaBeanValue)30 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)30 ArrayList (java.util.ArrayList)29 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)29 FieldValue (org.eclipse.ceylon.model.loader.model.FieldValue)28 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)27 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)26 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)24 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)23