Search in sources :

Example 1 with FunctionalInterfaceType

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

the class CeylonModelLoader method getFunctionalInterfaceType.

@Override
protected FunctionalInterfaceType getFunctionalInterfaceType(TypeMirror typeMirror) throws ModelResolutionException {
    if (typeMirror.getKind() != TypeKind.DECLARED)
        throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror);
    // FIXME: possibly apply other optimisations to lighten the lookup cost? see what javac does
    Type type = ((JavacType) typeMirror).type;
    try {
        Type descriptorType = types.findDescriptorType(type);
        // Let's be honest I've no idea what this means, but it happens and Javac seems to refuse it too
        if (descriptorType.hasTag(TypeTag.FORALL))
            throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror);
        MethodType methodDescriptorType = (MethodType) descriptorType;
        MethodSymbol methodSymbol = (MethodSymbol) types.findDescriptorSymbol(type.tsym);
        List<Type> parameterTypes = methodDescriptorType.getParameterTypes();
        ListBuffer<TypeMirror> mirrorParameterTypes = new ListBuffer<>();
        for (int i = 0; i < parameterTypes.size(); i++) {
            Type parameterType = parameterTypes.get(i);
            if (methodSymbol.isVarArgs() && i == parameterTypes.size() - 1)
                parameterType = ((ArrayType) parameterType).getComponentType();
            mirrorParameterTypes.add(new JavacType(parameterType));
        }
        return new FunctionalInterfaceType(new JavacMethod(new JavacClass(methodSymbol.enclClass()), methodSymbol), new JavacType(methodDescriptorType.getReturnType()), mirrorParameterTypes.toList(), methodSymbol.isVarArgs());
    } catch (Symbol.CompletionFailure err) {
        // bad luck
        throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror, err);
    } catch (FunctionDescriptorLookupError err) {
        throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror, err);
    }
}
Also used : JavacType(org.eclipse.ceylon.compiler.java.loader.mirror.JavacType) MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) JavacMethod(org.eclipse.ceylon.compiler.java.loader.mirror.JavacMethod) CompletionFailure(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.CompletionFailure) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) TypeSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol) ClassSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) PackageSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.PackageSymbol) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) ArrayType(org.eclipse.ceylon.langtools.tools.javac.code.Type.ArrayType) ModelResolutionException(org.eclipse.ceylon.model.loader.ModelResolutionException) MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ArrayType(org.eclipse.ceylon.langtools.tools.javac.code.Type.ArrayType) JavacType(org.eclipse.ceylon.compiler.java.loader.mirror.JavacType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) TypeMirror(org.eclipse.ceylon.model.loader.mirror.TypeMirror) JavacClass(org.eclipse.ceylon.compiler.java.loader.mirror.JavacClass) FunctionDescriptorLookupError(org.eclipse.ceylon.langtools.tools.javac.code.Types.FunctionDescriptorLookupError)

Example 2 with FunctionalInterfaceType

use of org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType 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 3 with FunctionalInterfaceType

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

the class AbstractModelLoader method getFunctionalInterfaceAsCallable.

private Type getFunctionalInterfaceAsCallable(Module moduleScope, Scope scope, TypeMirror typeMirror) {
    try {
        FunctionalInterfaceType functionalInterfaceType = getFunctionalInterfaceType(typeMirror);
        Type returnType = obtainType(moduleScope, functionalInterfaceType.getReturnType(), scope, TypeLocation.TOPLEVEL);
        java.util.List<Type> modelParameterTypes = new ArrayList<Type>(functionalInterfaceType.getParameterTypes().size());
        for (TypeMirror parameterType : functionalInterfaceType.getParameterTypes()) {
            Type modelParameterType = obtainType(moduleScope, parameterType, scope, TypeLocation.TOPLEVEL);
            modelParameterTypes.add(modelParameterType);
        }
        org.eclipse.ceylon.model.typechecker.model.Type parameterTuple = typeFactory.getTupleType(modelParameterTypes, functionalInterfaceType.isVariadic(), false, -1);
        org.eclipse.ceylon.model.typechecker.model.Type callableType = typeFactory.getCallableDeclaration().appliedType(null, Arrays.asList(returnType, parameterTuple));
        return callableType;
    } catch (ModelResolutionException x) {
        return logModelResolutionException(x, scope, "Failure to turn functional interface to Callable type");
    }
}
Also used : FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) 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) ArrayList(java.util.ArrayList) Type(org.eclipse.ceylon.model.typechecker.model.Type)

Aggregations

FunctionalInterfaceType (org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType)3 TypeMirror (org.eclipse.ceylon.model.loader.mirror.TypeMirror)3 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)3 Type (org.eclipse.ceylon.model.typechecker.model.Type)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 JavacClass (org.eclipse.ceylon.compiler.java.loader.mirror.JavacClass)1 JavacMethod (org.eclipse.ceylon.compiler.java.loader.mirror.JavacMethod)1 JavacType (org.eclipse.ceylon.compiler.java.loader.mirror.JavacType)1 Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)1 ClassSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol)1 CompletionFailure (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.CompletionFailure)1 MethodSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol)1 PackageSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.PackageSymbol)1 TypeSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol)1 Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)1 ArrayType (org.eclipse.ceylon.langtools.tools.javac.code.Type.ArrayType)1 MethodType (org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType)1 FunctionDescriptorLookupError (org.eclipse.ceylon.langtools.tools.javac.code.Types.FunctionDescriptorLookupError)1