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);
}
}
}
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);
}
}
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);
}
}
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);
}
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);
}
}
Aggregations