Search in sources :

Example 16 with TypedReference

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

the class ExpressionTransformer method transformExpression.

// 
// Any sort of expression
JCExpression transformExpression(final TypedDeclaration declaration, final Tree.Term expr) {
    // make sure we use the best declaration for boxing and type
    TypedReference typedRef = getTypedReference(declaration);
    TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
    Type nonWideningType = nonWideningType(typedRef, nonWideningTypedRef);
    // the non-widening type of the innermost callable
    if (declaration instanceof Functional && Decl.isMpl((Functional) declaration)) {
        for (int i = ((Functional) declaration).getParameterLists().size(); i > 1; i--) {
            nonWideningType = getReturnTypeOfCallable(nonWideningType);
        }
    }
    // respect the refining definition of optionality
    nonWideningType = propagateOptionality(declaration.getType(), nonWideningType);
    BoxingStrategy boxing = CodegenUtil.getBoxingStrategy(nonWideningTypedRef.getDeclaration());
    int flags = 0;
    if (declaration.hasUncheckedNullType() || declaration == coercedFunctionalInterfaceNeedsNoNullChecks)
        flags = ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL;
    if (CodegenUtil.downcastForSmall(expr, declaration))
        flags |= ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK;
    return transformExpression(expr, boxing, nonWideningType, flags);
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference)

Example 17 with TypedReference

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

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

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

the class MethodDefinitionBuilder method resultTypeNonWidening.

public MethodDefinitionBuilder resultTypeNonWidening(Type currentType, TypedReference typedRef, Type returnType, int flags) {
    TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef, currentType);
    returnType = gen.nonWideningType(typedRef, nonWideningTypedRef);
    return resultType(makeResultType(nonWideningTypedRef.getDeclaration(), returnType, flags), typedRef.getDeclaration());
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference)

Example 20 with TypedReference

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

the class NamedArgumentInvocation method bindAttributeArgument.

private void bindAttributeArgument(Tree.AttributeArgument attrArg, Parameter declaredParam, Naming.SyntheticName argName) {
    ListBuffer<JCStatement> statements;
    final Value model = attrArg.getDeclarationModel();
    final String name = model.getName();
    String className = Naming.getAttrClassName(model, 0);
    final List<JCTree> attrClass = gen.gen().transformAttribute(model, name, className, null, attrArg.getBlock(), attrArg.getSpecifierExpression(), null, null);
    TypedReference typedRef = gen.getTypedReference(model);
    TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
    Type nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef);
    Type type = parameterType(declaredParam, model.getType(), 0);
    final BoxingStrategy boxType = getNamedParameterBoxingStrategy(declaredParam);
    JCExpression initValue = gen.make().Apply(null, gen.makeSelect(gen.makeUnquotedIdent(className), Naming.getGetterName(model)), List.<JCExpression>nil());
    initValue = gen.expressionGen().applyErasureAndBoxing(initValue, nonWideningType, !CodegenUtil.isUnBoxed(nonWideningTypedRef.getDeclaration()), boxType, type);
    JCTree.JCVariableDecl var = gen.make().VarDef(gen.make().Modifiers(FINAL, List.<JCAnnotation>nil()), argName.asName(), gen.makeJavaType(type, boxType == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0), initValue);
    statements = toStmts(attrArg, attrClass).append(var);
    bind(declaredParam, argName, gen.makeJavaType(type, boxType == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0), statements.toList());
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) Value(org.eclipse.ceylon.model.typechecker.model.Value) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) BoxingStrategy(org.eclipse.ceylon.compiler.java.codegen.AbstractTransformer.BoxingStrategy) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)

Aggregations

TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)40 Type (org.eclipse.ceylon.model.typechecker.model.Type)35 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)17 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)17 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)16 Function (org.eclipse.ceylon.model.typechecker.model.Function)15 Value (org.eclipse.ceylon.model.typechecker.model.Value)14 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)12 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)11 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)10 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)10 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)10 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)10 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)9 ModelUtil.genericFunctionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType)8 ModelUtil.unionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType)8 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)8 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)8 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)8 ArrayList (java.util.ArrayList)7