use of org.eclipse.ceylon.model.typechecker.model.ClassAlias in project ceylon by eclipse.
the class DeclarationVisitor method visit.
@Override
public void visit(Tree.Parameter that) {
super.visit(that);
Tree.SpecifierOrInitializerExpression sie = null;
if (that instanceof Tree.ParameterDeclaration) {
Tree.ParameterDeclaration pd = (Tree.ParameterDeclaration) that;
Tree.TypedDeclaration td = pd.getTypedDeclaration();
if (td instanceof Tree.AttributeDeclaration) {
Tree.AttributeDeclaration ad = (Tree.AttributeDeclaration) td;
sie = ad.getSpecifierOrInitializerExpression();
} else if (td instanceof Tree.MethodDeclaration) {
Tree.MethodDeclaration md = (Tree.MethodDeclaration) td;
sie = md.getSpecifierExpression();
}
} else if (that instanceof Tree.InitializerParameter) {
Tree.InitializerParameter ip = (Tree.InitializerParameter) that;
sie = ip.getSpecifierExpression();
}
if (sie != null) {
if (scope instanceof ClassAlias) {
sie.addUnsupportedError("defaulted parameters are not yet supported for class aliases");
}
new Visitor() {
public void visit(Tree.AssignmentOp that) {
that.addError("assignment may not occur in default argument expression");
}
@Override
public void visit(Tree.PostfixOperatorExpression that) {
that.addError("postfix increment or decrement may not occur in default argument expression");
}
@Override
public void visit(Tree.PrefixOperatorExpression that) {
that.addError("prefix increment or decrement may not occur in default argument expression");
}
}.visit(sie);
}
}
use of org.eclipse.ceylon.model.typechecker.model.ClassAlias in project ceylon by eclipse.
the class DeclarationVisitor method visit.
@Override
public void visit(Tree.ClassDeclaration that) {
Class c = new ClassAlias();
that.setDeclarationModel(c);
super.visit(that);
if (that.getParameterList() == null) {
that.addError("class alias must have a parameter list");
}
}
use of org.eclipse.ceylon.model.typechecker.model.ClassAlias in project ceylon by eclipse.
the class ClassTransformer method transform.
public List<JCTree> transform(final Tree.ClassOrInterface def) {
final ClassOrInterface model = def.getDeclarationModel();
if (model.isToplevel() && isEe(model)) {
replaceModifierTransformation(new EeModifierTransformation());
}
// in that case
if (model.isAlias() && Decl.isAncestorLocal(model))
return List.nil();
naming.clearSubstitutions(model);
final String javaClassName;
String ceylonClassName = def.getIdentifier().getText();
if (def instanceof Tree.AnyInterface) {
javaClassName = naming.makeTypeDeclarationName(model, QUALIFIED).replaceFirst(".*\\.", "");
} else {
javaClassName = Naming.quoteClassName(ceylonClassName);
}
ClassDefinitionBuilder instantiatorImplCb;
ClassDefinitionBuilder instantiatorDeclCb;
if (model.isInterfaceMember()) {
instantiatorImplCb = gen().current().getCompanionBuilder((Interface) model.getContainer());
instantiatorDeclCb = gen().current();
} else {
instantiatorImplCb = gen().current();
instantiatorDeclCb = null;
}
ClassDefinitionBuilder classBuilder = ClassDefinitionBuilder.klass(this, javaClassName, ceylonClassName, Decl.isLocal(model)).forDefinition(model).hasDelegatingConstructors(CodegenUtil.hasDelegatingConstructors(def));
classBuilder.getInitBuilder().deprecated(model.isDeprecated());
// Very special case for Anything
if (model.isAnything()) {
classBuilder.extending(model.getType(), null);
}
if (def instanceof Tree.AnyClass) {
classBuilder.getInitBuilder().modifiers(modifierTransformation().constructor(model));
Tree.AnyClass classDef = (Tree.AnyClass) def;
Class cls = classDef.getDeclarationModel();
// Member classes need a instantiator method
boolean generateInstantiator = Strategy.generateInstantiator(cls);
if (!cls.hasConstructors()) {
classBuilder.getInitBuilder().userAnnotations(expressionGen().transformAnnotations(OutputElement.CONSTRUCTOR, def));
}
if (generateInstantiator && !cls.hasConstructors() && !cls.hasEnumerated()) {
if (!cls.isStatic()) {
classBuilder.getInitBuilder().modifiers(PROTECTED);
}
generateInstantiators(classBuilder, cls, null, instantiatorDeclCb, instantiatorImplCb, classDef, classDef.getParameterList());
}
classBuilder.annotations(expressionGen().transformAnnotations(OutputElement.TYPE, def));
if (def instanceof Tree.ClassDefinition) {
transformClass((Tree.ClassDefinition) def, cls, classBuilder, classDef.getParameterList(), generateInstantiator, instantiatorDeclCb, instantiatorImplCb);
} else {
// class alias
classBuilder.getInitBuilder().modifiers(PRIVATE);
transformClassAlias((Tree.ClassDeclaration) def, classBuilder);
}
addMissingUnrefinedMembers(def, cls, classBuilder);
}
if (def instanceof Tree.AnyInterface) {
classBuilder.annotations(expressionGen().transformAnnotations(OutputElement.TYPE, def));
if (def instanceof Tree.InterfaceDefinition) {
transformInterface(def, (Interface) model, classBuilder);
} else {
// interface alias
classBuilder.annotations(makeAtAlias(model.getExtendedType(), null));
classBuilder.isAlias(true);
}
classBuilder.isDynamic(model.isDynamic());
}
// make sure we set the container in case we move it out
addAtContainer(classBuilder, model);
transformTypeParameters(classBuilder, model);
// Transform the class/interface members
List<JCStatement> childDefs = visitClassOrInterfaceDefinition(def, classBuilder);
// everything else is synthetic
at(null);
TransformationPlan plan = errors().hasDeclarationError(def);
if (plan instanceof ThrowerCatchallConstructor) {
classBuilder.broken();
MethodDefinitionBuilder initBuilder = classBuilder.noInitConstructor().addConstructor(model.isDeprecated());
initBuilder.body(statementGen().makeThrowUnresolvedCompilationError(plan.getErrorMessage().getMessage()));
// Although we have the class pl which we could use we don't know
// that it won't collide with the default named constructor's pl
// which would cause a javac error about two constructors with the same sig
// so we generate a Object... here. There's still a risk of collision though
// when the default constructor has pl (ObjectArray).
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.implicitParameter(this, "ignored");
pdb.modifiers(VARARGS);
pdb.type(new TransformedType(make().TypeArray(make().Type(syms().objectType))));
initBuilder.parameter(pdb);
} else if (plan instanceof PrivateConstructorOnly) {
classBuilder.broken();
MethodDefinitionBuilder initBuilder = classBuilder.noInitConstructor().addConstructor(model.isDeprecated());
initBuilder.body(statementGen().makeThrowUnresolvedCompilationError(plan.getErrorMessage().getMessage()));
initBuilder.modifiers(PRIVATE);
}
// If it's a Class without initializer parameters...
if (Strategy.generateMain(def)) {
// ... then add a main() method
classBuilder.method(makeMainForClass(model));
}
classBuilder.modelAnnotations(model.getAnnotations()).modifiers(modifierTransformation().classFlags(model)).satisfies(model.getSatisfiedTypes()).caseTypes(model.getCaseTypes(), model.getSelfType()).defs(childDefs);
// aliases and native headers don't need a $getType method
if (!model.isAlias()) {
// only classes get a $getType method
if (model instanceof Class)
classBuilder.addGetTypeMethod(model.getType());
if (supportsReifiedAlias(model))
classBuilder.reifiedAlias(model.getType());
}
// we can add things which depend on knowing all the fields
if (Strategy.generateJpaCtor(model) && plan instanceof Generate) {
buildJpaConstructor((Class) model, classBuilder);
}
if (model instanceof Class && !(model instanceof ClassAlias) && plan instanceof Generate) {
Class c = (Class) model;
if (Strategy.introduceJavaIoSerializable(c, typeFact().getJavaIoSerializable())) {
classBuilder.introduce(make().QualIdent(syms().serializableType.tsym));
if (Strategy.useSerializationProxy(c) && noValueConstructorErrors((Tree.ClassDefinition) def)) {
at(def);
addWriteReplace(c, classBuilder);
}
}
serialization(c, classBuilder);
}
// reset position before initializer constructor is generated.
at(def);
classBuilder.at(def);
List<JCTree> result;
if (Decl.isAnnotationClass(def.getDeclarationModel())) {
ListBuffer<JCTree> trees = new ListBuffer<JCTree>();
trees.addAll(transformAnnotationClass((Tree.AnyClass) def));
transformAnnotationClassConstructor((Tree.AnyClass) def, classBuilder);
// you only need that method if you satisfy Annotation which is erased to j.l.a.Annotation
if (model.inherits(typeFact().getAnnotationDeclaration()))
classBuilder.addAnnotationTypeMethod(model.getType());
trees.addAll(classBuilder.build());
result = trees.toList();
} else {
result = classBuilder.build();
}
if (model.isToplevel() && isEe(model)) {
replaceModifierTransformation(new ModifierTransformation());
}
return result;
}
use of org.eclipse.ceylon.model.typechecker.model.ClassAlias in project ceylon by eclipse.
the class ClassTransformer method transformClassAlias.
private void transformClassAlias(final Tree.ClassDeclaration def, ClassDefinitionBuilder classBuilder) {
ClassAlias model = (ClassAlias) def.getDeclarationModel();
Type aliasedClass = model.getExtendedType();
TypeDeclaration classOrCtor = def.getClassSpecifier().getType().getDeclarationModel();
while (classOrCtor instanceof ClassAlias) {
classOrCtor = ((ClassAlias) classOrCtor).getConstructor();
}
classBuilder.annotations(makeAtAlias(aliasedClass, classOrCtor instanceof Constructor ? (Constructor) classOrCtor : null));
classBuilder.isAlias(true);
MethodDefinitionBuilder instantiator = transformClassAliasInstantiator(def, model, aliasedClass);
ClassDefinitionBuilder cbInstantiator = null;
switch(Strategy.defaultParameterMethodOwner(model)) {
case STATIC:
cbInstantiator = classBuilder;
break;
case OUTER:
cbInstantiator = classBuilder.getContainingClassBuilder();
break;
case OUTER_COMPANION:
cbInstantiator = classBuilder.getContainingClassBuilder().getCompanionBuilder(ModelUtil.getClassOrInterfaceContainer(model, true));
break;
default:
throw BugException.unhandledEnumCase(Strategy.defaultParameterMethodOwner(model));
}
cbInstantiator.method(instantiator);
}
use of org.eclipse.ceylon.model.typechecker.model.ClassAlias in project ceylon by eclipse.
the class ClassTransformer method makeMainForClass.
/**
* Makes a {@code main()} method which calls the given top-level method
* @param def
*/
private MethodDefinitionBuilder makeMainForClass(ClassOrInterface model) {
at(null);
List<JCExpression> arguments = List.nil();
if (model.isAlias()) {
TypeDeclaration constr = ((ClassAlias) model).getConstructor();
if (constr instanceof Constructor) {
// must pass the constructor name arg
arguments = List.of(naming.makeNamedConstructorName((Constructor) constr, false));
}
model = (ClassOrInterface) model.getExtendedType().getDeclaration();
}
JCExpression nameId = makeJavaType(model.getType(), JT_RAW);
arguments = makeBottomReifiedTypeParameters(model.getTypeParameters(), arguments);
JCNewClass expr = make().NewClass(null, null, nameId, arguments, null);
return makeMainMethod(model, expr);
}
Aggregations