Search in sources :

Example 26 with TypedDeclaration

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

the class ExpressionTransformer method transformCallableBridge.

public JCExpression transformCallableBridge(Tree.StaticMemberOrTypeExpression expr, Value functional, Type expectedType) {
    ParameterList paramList = new ParameterList();
    // expr is a SAM
    // expectedType is a Callable
    TypedReference samRef = checkForFunctionalInterface(expr.getTypeModel());
    TypedDeclaration samDecl = samRef.getDeclaration();
    if (samDecl instanceof Value) {
        Parameter param = new Parameter();
        Value paramModel = new Value();
        param.setModel(paramModel);
        param.setName("arg0");
        paramModel.setName("arg0");
        paramModel.setType(samRef.getType());
        paramModel.setUnboxed(samDecl.getUnboxed());
        // FIXME: other stuff like erasure?
        paramList.getParameters().add(param);
    } else {
        int i = 0;
        for (Parameter samParam : ((Function) samDecl).getFirstParameterList().getParameters()) {
            TypedReference typedSamParam = samRef.getTypedParameter(samParam);
            Parameter param = new Parameter();
            Value paramModel = new Value();
            param.setModel(paramModel);
            param.setName("arg" + i);
            paramModel.setName("arg" + i);
            paramModel.setType(typedSamParam.getFullType());
            // FIXME: other stuff like erasure?
            paramModel.setUnboxed(typedSamParam.getDeclaration().getUnboxed());
            paramList.getParameters().add(param);
            i++;
        }
    }
    // FIXME: this is cheating we should be assembling it from the SAM type
    Type callableType = expectedType.getSupertype(typeFact().getCallableDeclaration());
    return CallableBuilder.methodReference(gen(), expr, paramList, expectedType, callableType, false);
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Value(org.eclipse.ceylon.model.typechecker.model.Value) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) 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 27 with TypedDeclaration

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

the class MethodDefinitionBuilder method getNonWideningParam.

public NonWideningParam getNonWideningParam(TypedReference typedRef, WideningRules wideningRules) {
    TypedDeclaration nonWideningDecl = null;
    int flags = 0;
    long modifiers = 0;
    Type nonWideningType;
    FunctionOrValue mov = (FunctionOrValue) typedRef.getDeclaration();
    if (Decl.isValue(mov)) {
        TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
        nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef).resolveAliases();
        nonWideningDecl = nonWideningTypedRef.getDeclaration();
    } else {
        // Stef: So here's the thing. I know this is wrong for Function where we should do getFullType(), BUT
        // lots of methods call this and then feed the output into AT.makeJavaType(TypedDeclaration typeDecl, Type type, int flags)
        // which adds the Callable type, so if we fix it here we have to remove it from there and there's lots of callers of that
        // function which rely on its behaviour and frankly I've had enough of this refactoring, so a few callers of this function
        // have to add the Callable back. It sucks, yeah, but so far it works, which is amazing enough that I don't want to touch it
        // any more. More ambitious/courageous people are welcome to fix this properly.
        nonWideningType = typedRef.getType().resolveAliases();
        nonWideningDecl = mov;
    }
    if (!CodegenUtil.isUnBoxed(nonWideningDecl))
        flags |= AbstractTransformer.JT_NO_PRIMITIVES;
    // make sure we don't accidentally narrow value parameters that would be erased in the topmost declaration
    if (wideningRules != WideningRules.NONE && mov instanceof Value) {
        TypedDeclaration refinedParameter = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(mov);
        if (refinedParameter != null && refinedParameter instanceof Value && ((Value) refinedParameter).getInitializerParameter() != null && gen.isJavaVariadic(((Value) refinedParameter).getInitializerParameter())) {
            modifiers |= Flags.VARARGS;
        }
        // mixin bridge methods have the same rules as when refining stuff except they are their own refined decl
        if (wideningRules == WideningRules.FOR_MIXIN || !Decl.equal(refinedParameter, mov)) {
            Type refinedParameterType;
            // in the refined parameter type
            if (refinedParameter instanceof Function)
                refinedParameterType = refinedParameter.appliedTypedReference(null, Collections.<Type>emptyList()).getFullType();
            else
                refinedParameterType = refinedParameter.getType();
            // if the supertype method itself got erased to Object, we can't do better than this
            if (gen.willEraseToObject(refinedParameterType) && !gen.willEraseToBestBounds(mov))
                nonWideningType = gen.typeFact().getObjectType();
            else if (CodegenUtil.isRaw(refinedParameter)) {
                flags |= AbstractTransformer.JT_RAW;
            } else {
                flags |= AbstractTransformer.JT_NARROWED;
            }
            if ((flags & AbstractTransformer.JT_RAW) == 0 && !Decl.equal(refinedParameter, mov) && implementsRawParameter(mov)) {
                flags |= AbstractTransformer.JT_RAW;
            }
        }
    }
    // keep in sync with gen.willEraseToBestBounds()
    if (wideningRules != WideningRules.NONE && (gen.typeFact().isUnion(nonWideningType) || gen.typeFact().isIntersection(nonWideningType))) {
        final Type refinedType = ((TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(nonWideningDecl)).getType();
        if (refinedType.isTypeParameter() && !refinedType.getSatisfiedTypes().isEmpty()) {
            nonWideningType = refinedType.getSatisfiedTypes().get(0);
            // Could be parameterized, and type param won't be in scope, so have to go raw
            flags |= AbstractTransformer.JT_RAW;
        }
    }
    // this is to be done on the parameter's containing method, to see if that method must have raw parameters
    if (mov.isParameter() && mov.getContainer() instanceof Declaration && gen.rawParameters((Declaration) mov.getContainer())) {
        flags |= AbstractTransformer.JT_RAW;
    }
    return new NonWideningParam(flags, modifiers, nonWideningType, nonWideningDecl);
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 28 with TypedDeclaration

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

the class MethodDefinitionBuilder method implementsRawParameter.

private boolean implementsRawParameter(FunctionOrValue decl) {
    if (ModelUtil.containsRawType(decl.getType()))
        return true;
    // Taken pretty much straight from JvmBackendUtil.getTopmostRefinement
    Functional func = (Functional) JvmBackendUtil.getParameterized((FunctionOrValue) decl);
    if (func == null || func instanceof TypedDeclaration == false)
        return false;
    Declaration kk = getFirstRefinedDeclaration((TypedDeclaration) func);
    // error recovery
    if (kk instanceof Functional == false)
        return false;
    Functional refinedFunc = (Functional) kk;
    // shortcut if the functional doesn't override anything
    if (ModelUtil.equal((Declaration) refinedFunc, (Declaration) func)) {
        return false;
    }
    if (func.getParameterLists().size() != refinedFunc.getParameterLists().size()) {
        // invalid input
        return false;
    }
    for (int ii = 0; ii < func.getParameterLists().size(); ii++) {
        if (func.getParameterLists().get(ii).getParameters().size() != refinedFunc.getParameterLists().get(ii).getParameters().size()) {
            // invalid input
            return false;
        }
        // find the index of the parameter in the declaration
        int index = 0;
        for (Parameter px : func.getParameterLists().get(ii).getParameters()) {
            if (px.getModel() == null || px.getModel().equals(decl)) {
                // And return the corresponding parameter from the refined declaration
                FunctionOrValue refinedDecl = refinedFunc.getParameterLists().get(ii).getParameters().get(index).getModel();
                return implementsRawParameter(refinedDecl);
            }
            index++;
        }
        continue;
    }
    // invalid input
    return false;
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 29 with TypedDeclaration

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

the class Naming method makeDefaultedParamMethod.

JCExpression makeDefaultedParamMethod(JCExpression qualifier, Parameter param) {
    // TODO Can we merge this into makeName(..., NA_DPM) ?
    if (!Strategy.hasDefaultParameterValueMethod(param)) {
        throw new BugException();
    }
    Declaration decl = param.getDeclaration();
    String methodName = getDefaultedParamMethodName(decl, param);
    switch(Strategy.defaultParameterMethodOwner(param.getModel())) {
        case SELF:
            {
                // method not within interface
                Declaration container = param.getDeclaration().getRefinedDeclaration();
                if (!container.isToplevel()) {
                    container = (Declaration) container.getContainer();
                }
                JCExpression className = makeTypeDeclarationExpression(qualifier, (TypeDeclaration) container, DeclNameFlag.COMPANION);
                return makeSelect(className, methodName);
            }
        case OUTER:
        case OUTER_COMPANION:
            return makeQuotedQualIdent(qualifier, methodName);
        case STATIC:
            {
                // top level method or class
                // return makeSelect(gen().makeStaticQualifier(param.getDeclaration().getRefinedDeclaration()), methodName);
                Declaration container = param.getDeclaration().getRefinedDeclaration();
                if (!container.isToplevel() && !container.isStatic()) {
                    container = (Declaration) container.getContainer();
                } else if (container.isStatic() && container instanceof TypedDeclaration) {
                    container = (Declaration) container.getContainer();
                }
                if (container instanceof TypedDeclaration) {
                    return makeSelect(makeName((TypedDeclaration) container, NA_FQ | NA_WRAPPER), methodName);
                } else {
                    return makeSelect(gen().makeJavaType(((TypeDeclaration) container).getType(), AbstractTransformer.JT_RAW | AbstractTransformer.JT_NO_PRIMITIVES), methodName);
                }
            }
        default:
            // inner or local class or method, or method in an interface
            return makeQuotedQualIdent(qualifier, methodName);
    }
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 30 with TypedDeclaration

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

the class Naming method addNamesForWrapperClass.

private <R> void addNamesForWrapperClass(TypeDeclarationBuilder<R> builder, TypedDeclaration decl, int namingOptions) {
    if ((namingOptions & NA_FQ) != 0) {
        if ((namingOptions & NA_WRAPPER) == 0 && (namingOptions & NA_WRAPPER_UNQUOTED) == 0) {
            throw new BugException("If you pass FQ you must pass WRAPPER or WRAPPER_UNQUOTED too, or there's no class name to qualify!");
        }
        List<String> outerNames = null;
        Scope s = decl.getContainer();
        boolean isInterop = false;
        while (s != null) {
            if (s instanceof Package) {
                final List<String> packageName = isInterop ? ORG_ECLIPSE_CEYLON_LANGUAGE_PACKAGE : ((Package) s).getName();
                for (int ii = 0; ii < packageName.size(); ii++) {
                    if (ii == 0 && packageName.get(ii).isEmpty()) {
                        continue;
                    }
                    builder.select(quoteIfJavaKeyword(packageName.get(ii)));
                }
                break;
            } else if (s instanceof ClassOrInterface) {
                ClassOrInterface c = (ClassOrInterface) s;
                if (isJavaInterop(c))
                    isInterop = true;
                if (outerNames == null) {
                    outerNames = new ArrayList<String>(2);
                }
                outerNames.add(getQuotedClassName(c, 0));
            } else if (s instanceof TypedDeclaration) {
                if (outerNames == null) {
                    outerNames = new ArrayList<String>(2);
                }
                outerNames.add(quoteIfJavaKeyword(getRealName((TypedDeclaration) s, 0)));
            }
            s = s.getContainer();
        }
        if (outerNames != null) {
            for (int ii = outerNames.size() - 1; ii >= 0; ii--) {
                String outerName = outerNames.get(ii);
                builder.select(outerName);
            }
        }
    }
    if ((namingOptions & NA_WRAPPER) != 0) {
        builder.select(getQuotedClassName(decl, namingOptions & (NA_GETTER | NA_SETTER)));
    } else if ((namingOptions & NA_WRAPPER_UNQUOTED) != 0) {
        builder.select(getRealName(decl, namingOptions & (NA_GETTER | NA_SETTER | NA_WRAPPER_UNQUOTED)));
    } else if ((namingOptions & NA_Q_LOCAL_INSTANCE) != 0) {
        if (Decl.isBoxedVariable(decl)) {
            builder.select(getVariableBoxName(decl));
        } else {
            builder.select(getAttrClassName(decl, namingOptions & (NA_GETTER | NA_SETTER)));
        }
    }
    if ((namingOptions & NA_WRAPPER_WITH_THIS) != 0) {
        builder.select("this");
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ArrayList(java.util.ArrayList) Package(org.eclipse.ceylon.model.typechecker.model.Package)

Aggregations

TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)110 Type (org.eclipse.ceylon.model.typechecker.model.Type)58 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)51 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)50 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)47 Function (org.eclipse.ceylon.model.typechecker.model.Function)34 Value (org.eclipse.ceylon.model.typechecker.model.Value)28 Class (org.eclipse.ceylon.model.typechecker.model.Class)26 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)26 AnalyzerUtil.getTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration)25 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)22 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)21 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)21 AnalyzerUtil.getPackageTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration)20 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)19 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)18 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)17 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)17 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)16 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)15