Search in sources :

Example 31 with ParameterList

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

the class ClassDeclarationImpl method init.

@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
protected void init() {
    super.init();
    // anonymous classes don't have parameter lists
    if (!declaration.isAnonymous()) {
        org.eclipse.ceylon.model.typechecker.model.Class classDeclaration = (org.eclipse.ceylon.model.typechecker.model.Class) declaration;
        if (classDeclaration.isAbstraction()) {
            List<Declaration> overloads = classDeclaration.getOverloads();
            if (overloads.size() == 1) {
                classDeclaration = (org.eclipse.ceylon.model.typechecker.model.Class) overloads.get(0);
            }
        // else{
        // throw Metamodel.newModelError("Class has more than one overloaded constructor: "+classDeclaration.getNameAsString());
        // }
        }
        ParameterList parameterList = classDeclaration.getParameterList();
        if (parameterList != null) {
            this.parameters = FunctionalUtil.getParameters(classDeclaration);
        } else {
            this.parameters = null;
        }
    } else {
        this.parameters = null;
    }
    if (((Class) declaration).hasConstructors() || ((Class) declaration).hasEnumerated()) {
        this.constructors = new LinkedList<ceylon.language.meta.declaration.Declaration>();
        for (Declaration d : declaration.getMembers()) {
            if (d instanceof Constructor) {
                this.constructors.add(Metamodel.<ceylon.language.meta.declaration.Declaration>getOrCreateMetamodel(d));
            }
        }
    } else {
        this.constructors = Collections.emptyList();
    }
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Class(org.eclipse.ceylon.model.typechecker.model.Class) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Metamodel(org.eclipse.ceylon.compiler.java.runtime.metamodel.Metamodel) Class(org.eclipse.ceylon.model.typechecker.model.Class) CallableConstructorDeclaration(ceylon.language.meta.declaration.CallableConstructorDeclaration) FunctionOrValueDeclaration(ceylon.language.meta.declaration.FunctionOrValueDeclaration) ValueDeclaration(ceylon.language.meta.declaration.ValueDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) ConstructorDeclaration(ceylon.language.meta.declaration.ConstructorDeclaration) ValueConstructorDeclaration(ceylon.language.meta.declaration.ValueConstructorDeclaration)

Example 32 with ParameterList

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

the class Constructors method generateConstructor.

private static void generateConstructor(final Tree.Constructor that, final Tree.ClassDefinition cdef, final List<Tree.Constructor> constructors, final String fullName, final GenerateJsVisitor gen) {
    final Constructor d = TypeUtils.getConstructor(that.getDeclarationModel());
    final Class container = cdef.getDeclarationModel();
    final Tree.DelegatedConstructor delcons = that.getDelegatedConstructor();
    final TypeDeclaration superdec;
    final ParameterList superplist;
    final boolean callAbstract;
    if (delcons == null) {
        superdec = null;
        superplist = null;
        callAbstract = false;
    } else {
        superdec = delcons.getType().getDeclarationModel();
        /**
         * Is the delegated constructor is within the same class we call its abstract version
         */
        callAbstract = superdec instanceof Class ? superdec == container : ((Constructor) superdec).getContainer() == container;
        superplist = superdec instanceof Class ? ((Class) superdec).getParameterList() : ((Constructor) superdec).getFirstParameterList();
    }
    gen.out("function ", fullName, "$$a");
    final boolean withTargs = TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
    final String me = gen.getNames().self(container);
    gen.beginBlock();
    gen.initParameters(that.getParameterList(), container, null);
    if (delcons != null) {
        TypeGenerator.callSuperclass(delcons.getType(), delcons.getInvocationExpression(), container, superplist, that, callAbstract, null, gen);
    }
    // If there's a delegated constructor, run the statements after that one and before this one
    gen.generateConstructorStatements(that, classStatementsBetweenConstructors(cdef, delcons, that, gen));
    gen.out("return ", me, ";");
    gen.endBlockNewLine(true);
    gen.out("function ", fullName);
    TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
    gen.beginBlock();
    if (!d.isAbstract()) {
        gen.out("$init$", gen.getNames().name(container), "();");
        gen.endLine();
        gen.declareSelf(container);
        gen.referenceOuter(container);
    }
    gen.initParameters(that.getParameterList(), container, null);
    if (!d.isAbstract()) {
        // Call common initializer
        gen.out(gen.getNames().name(container), "$$c(");
        if (withTargs) {
            gen.out("$$targs$$,");
        }
        gen.out(me, ");");
        gen.endLine();
    }
    gen.out(fullName, "$$a");
    TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
    gen.endLine(true);
    if (d.isNative()) {
        gen.stitchConstructorHelper(cdef, "_cons_before");
    }
    gen.visitStatements(classStatementsAfterConstructor(cdef, that));
    if (d.isNative()) {
        gen.stitchConstructorHelper(cdef, "_cons_after");
    }
    gen.out("return ", me, ";");
    gen.endBlockNewLine(true);
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 33 with ParameterList

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

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

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

Aggregations

ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)69 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)47 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)44 Type (org.eclipse.ceylon.model.typechecker.model.Type)25 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)24 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)24 Functional (org.eclipse.ceylon.model.typechecker.model.Functional)23 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)22 Function (org.eclipse.ceylon.model.typechecker.model.Function)21 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)20 Value (org.eclipse.ceylon.model.typechecker.model.Value)20 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)19 ArrayList (java.util.ArrayList)16 AnalyzerUtil.getMatchingParameter (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getMatchingParameter)12 AnalyzerUtil.getUnspecifiedParameter (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getUnspecifiedParameter)12 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)12 FieldValue (org.eclipse.ceylon.model.loader.model.FieldValue)12 Class (org.eclipse.ceylon.model.typechecker.model.Class)11 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)10 HashMap (java.util.HashMap)9