Search in sources :

Example 1 with Tree

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree in project ceylon by eclipse.

the class BoxingVisitor method visit.

@Override
public void visit(Tree.IfExpression that) {
    super.visit(that);
    if (that.getIfClause() == null || that.getElseClause() == null)
        return;
    Tree.Expression ifExpr = that.getIfClause().getExpression();
    Tree.Expression elseExpr = that.getElseClause().getExpression();
    if (ifExpr == null || elseExpr == null)
        return;
    if (CodegenUtil.isUnBoxed(ifExpr) && CodegenUtil.isUnBoxed(elseExpr) && !willEraseToObject(that.getUnit().denotableType(that.getTypeModel())))
        CodegenUtil.markUnBoxed(that);
    if (that.getTypeModel().isExactly(that.getUnit().getNullValueType())) {
        CodegenUtil.markTypeErased(that);
    }
// An If expression can never be raw, type erased or untrusted because
// it uses a Let with a new variable declaration, so the rawness,
// erasedness and untrustedness of its branches cannot propagate further
// up the tree.
}
Also used : Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Example 2 with Tree

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree in project ceylon by eclipse.

the class ExpressionVisitor method handleStaticReferenceImplicitTypeArguments.

/**
 * Validate the type arguments to the qualifying type
 * in a static reference when no type arguments are
 * given explicitly.
 *
 * This is called later than usual because the type args
 * might be inferrable from an invocation of the whole
 * static reference.
 *
 * @param that the static reference
 */
private void handleStaticReferenceImplicitTypeArguments(Tree.QualifiedMemberOrTypeExpression that) {
    Declaration member = that.getDeclaration();
    Tree.TypeArguments tas = that.getTypeArguments();
    // without type arguments to the qualifying type
    if (isStaticReference(that)) {
        if (member != null && !explicitTypeArguments(member, tas)) {
            that.addError("type arguments could not be inferred: '" + member.getName(unit) + "' is generic");
        }
        // the reference to the qualifying type
        Tree.StaticMemberOrTypeExpression smte = (Tree.StaticMemberOrTypeExpression) that.getPrimary();
        // we have to get the type args from the tree
        // here because the calling code doesn't know
        // them (it is walking the qualifying reference)
        Tree.TypeArguments typeArgs = smte.getTypeArguments();
        TypeDeclaration type = (TypeDeclaration) smte.getDeclaration();
        if (type != null && !explicitTypeArguments(type, typeArgs) && typeArgs.getTypeModels() == null) {
            // nothing inferred
            Declaration declaration = smte.getDeclaration();
            smte.addError("missing type arguments to generic type qualifying static reference: '" + declaration.getName(unit) + "' declares type parameters " + typeParameterList(declaration));
        }
    }
    Tree.Primary primary = that.getPrimary();
    if (!that.getDirectlyInvoked() && (member.isStatic() || isConstructor(member)) && primary instanceof Tree.StaticMemberOrTypeExpression) {
        Tree.StaticMemberOrTypeExpression smte = (Tree.StaticMemberOrTypeExpression) primary;
        Declaration qualifyingType = smte.getDeclaration();
        Tree.TypeArguments qtas = smte.getTypeArguments();
        if (qualifyingType != null && qualifyingType.isParameterized() && !qualifyingType.isJava() && !explicitTypeArguments(qualifyingType, qtas)) {
            if (explicitTypeArguments(member, tas)) {
                Type functionType = genericFunctionType(qualifyingType, that.getScope(), member, that.getTarget(), unit);
                that.setTypeModel(functionType);
                checkNotJvm(that, "type functions are not supported on the JVM: '" + qualifyingType.getName(unit) + "' is generic (specify explicit type arguments)");
            } else {
                that.addError("missing explicit type arguments to generic qualifying type: '" + qualifyingType.getName(unit) + "' declares type parameters " + typeParameterList(qualifyingType));
            }
        }
    }
}
Also used : ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)

Example 3 with Tree

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree 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)

Example 4 with Tree

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree in project ceylon by eclipse.

the class ExpressionVisitor method visit.

/**
 * Typecheck an invocation expression. Note that this
 * is a tricky process involving type argument inference,
 * anonymous function parameter type inference, function
 * reference type argument inference, Java overload
 * resolution, and argument type checking, and it all
 * has to happen in exactly the right order, which is
 * not at all the natural order for walking the tree.
 */
@Override
public void visit(Tree.InvocationExpression that) {
    // assign some provisional argument types
    // that will help with overload resolution
    visitInvocationPositionalArgs(that);
    // make a first attempt at resolving the
    // invoked reference (but we don't have
    // all the needed types yet)
    Tree.Primary p = that.getPrimary();
    p.visit(this);
    // set up the parameter lists of all
    // argument anonymous functions with
    // inferred (missing) parameter lists
    createAnonymousFunctionParameters(that);
    // named argument lists are the easy
    // case because they don't support
    // anonymous functions with inferred
    // parameter lists
    Tree.NamedArgumentList nal = that.getNamedArgumentList();
    if (nal != null) {
        inferParameterTypes(p, nal);
        nal.visit(this);
    }
    Tree.PositionalArgumentList pal = that.getPositionalArgumentList();
    int argCount = 0;
    boolean[] delayed = null;
    if (pal != null) {
        List<PositionalArgument> args = pal.getPositionalArguments();
        argCount = args.size();
        // infer parameter types as far as we
        // can without having the inferred type
        // parameters of the primary
        delayed = inferParameterTypes(p, pal, false);
        // which parameter type inference failed
        for (int j = 0; j < argCount; j++) {
            if (!delayed[j]) {
                Tree.PositionalArgument pa = args.get(j);
                if (pa != null) {
                    pa.visit(this);
                }
            }
        }
    }
    // assign some additional types that
    // we will use for overload resolution
    visitInvocationPositionalArgs(that);
    // now here's where overloading is
    // finally resolved and then type
    // argments are inferred
    visitInvocationPrimary(that);
    if (pal != null) {
        List<PositionalArgument> args = pal.getPositionalArguments();
        // now infer the remaining parameter
        // types
        inferParameterTypes(p, pal, true);
        // missed the first time round
        for (int j = 0; j < argCount; j++) {
            if (delayed[j]) {
                Tree.PositionalArgument pa = args.get(j);
                if (pa != null) {
                    pa.visit(this);
                }
            }
        }
    }
    // assignable to parameters)
    if (isIndirectInvocation(that)) {
        visitIndirectInvocation(that);
    } else {
        visitDirectInvocation(that);
    }
}
Also used : CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint)

Example 5 with Tree

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree in project ceylon by eclipse.

the class TypeUtils method encodeParameterListForRuntime.

public static void encodeParameterListForRuntime(final boolean resolveTargs, final Node n, final ParameterList plist, final GenerateJsVisitor gen) {
    boolean first = true;
    gen.out("[");
    Map<String, Tree.Parameter> treeParams = new HashMap<>();
    // Map of the parameters in the tree
    if (n instanceof Tree.AnyMethod) {
        for (Tree.ParameterList tplist : ((Tree.AnyMethod) n).getParameterLists()) {
            for (Tree.Parameter tparm : tplist.getParameters()) {
                if (tparm.getParameterModel() != null && tparm.getParameterModel().getName() != null) {
                    treeParams.put(tparm.getParameterModel().getName(), tparm);
                }
            }
        }
    }
    for (Parameter p : plist.getParameters()) {
        if (first)
            first = false;
        else
            gen.out(",");
        gen.out("{", MetamodelGenerator.KEY_NAME, ":'", p.getName(), "',");
        gen.out(MetamodelGenerator.KEY_METATYPE, ":'", MetamodelGenerator.METATYPE_PARAMETER, "',");
        Type ptype = p.getType();
        if (p.getModel() instanceof Function) {
            gen.out("$pt:'f',");
            ptype = ((Function) p.getModel()).getTypedReference().getFullType();
        }
        if (p.isSequenced()) {
            if (p.isAtLeastOne()) {
                gen.out("seq:2,");
            } else {
                gen.out("seq:1,");
            }
        }
        if (p.isDefaulted()) {
            gen.out(MetamodelGenerator.KEY_DEFAULT, ":1,");
        }
        gen.out(MetamodelGenerator.KEY_TYPE, ":");
        metamodelTypeNameOrList(resolveTargs, n, gen.getCurrentPackage(), ptype, null, gen);
        if (p.getModel() instanceof Function) {
            gen.out(",", MetamodelGenerator.KEY_RETURN_TYPE, ":");
            metamodelTypeNameOrList(resolveTargs, n, gen.getCurrentPackage(), p.getType(), null, gen);
            gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
            encodeParameterListForRuntime(resolveTargs, n, ((Function) p.getModel()).getFirstParameterList(), gen);
        }
        Tree.Parameter tparm = p.getName() == null ? null : treeParams.get(p.getName());
        if (tparm == null) {
            if (p.getModel().getAnnotations() != null && !p.getModel().getAnnotations().isEmpty()) {
                new ModelAnnotationGenerator(gen, p.getModel(), n).generateAnnotations();
            }
        } else if (tparm instanceof Tree.ParameterDeclaration) {
            Tree.TypedDeclaration tdec = ((Tree.ParameterDeclaration) tparm).getTypedDeclaration();
            if (tdec.getAnnotationList() != null && !tdec.getAnnotationList().getAnnotations().isEmpty()) {
                outputAnnotationsFunction(tdec.getAnnotationList(), p.getDeclaration(), gen);
            }
        }
        gen.out("}");
    }
    gen.out("]");
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) HashMap(java.util.HashMap) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Aggregations

Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)7 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)3 Expression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression)3 Function (org.eclipse.ceylon.model.typechecker.model.Function)2 Type (org.eclipse.ceylon.model.typechecker.model.Type)2 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)2 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)2 HashMap (java.util.HashMap)1 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)1 AnalyzerUtil.checkCasesDisjoint (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint)1 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)1 AnalyzerUtil.getPackageTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration)1 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)1 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)1 AnalyzerUtil.getTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration)1 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)1 BaseMemberExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression)1 ClassDefinition (org.eclipse.ceylon.compiler.typechecker.tree.Tree.ClassDefinition)1 IndexExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.IndexExpression)1 InvocationExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.InvocationExpression)1