Search in sources :

Example 26 with Setter

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

the class ClassTransformer method addAmbiguousMember.

private void addAmbiguousMember(ClassDefinitionBuilder classBuilder, Interface model, String name) {
    Declaration member = model.getMember(name, null, false);
    Type satisfiedType = model.getType().getSupertype(model);
    if (member instanceof Class) {
        Class klass = (Class) member;
        if (Strategy.generateInstantiator(member) && !klass.hasConstructors()) {
            // instantiator method implementation
            generateInstantiatorDelegate(classBuilder, satisfiedType, model, klass, null, model.getType(), false);
        }
        if (klass.hasConstructors()) {
            for (Declaration m : klass.getMembers()) {
                if (m instanceof Constructor && Strategy.generateInstantiator(m)) {
                    Constructor ctor = (Constructor) m;
                    generateInstantiatorDelegate(classBuilder, satisfiedType, model, klass, ctor, model.getType(), false);
                }
            }
        }
    } else if (member instanceof Function) {
        Function method = (Function) member;
        final TypedReference typedMember = satisfiedType.getTypedMember(method, Collections.<Type>emptyList());
        java.util.List<java.util.List<Type>> producedTypeParameterBounds = producedTypeParameterBounds(typedMember, method);
        final java.util.List<TypeParameter> typeParameters = method.getTypeParameters();
        final java.util.List<Parameter> parameters = method.getFirstParameterList().getParameters();
        for (Parameter param : parameters) {
            if (Strategy.hasDefaultParameterOverload(param)) {
                MethodDefinitionBuilder overload = new DefaultedArgumentMethodTyped(null, MethodDefinitionBuilder.method(this, method), typedMember, true).makeOverload(method.getFirstParameterList(), param, typeParameters);
                overload.modifiers(PUBLIC | ABSTRACT);
                classBuilder.method(overload);
            }
        }
        final MethodDefinitionBuilder concreteMemberDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, method.getTypeParameters(), producedTypeParameterBounds, typedMember.getType(), naming.selector(method), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), null, null, false);
        classBuilder.method(concreteMemberDelegate);
    } else if (member instanceof Value || member instanceof Setter) {
        TypedDeclaration attr = (TypedDeclaration) member;
        final TypedReference typedMember = satisfiedType.getTypedMember(attr, Collections.<Type>emptyList());
        if (member instanceof Value) {
            final MethodDefinitionBuilder getterDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typedMember.getType(), Naming.getGetterName(attr), Collections.<Parameter>emptyList(), attr.getTypeErased(), null, null, false);
            classBuilder.method(getterDelegate);
        }
        if (member instanceof Setter) {
            final MethodDefinitionBuilder setterDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typeFact().getAnythingType(), Naming.getSetterName(attr), Collections.<Parameter>singletonList(((Setter) member).getParameter()), ((Setter) member).getTypeErased(), null, null, false);
            classBuilder.method(setterDelegate);
        }
    }
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) ThrowerCatchallConstructor(org.eclipse.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) ArrayList(java.util.ArrayList) AnnotationList(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)

Example 27 with Setter

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

the class CeylonTransformer method transformAttribute.

public List<JCTree> transformAttribute(TypedDeclaration declarationModel, String attrName, String attrClassName, final Tree.Declaration annotated, final Tree.Block block, final Tree.SpecifierOrInitializerExpression expression, final Tree.TypedDeclaration decl, final Tree.AttributeSetterDefinition setterDecl) {
    // For everything else generate a getter/setter method
    ClassDefinitionBuilder classBuilder = ClassDefinitionBuilder.klass(this, attrClassName, null, false);
    final HasErrorException expressionError;
    if (expression != null) {
        expressionError = errors().getFirstExpressionErrorAndMarkBrokenness(expression.getExpression());
    } else {
        expressionError = null;
    }
    BoxingStrategy boxingStrategy = null;
    final JCExpression initialValue;
    if (expressionError != null) {
        initialValue = make().Erroneous();
    } else {
        if (Decl.isNonTransientValue(declarationModel) && !(expression instanceof Tree.LazySpecifierExpression)) {
            if (expression != null) {
                boxingStrategy = useJavaBox(declarationModel, declarationModel.getType()) && javaBoxExpression(expression.getExpression().getTypeModel(), declarationModel.getType()) ? BoxingStrategy.JAVA : CodegenUtil.getBoxingStrategy(declarationModel);
                initialValue = expressionGen().transform(expression, boxingStrategy, declarationModel.getType());
            } else {
                Parameter p = CodegenUtil.findParamForDecl(attrName, declarationModel);
                if (p != null) {
                    boxingStrategy = CodegenUtil.getBoxingStrategy(p.getModel());
                    initialValue = naming.makeName(p.getModel(), Naming.NA_MEMBER | Naming.NA_ALIASED);
                } else {
                    initialValue = null;
                }
            }
        } else {
            initialValue = null;
        }
    }
    boolean memoized = declarationModel.isLate() && expression != null;
    AttributeDefinitionBuilder builder = AttributeDefinitionBuilder.wrapped(this, attrName, declarationModel, declarationModel.isToplevel(), memoized ? initialValue : null);
    builder.is(Flags.PUBLIC, declarationModel.isShared());
    if (isJavaStrictfp(declarationModel)) {
        builder.is(Flags.STRICTFP, true);
    }
    if (isJavaSynchronized(declarationModel)) {
        builder.is(Flags.SYNCHRONIZED, true);
    }
    if (isJavaNative(declarationModel)) {
        builder.is(Flags.NATIVE, true);
        builder.isJavaNative(true);
    }
    // For captured local variable Values, use a VariableBox
    if (Decl.isBoxedVariable(declarationModel)) {
        classBuilder.restoreClassBuilder();
        if (expressionError != null) {
            return List.<JCTree>of(this.makeThrowUnresolvedCompilationError(expressionError));
        } else {
            return List.<JCTree>of(makeVariableBoxDecl(initialValue, declarationModel));
        }
    }
    // For late-bound getters we only generate a declaration
    if (block == null && expression == null && !declarationModel.isToplevel()) {
        JCExpression typeExpr = makeJavaType(getGetterInterfaceType(declarationModel));
        JCTree.JCVariableDecl var = makeVar(attrClassName, typeExpr, null);
        classBuilder.restoreClassBuilder();
        return List.<JCTree>of(var);
    }
    // Set the local declarations annotation
    List<JCAnnotation> scopeAnnotations = null;
    if (decl != null) {
        scopeAnnotations = declarationModel.isToplevel() && setterDecl != null ? makeAtLocalDeclarations(decl, setterDecl) : makeAtLocalDeclarations(decl);
    } else if (block != null) {
        scopeAnnotations = makeAtLocalDeclarations(block);
    }
    if (scopeAnnotations != null)
        builder.classAnnotations(scopeAnnotations);
    // Remember the setter class if we generate a getter
    if (Decl.isGetter(declarationModel) && declarationModel.isVariable() && Decl.isLocal(declarationModel)) {
        // we must have a setter class
        Setter setter = ((Value) declarationModel).getSetter();
        if (setter != null) {
            String setterClassName = Naming.getAttrClassName(setter, 0);
            JCExpression setterClassNameExpr = naming.makeUnquotedIdent(setterClassName);
            builder.setterClass(makeSelect(setterClassNameExpr, "class"));
        }
    }
    if (declarationModel instanceof Setter || (declarationModel instanceof FunctionOrValue && ((FunctionOrValue) declarationModel).isParameter())) {
        // For local setters
        JCBlock setterBlock = makeSetterBlock(declarationModel, block, expression);
        builder.setterBlock(setterBlock);
        builder.skipGetter();
        if (Decl.isLocal(decl.getDeclarationModel())) {
            // we need to find back the Setter model for local setters, because
            // in transformAttribute(Tree.TypedDeclaration decl, Tree.AttributeSetterDefinition setterDecl)
            // we turn the declaration model from the Setter to its single parameter
            Setter setter = (Setter) declarationModel.getContainer();
            String getterClassName = Naming.getAttrClassName(setter.getGetter(), 0);
            JCExpression getterClassNameExpr = naming.makeUnquotedIdent(getterClassName);
            builder.isSetter(makeSelect(getterClassNameExpr, "class"));
        }
    } else {
        if (Decl.isValue(declarationModel)) {
            // For local and toplevel value attributes
            if (!declarationModel.isVariable() && !declarationModel.isLate()) {
                builder.immutable();
            }
        } else {
            // For local and toplevel getters
            boolean prevSyntheticClassBody = Decl.isLocal(declarationModel) ? expressionGen().withinSyntheticClassBody(true) : expressionGen().isWithinSyntheticClassBody();
            JCBlock getterBlock = makeGetterBlock(declarationModel, block, expression);
            prevSyntheticClassBody = expressionGen().withinSyntheticClassBody(prevSyntheticClassBody);
            builder.getterBlock(getterBlock);
            if (Decl.isLocal(declarationModel)) {
                // For local getters
                builder.immutable();
            } else {
                // For toplevel getters
                if (setterDecl != null) {
                    JCBlock setterBlock = makeSetterBlock(setterDecl.getDeclarationModel(), setterDecl.getBlock(), setterDecl.getSpecifierExpression());
                    builder.setterBlock(setterBlock);
                    // builder.userAnnotationsSetter(expressionGen().transformAnnotations(true, OutputElement.METHOD, setterDecl));
                    builder.userAnnotationsSetter(expressionGen().transformAnnotations(OutputElement.SETTER, setterDecl));
                } else {
                    builder.immutable();
                }
            }
        }
    }
    if (annotated != null) {
        builder.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, annotated));
        builder.fieldAnnotations(expressionGen().transformAnnotations(OutputElement.FIELD, annotated));
    }
    if (Decl.isLocal(declarationModel)) {
        if (expressionError != null) {
            classBuilder.restoreClassBuilder();
            return List.<JCTree>of(this.makeThrowUnresolvedCompilationError(expressionError));
        }
        builder.classAnnotations(makeAtLocalDeclaration(declarationModel.getQualifier(), false));
        if (initialValue != null)
            builder.valueConstructor();
        JCExpression typeExpr;
        if (declarationModel instanceof Setter || (declarationModel instanceof FunctionOrValue && ((FunctionOrValue) declarationModel).isParameter())) {
            typeExpr = makeQuotedIdent(attrClassName);
        } else {
            typeExpr = makeJavaType(getGetterInterfaceType(declarationModel));
        }
        return builder.buildWithWrapperClass(classBuilder).append(makeLocalIdentityInstance(typeExpr, attrClassName, attrClassName, declarationModel.isShared(), initialValue));
    } else {
        if (expressionError != null) {
            builder.initialValueError(expressionError);
        } else if (!memoized && initialValue != null) {
            builder.initialValue(initialValue, boxingStrategy);
        }
        builder.is(Flags.STATIC, true);
        return builder.buildWithWrapperClass(classBuilder);
    }
}
Also used : JCBlock(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Value(org.eclipse.ceylon.model.typechecker.model.Value) 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) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 28 with Setter

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

the class InterfaceVisitor method visit.

@Override
public void visit(Tree.AttributeSetterDefinition that) {
    Setter model = that.getDeclarationModel();
    // locals and toplevels get a type generated for them
    if (!model.isMember() && !model.isToplevel()) {
        Set<String> old = localCompanionClasses;
        localCompanionClasses = new HashSet<String>();
        super.visit(that);
        localCompanionClasses = old;
    } else {
        super.visit(that);
    }
}
Also used : Setter(org.eclipse.ceylon.model.typechecker.model.Setter)

Example 29 with Setter

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

the class GenerateJsVisitor method visit.

@Override
public void visit(final Tree.AttributeSetterDefinition that) {
    if (errVisitor.hasErrors(that) || !TypeUtils.acceptNative(that))
        return;
    Setter d = that.getDeclarationModel();
    if (opts.isOptimize() && d.isClassOrInterfaceMember() || AttributeGenerator.defineAsProperty(d))
        return;
    comment(that);
    out("function ", names.setter(d.getGetter()), "(", names.name(d.getParameter()), ")");
    AttributeGenerator.setter(that, this);
    if (!shareSetter(d)) {
        out(";");
    }
    if (!d.isToplevel())
        outerSelf(d);
    out(names.setter(d.getGetter()), ".$crtmm$=");
    TypeUtils.encodeForRuntime(that, that.getDeclarationModel(), that.getAnnotationList(), this);
    endLine(true);
    AttributeGenerator.generateAttributeMetamodel(that, false, true, this);
}
Also used : Setter(org.eclipse.ceylon.model.typechecker.model.Setter)

Example 30 with Setter

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

the class AttributeGenerator method generateAttributeMetamodel.

/**
 * Generate runtime metamodel info for an attribute declaration or definition.
 */
static void generateAttributeMetamodel(final Tree.TypedDeclaration that, final boolean addGetter, final boolean addSetter, GenerateJsVisitor gen) {
    // No need to define all this for local values
    Scope _scope = that.getScope();
    while (_scope != null) {
        // TODO this is bound to change for local decl metamodel
        if (_scope instanceof Declaration) {
            if (_scope instanceof Function)
                return;
            else
                break;
        }
        _scope = _scope.getContainer();
    }
    Declaration d = that.getDeclarationModel();
    if (d instanceof Setter)
        d = ((Setter) d).getGetter();
    final String pname = gen.getNames().getter(d, false);
    final String pnameMeta = gen.getNames().getter(d, true);
    if (!gen.isGeneratedAttribute(d)) {
        if (d.isToplevel()) {
            gen.out("var ");
        } else if (gen.outerSelf(d)) {
            // TODO what about statics?
            gen.out(".");
        }
        // issue 297 this is only needed in some cases
        gen.out(pnameMeta, "={$crtmm$:");
        TypeUtils.encodeForRuntime(that, that.getDeclarationModel(), that.getAnnotationList(), gen);
        gen.out("}");
        gen.endLine(true);
        if (d.isToplevel()) {
            gen.out("ex$.", pnameMeta, "=", pnameMeta);
            gen.endLine(true);
        }
        gen.addGeneratedAttribute(d);
    }
    if (addGetter) {
        if (!d.isToplevel()) {
            // TODO what about statics?
            if (gen.outerSelf(d))
                gen.out(".");
        }
        gen.out(pnameMeta, ".get=");
        if (gen.isCaptured(d) && !defineAsProperty(d)) {
            gen.out(pname);
            gen.endLine(true);
            gen.out(pname, ".$crtmm$=", pnameMeta, ".$crtmm$");
        } else {
            if (d.isToplevel()) {
                gen.out(pname);
            } else {
                gen.out("function(){return ", gen.getNames().name(d), "}");
            }
        }
        gen.endLine(true);
    }
    if (addSetter) {
        final String pset = gen.getNames().setter(d instanceof Setter ? ((Setter) d).getGetter() : d);
        if (!d.isToplevel()) {
            // TODO what about statics?
            if (gen.outerSelf(d))
                gen.out(".");
        }
        gen.out(pnameMeta, ".set=", pset);
        gen.endLine(true);
        gen.out("if(", pset, ".$crtmm$===undefined)", pset, ".$crtmm$=", pnameMeta, ".$crtmm$");
        gen.endLine(true);
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Aggregations

Setter (org.eclipse.ceylon.model.typechecker.model.Setter)30 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)18 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)17 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)16 Value (org.eclipse.ceylon.model.typechecker.model.Value)16 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)14 Class (org.eclipse.ceylon.model.typechecker.model.Class)8 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)8 Function (org.eclipse.ceylon.model.typechecker.model.Function)8 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)7 Type (org.eclipse.ceylon.model.typechecker.model.Type)7 ArrayList (java.util.ArrayList)6 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)5 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)5 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)5 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)5 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)4 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)4 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)4 MethodDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)4