Search in sources :

Example 36 with Value

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

the class ExpressionTransformer method appendImplicitArguments.

private void appendImplicitArguments(Invocation invocation, TransformedInvocationPrimary transformedPrimary, ListBuffer<ExpressionAndType> result) {
    // Implicit arguments
    // except for Java array constructors
    Declaration primaryDeclaration = invocation.getPrimaryDeclaration();
    Tree.Term primary = invocation.getPrimary();
    if (primaryDeclaration instanceof Value == false) {
        if (primaryDeclaration instanceof Class == false || !isJavaArray(((Class) primaryDeclaration).getType())) {
            invocation.addReifiedArguments(result);
        }
    }
    if (!(primary instanceof Tree.BaseTypeExpression) && !(primary instanceof Tree.QualifiedTypeExpression) && (!(primary instanceof Tree.QualifiedMemberExpression) || !(((Tree.QualifiedMemberExpression) primary).getMemberOperator() instanceof Tree.SpreadOp)) && Invocation.onValueType(this, primary, primaryDeclaration) && transformedPrimary != null) {
        result.add(new ExpressionAndType(transformedPrimary.expr, makeJavaType(primary.getTypeModel())));
    }
}
Also used : Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) Value(org.eclipse.ceylon.model.typechecker.model.Value) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) 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)

Example 37 with Value

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

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

the class ExpressionTransformer method transform.

public JCTree transform(Tree.MemberLiteral expr) {
    at(expr);
    Declaration declaration = expr.getDeclaration();
    if (declaration == null)
        return makeErroneous(expr, "compiler bug: missing declaration");
    if (declaration.isToplevel()) {
        return makeTopLevelValueOrFunctionLiteral(expr);
    } else if (expr.getWantsDeclaration()) {
        return makeMemberValueOrFunctionDeclarationLiteral(expr, declaration);
    } else {
        // get its produced ref
        Reference producedReference = expr.getTarget();
        // it's a member we get from its container type
        Type containerType = producedReference.getQualifyingType();
        // if we have no container type it means we have an object member
        boolean objectMember = containerType.getDeclaration().isAnonymous();
        JCExpression memberCall;
        if (objectMember) {
            // We don't care about the type args for the cast, nor for the reified container expr, because
            // we take the real reified container type from the container instance, and that one has the type
            // arguments
            containerType = ((Class) declaration.getContainer()).getType();
        }
        JCExpression typeCall = makeTypeLiteralCall(containerType, false, expr.getTypeModel());
        // make sure we cast it to ClassOrInterface
        String metatypeName;
        if (Decl.isConstructor(declaration)) {
            Class constructedClass = ModelUtil.getConstructedClass(declaration);
            Declaration container = getDeclarationContainer(constructedClass);
            if (constructedClass.isToplevel() || container instanceof TypeDeclaration == false) {
                metatypeName = "Class";
            } else {
                metatypeName = "MemberClass";
            }
        } else {
            metatypeName = "ClassOrInterface";
        }
        TypeDeclaration classOrInterfaceDeclaration = (TypeDeclaration) typeFact().getLanguageModuleModelDeclaration(metatypeName);
        JCExpression classOrInterfaceTypeExpr = makeJavaType(classOrInterfaceDeclaration.appliedReference(null, Arrays.asList(containerType)).getType());
        typeCall = make().TypeCast(classOrInterfaceTypeExpr, typeCall);
        // we will need a TD for the container
        // Note that we don't use Basic for the container for object members, because that's not how we represent
        // anonymous types.
        JCExpression reifiedContainerExpr = makeReifiedTypeArgument(containerType);
        // make a raw call and cast
        if (Decl.isConstructor(declaration)) {
            Type callableType = producedReference.getFullType();
            /*JCExpression reifiedArgumentsExpr;
                if (Decl.isEnumeratedConstructor(Decl.getConstructor(declaration))) {
                    reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType.getQualifyingType()));
                } else {
                    reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
                }*/
            JCExpression reifiedArguments;
            if (ModelUtil.isEnumeratedConstructor(ModelUtil.getConstructor(declaration))) {
                reifiedArguments = makeReifiedTypeArgument(typeFact().getNothingType());
            } else {
                reifiedArguments = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
            }
            List<JCExpression> arguments = List.of(reifiedArguments, ceylonLiteral(declaration.getName()));
            JCExpression classModel = makeSelect(typeCall, "getDeclaredConstructor");
            memberCall = make().Apply(null, classModel, arguments);
        } else if (declaration instanceof Function) {
            // we need to get types for each type argument
            JCExpression closedTypesExpr = null;
            if (expr.getTypeArgumentList() != null) {
                java.util.List<Type> typeModels = expr.getTypeArgumentList().getTypeModels();
                if (typeModels != null) {
                    closedTypesExpr = getClosedTypesSequential(typeModels);
                }
            }
            // we also need type descriptors for ret and args
            Type callableType = producedReference.getFullType();
            JCExpression reifiedReturnTypeExpr = makeReifiedTypeArgument(typeFact().getCallableReturnType(callableType));
            JCExpression reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
            List<JCExpression> arguments;
            if (closedTypesExpr != null)
                arguments = List.of(reifiedContainerExpr, reifiedReturnTypeExpr, reifiedArgumentsExpr, ceylonLiteral(declaration.getName()), closedTypesExpr);
            else
                arguments = List.of(reifiedContainerExpr, reifiedReturnTypeExpr, reifiedArgumentsExpr, ceylonLiteral(declaration.getName()));
            memberCall = make().Apply(null, makeSelect(typeCall, "getMethod"), arguments);
        } else if (declaration instanceof Value) {
            JCExpression reifiedGetExpr = makeReifiedTypeArgument(producedReference.getType());
            String getterName = "getAttribute";
            Type ptype;
            if (!((Value) declaration).isVariable())
                ptype = typeFact().getNothingType();
            else
                ptype = producedReference.getType();
            JCExpression reifiedSetExpr = makeReifiedTypeArgument(ptype);
            memberCall = make().Apply(null, makeSelect(typeCall, getterName), List.of(reifiedContainerExpr, reifiedGetExpr, reifiedSetExpr, ceylonLiteral(declaration.getName())));
        } else {
            return makeErroneous(expr, "Unsupported member type: " + declaration);
        }
        // if(objectMember){
        // // now get the instance and bind it
        // // I don't think we need any expected type since objects can't be erased
        // JCExpression object = transformExpression(expr.getObjectExpression());
        // // reset the location after we transformed the expression
        // memberCall = at(expr).Apply(null, makeSelect(memberCall, "bind"), List.of(object));
        // }
        // cast the member call because we invoke it with no Java generics
        memberCall = make().TypeCast(makeJavaType(expr.getTypeModel(), JT_RAW | JT_NO_PRIMITIVES), memberCall);
        memberCall = make().TypeCast(makeJavaType(expr.getTypeModel(), JT_NO_PRIMITIVES), memberCall);
        return memberCall;
    }
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) Function(org.eclipse.ceylon.model.typechecker.model.Function) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Value(org.eclipse.ceylon.model.typechecker.model.Value) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) CondList(org.eclipse.ceylon.compiler.java.codegen.StatementTransformer.CondList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) 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 39 with Value

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

the class ExpressionTransformer method addThisOrObjectQualifierIfRequired.

/**
 * We may need to force a qualified this prefix (direct or outer) in the following cases:
 *
 * - Required because of mixin inheritance with different type arguments (the same is already
 *   done for qualified references, but not for direct references)
 * - The compiler generates anonymous local classes for things like
 *   Callables and Comprehensions. When referring to a member foo
 *   within one of those things we need a qualified {@code this}
 *   to ensure we're accessing the outer instances member, not
 *   a member of the anonymous local class that happens to have the same name.
 */
private JCExpression addThisOrObjectQualifierIfRequired(JCExpression qualExpr, Tree.StaticMemberOrTypeExpression expr, Declaration decl) {
    // find out the real target
    Declaration typeDecl;
    if (Decl.isConstructor(decl))
        typeDecl = ModelUtil.getConstructedClass(decl);
    else
        typeDecl = decl;
    if (qualExpr == null && // statics are not members that can be inherited
    !decl.isStatic() && (!Decl.isConstructor(decl) || !Decl.isConstructor(typeDecl)) && typeDecl.isMember() && // and have a name mapping)
    expr.getTarget().getDeclaration() == decl && !ModelUtil.isLocalToInitializer(typeDecl) && !isWithinSuperInvocation()) {
        // First check whether the expression is captured from an enclosing scope
        TypeDeclaration outer = Decl.getOuterScopeOfMemberInvocation(expr, typeDecl);
        if (outer != null) {
            Type targetType = expr.getTarget().getQualifyingType();
            Type declarationContainerType = ((TypeDeclaration) outer).getType();
            // check if we need a variance cast
            VarianceCastResult varianceCastResult = getVarianceCastResult(targetType, declarationContainerType);
            // if we are within a comprehension body, or if we need a variance cast
            if (isWithinSyntheticClassBody() || varianceCastResult != null) {
                if (decl.isShared() && outer instanceof Interface) {
                    // always prefer qualified
                    qualExpr = makeQualifiedDollarThis(declarationContainerType);
                } else {
                    // Class or companion class,
                    qualExpr = naming.makeQualifiedThis(makeJavaType(((TypeDeclaration) outer).getType(), JT_RAW | (outer instanceof Interface ? JT_COMPANION : 0)));
                }
                // add the variance cast if required
                if (varianceCastResult != null) {
                    qualExpr = applyVarianceCasts(qualExpr, targetType, varianceCastResult, 0);
                }
            }
        } else if (typeDecl.isClassOrInterfaceMember()) {
            ClassOrInterface container;
            if (((ClassOrInterface) typeDecl.getContainer()).isAnonymous() && ((ClassOrInterface) typeDecl.getContainer()).isToplevel()) {
                // easy
                container = (Class) typeDecl.getContainer();
            } else {
                // find the import
                Import foundImport = statementGen().findImport(expr, decl);
                container = (Class) foundImport.getTypeDeclaration();
            }
            Value value = (Value) ((Package) container.getContainer()).getMember(container.getName(), null, false);
            qualExpr = make().Apply(null, naming.makeName(value, Naming.NA_FQ | Naming.NA_WRAPPER | Naming.NA_MEMBER), List.<JCExpression>nil());
        } else if (decl.isMember() && !expr.getStaticMethodReference()) {
            throw new BugException(expr, decl.getQualifiedNameString() + " was unexpectedly a member");
        }
    }
    return qualExpr;
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) Import(org.eclipse.ceylon.model.typechecker.model.Import) Value(org.eclipse.ceylon.model.typechecker.model.Value) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) 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) Package(org.eclipse.ceylon.model.typechecker.model.Package) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 40 with Value

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

the class StatementTransformer method transform.

/**
 * Transforms a Ceylon destructuring assignment to Java code.
 * @param stmt The Ceylon destructure
 * @return The Java tree
 */
List<JCStatement> transform(Tree.Destructure stmt) {
    List<JCStatement> result = List.nil();
    // Create temp var to hold result of expression
    Tree.Pattern pat = stmt.getPattern();
    Naming.SyntheticName tmpVarName = naming.synthetic(pat);
    Expression destExpr = stmt.getSpecifierExpression().getExpression();
    JCExpression typeExpr = makeJavaType(destExpr.getTypeModel());
    JCExpression expr = expressionGen().transformExpression(destExpr);
    at(stmt);
    JCVariableDecl tmpVar = makeVar(Flags.FINAL, tmpVarName, typeExpr, expr);
    result = result.append(tmpVar);
    // Now add the destructured variables
    List<VarDefBuilder> destructured = transformPattern(pat, tmpVarName.makeIdent());
    for (VarDefBuilder vdb : destructured) {
        Value v = vdb.var.getDeclarationModel();
        at(vdb.var);
        if (v.isClassMember() && v.isCaptured()) {
            AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.getter(this, v.getName(), v);
            adb.immutable();
            classGen().current().attribute(adb);
            classGen().current().defs(vdb.buildDefOnly());
            result = result.append(make().Exec(make().Assign(vdb.name().makeIdentWithThis(), vdb.expr())));
        } else {
            result = result.append(vdb.build());
        }
    }
    return result;
}
Also used : JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Value(org.eclipse.ceylon.model.typechecker.model.Value) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)

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