Search in sources :

Example 81 with Constructor

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

the class CeylonVisitor method visit.

public void visit(Tree.ClassBody that) {
    // Transform executable statements and declarations in the body
    // except constructors. Record how constructors delegate.
    HashMap<Constructor, CtorDelegation> delegates = new HashMap<Constructor, CtorDelegation>();
    java.util.List<Statement> stmts = getBodyStatements(that);
    HashMap<Constructor, CtorDelegation> broken = new HashMap<Constructor, CtorDelegation>();
    for (Tree.Statement stmt : stmts) {
        if (stmt instanceof Tree.Constructor) {
            Tree.Constructor ctor = (Tree.Constructor) stmt;
            Constructor ctorModel = ctor.getConstructor();
            if (gen.errors().hasDeclarationAndMarkBrokenness(ctor) instanceof Drop) {
                broken.put(ctorModel, CtorDelegation.brokenDelegation(ctorModel));
                continue;
            }
            classBuilder.getInitBuilder().constructor(ctor);
            if (ctor.getDelegatedConstructor() != null) {
                // error recovery
                if (ctor.getDelegatedConstructor().getInvocationExpression() != null) {
                    Tree.ExtendedTypeExpression p = (Tree.ExtendedTypeExpression) ctor.getDelegatedConstructor().getInvocationExpression().getPrimary();
                    Declaration delegatedDecl = p.getDeclaration();
                    delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
                }
            } else {
                // implicitly delegating to superclass initializer
                Type et = ModelUtil.getConstructedClass(ctorModel).getExtendedType();
                if (et != null) {
                    Declaration delegatedDecl = et.getDeclaration();
                    delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
                }
            }
        } else if (stmt instanceof Tree.Enumerated) {
            Tree.Enumerated singleton = (Tree.Enumerated) stmt;
            Constructor ctorModel = singleton.getEnumerated();
            if (gen.errors().hasDeclarationAndMarkBrokenness(singleton) instanceof Drop) {
                broken.put(ctorModel, CtorDelegation.brokenDelegation(ctorModel));
                continue;
            }
            classBuilder.getInitBuilder().singleton(singleton);
            if (singleton.getDelegatedConstructor() != null) {
                Tree.ExtendedTypeExpression p = (Tree.ExtendedTypeExpression) singleton.getDelegatedConstructor().getInvocationExpression().getPrimary();
                Declaration delegatedDecl = p.getDeclaration();
                delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
            } else {
                // implicitly delegating to superclass initializer
                Type et = ModelUtil.getConstructedClass(ctorModel).getExtendedType();
                if (et != null) {
                    Declaration delegatedDecl = et.getDeclaration();
                    delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
                }
            }
        } else if (stmt instanceof Tree.SpecifierStatement && ((Tree.SpecifierStatement) stmt).getRefinement()) {
            HasErrorException error = gen.errors().getFirstErrorBlock(stmt);
            if (error != null) {
                classBuilder.broken();
            }
            stmt.visit(this);
        } else {
            HasErrorException error = gen.errors().getFirstErrorInitializer(stmt);
            if (error != null) {
                append(gen.makeThrowUnresolvedCompilationError(error));
            } else {
                stmt.visit(this);
            }
        }
    }
    // Now transform constructors
    for (Tree.Statement stmt : stmts) {
        if (stmt instanceof Tree.Constructor) {
            Tree.Constructor ctor = (Tree.Constructor) stmt;
            if (gen.errors().hasDeclarationError(ctor) instanceof Drop) {
                continue;
            }
            transformConstructor(ctor, ctor.getParameterList(), ctor.getDelegatedConstructor(), ctor.getBlock(), ctor.getConstructor(), delegates);
        } else if (stmt instanceof Tree.Enumerated) {
            Tree.Enumerated ctor = (Tree.Enumerated) stmt;
            if (gen.errors().hasDeclarationError(ctor) instanceof Drop) {
                continue;
            }
            transformSingletonConstructor(delegates, ctor);
        }
    }
}
Also used : HashMap(java.util.HashMap) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Statement(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Drop(org.eclipse.ceylon.compiler.java.codegen.recovery.Drop) Type(org.eclipse.ceylon.model.typechecker.model.Type) Statement(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 82 with Constructor

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

the class ExpressionTransformer method transformQualifiedMemberPrimary.

JCExpression transformQualifiedMemberPrimary(Tree.QualifiedMemberOrTypeExpression expr) {
    Declaration exprDec = expr.getDeclaration();
    if (expr.getTarget() == null)
        return makeErroneous(expr, "compiler bug: " + // make sure we don't die of a missing declaration too
        (exprDec != null ? exprDec.getName() : expr) + " has a null target");
    // do not consider the primary to be an invocation since in foo.x() we're invoking x, not foo.
    boolean previousWithinInvocation = withinInvocation(false);
    try {
        // consider package qualifiers as non-prefixed, we always qualify them anyways, this is
        // only useful for the typechecker resolving
        Tree.Primary primary = expr.getPrimary();
        if (Decl.isConstructor(exprDec)) {
            // Constructor ctor = Decl.getConstructor(expr.getDeclaration());
            if (primary instanceof Tree.QualifiedMemberOrTypeExpression) {
                // foo.Class.Ctor => foo
                primary = ((Tree.QualifiedMemberOrTypeExpression) primary).getPrimary();
            } else if (primary instanceof Tree.BaseMemberExpression) {
            // foo.member.Ctor => foo
            } else if (primary instanceof Tree.BaseTypeExpression) {
                // Class.Ctor => null
                return null;
            }
        }
        if (isPackage(primary))
            return null;
        Type type = expr.getTarget().getQualifyingType();
        if (expr.getMemberOperator() instanceof Tree.SafeMemberOp && !isOptional(type)) {
            Type optionalType = typeFact().getOptionalType(type);
            if (optionalType.isCached()) {
                optionalType = optionalType.clone();
            }
            optionalType.setUnderlyingType(type.getUnderlyingType());
            type = optionalType;
        }
        BoxingStrategy boxing = expr.getMemberOperator() instanceof Tree.SafeMemberOp == false && Decl.isValueTypeDecl(primary) && CodegenUtil.isUnBoxed(primary) ? BoxingStrategy.UNBOXED : BoxingStrategy.BOXED;
        JCExpression result;
        if (isSuper(primary)) {
            result = transformSuper(expr);
        } else if (isSuperOf(primary)) {
            result = transformSuperOf(expr, expr.getPrimary(), exprDec.getName());
        } else if (isThis(primary) && !exprDec.isCaptured() && !exprDec.isShared() && Decl.getDeclarationScope(expr.getScope()) instanceof Constructor) {
            result = null;
        } else if (Decl.isJavaStaticOrInterfacePrimary(primary)) {
            // Java static field or method access
            result = transformJavaStaticOrInterfaceMember((Tree.QualifiedMemberOrTypeExpression) primary, expr.getTypeModel());
        } else {
            result = transformExpression(primary, boxing, type);
        }
        return result;
    } finally {
        withinInvocation(previousWithinInvocation);
    }
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) 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) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) 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 83 with Constructor

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

the class Decl method isPrivateAccessRequiringUpcast.

/**
 * Is the member private and not visible from the primary (i.e. is an
 * upcast required to be able to see that member)
 */
public static boolean isPrivateAccessRequiringUpcast(Tree.StaticMemberOrTypeExpression qual) {
    if (qual instanceof Tree.QualifiedMemberOrTypeExpression) {
        Tree.Primary primary = ((Tree.QualifiedMemberOrTypeExpression) qual).getPrimary();
        Declaration decl = qual.getDeclaration();
        return decl.isMember() && !decl.isShared() && !(decl instanceof Constructor) && decl.getContainer() instanceof Class && !Decl.hasScopeInType(decl.getContainer(), primary.getTypeModel());
    }
    return false;
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) 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) AttributeDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)

Example 84 with Constructor

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

the class FunctionHelper method generateCallable.

static void generateCallable(final Tree.QualifiedMemberOrTypeExpression that, String name, final GenerateJsVisitor gen) {
    final Declaration d = that.getDeclaration();
    if (that.getPrimary() instanceof Tree.BaseTypeExpression) {
        // it's a static method ref
        if (name == null) {
            name = gen.memberAccess(that, "");
        }
        if (ModelUtil.isConstructor(d)) {
            Constructor cd = TypeUtils.getConstructor(d);
            final boolean hasTargs = BmeGenerator.hasTypeParameters((Tree.BaseTypeExpression) that.getPrimary());
            if (hasTargs) {
                if (that.getDirectlyInvoked()) {
                    gen.out(gen.qualifiedPath(that, cd), gen.getNames().constructorSeparator(cd), gen.getNames().name(cd));
                } else {
                    BmeGenerator.printGenericMethodReference(gen, (Tree.BaseTypeExpression) that.getPrimary(), "0", gen.qualifiedPath(that, cd) + gen.getNames().constructorSeparator(cd) + gen.getNames().name(cd));
                }
            } else {
                gen.qualify(that, cd);
                gen.out(gen.getNames().name(cd));
                if (cd.isValueConstructor()) {
                    gen.out("()");
                }
            }
        } else if (d.isStatic()) {
            BmeGenerator.generateStaticReference(that, d, gen);
        } else {
            gen.out("function(x){return ");
            if (BmeGenerator.hasTypeParameters(that)) {
                BmeGenerator.printGenericMethodReference(gen, that, "x", "x." + name);
            } else {
                gen.out(gen.getClAlias(), "jsc$3(x,x.", name, ")");
            }
            gen.out(";}");
        }
        return;
    }
    if (d.isToplevel() && d instanceof Function) {
        // Just output the name
        gen.out(gen.getNames().name(d));
        return;
    }
    String primaryVar = gen.createRetainedTempVar();
    gen.out("(", primaryVar, "=");
    that.getPrimary().visit(gen);
    if (!(that.getStaticMethodReferencePrimary() && !ModelUtil.isConstructor(that.getDeclaration()))) {
        gen.out(",");
        final String member = (name == null) ? gen.memberAccess(that, primaryVar) : (primaryVar + "." + name);
        if (that.getDeclaration() instanceof Function && !((Function) that.getDeclaration()).getTypeParameters().isEmpty()) {
            // Function ref with type parameters
            BmeGenerator.printGenericMethodReference(gen, that, primaryVar, member);
        } else {
            if (that.getUnit().isOptionalType(that.getPrimary().getTypeModel())) {
                gen.out(gen.getClAlias(), "jsc$3(", primaryVar, ",", gen.getClAlias(), "nn$(", primaryVar, ")?", member, ":null)");
            } else {
                gen.out(gen.getClAlias(), "jsc$3(", primaryVar, ",", member, ")");
            }
        }
    }
    gen.out(")");
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 85 with Constructor

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

the class GenerateJsVisitor method assignment.

private void assignment(final TypeDeclaration outer, final Declaration d, final Tree.Expression expr) {
    FunctionOrValue vdec = (FunctionOrValue) d;
    final String atname = names.valueName(vdec);
    if (outer instanceof Constructor) {
        if (d.isClassOrInterfaceMember()) {
            out(names.self(outer), ".", atname, "=");
        } else {
            out(names.name(d), "=");
        }
        expr.visit(this);
        endLine(true);
    }
    if (d.isClassOrInterfaceMember()) {
        defineAttribute(names.self(outer), names.name(d));
        out("{");
        if (vdec.isLate()) {
            generateUnitializedAttributeReadCheck("this." + atname, names.name(d), null);
        }
        out("return this.", atname, ";}");
        if (vdec.isVariable() || vdec.isLate()) {
            final String par = getNames().createTempVariable();
            out(",function(", par, "){");
            generateImmutableAttributeReassignmentCheck(vdec, "this." + atname, names.name(d));
            out("return this.", atname, "=", par, ";}");
        } else {
            out(",undefined");
        }
        out(",");
        TypeUtils.encodeForRuntime(expr, d, this);
        out(")");
        endLine(true);
    }
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Aggregations

Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)95 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)65 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)48 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)47 Type (org.eclipse.ceylon.model.typechecker.model.Type)45 Class (org.eclipse.ceylon.model.typechecker.model.Class)42 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)42 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)27 Value (org.eclipse.ceylon.model.typechecker.model.Value)27 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)26 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)25 Function (org.eclipse.ceylon.model.typechecker.model.Function)23 ModelUtil.isConstructor (org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor)21 ArrayList (java.util.ArrayList)20 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)19 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)17 AnalyzerUtil.unwrapAliasedTypeConstructor (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor)16 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)14 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)14