use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class CeylonTransformer method transformAttributeGetter.
public JCExpression transformAttributeGetter(TypedDeclaration declarationModel, final JCExpression expression) {
final String attrName = declarationModel.getName();
final String attrClassName = Naming.getAttrClassName(declarationModel, 0);
JCBlock getterBlock = makeGetterBlock(expression);
// For everything else generate a getter/setter method
AttributeDefinitionBuilder builder = AttributeDefinitionBuilder.indirect(this, attrClassName, attrName, declarationModel, declarationModel.isToplevel()).getterBlock(getterBlock).immutable();
List<JCTree> attr = builder.build();
JCNewClass newExpr = makeNewClass(attrClassName, false, null);
JCExpression result = makeLetExpr(naming.temp(), List.<JCStatement>of((JCStatement) attr.get(0)), newExpr);
return result;
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class ClassTransformer method transformObject.
private List<JCTree> transformObject(Node def, Tree.Declaration annotated, Tree.SatisfiedTypes satisfiesTypes, Value model, Class klass, ClassDefinitionBuilder containingClassBuilder, boolean makeLocalInstance) {
naming.clearSubstitutions(klass);
String name = klass.getName();
String javaClassName = Naming.quoteClassName(name);
ClassDefinitionBuilder objectClassBuilder = ClassDefinitionBuilder.object(this, javaClassName, name, Decl.isLocal(klass)).forDefinition(klass);
if (Strategy.introduceJavaIoSerializable(klass, typeFact().getJavaIoSerializable())) {
objectClassBuilder.introduce(make().QualIdent(syms().serializableType.tsym));
if (def instanceof Tree.ObjectDefinition && klass.isMember() && (klass.isShared() || klass.isCaptured() || model.isCaptured())) {
addWriteReplace(klass, objectClassBuilder);
}
}
makeReadResolve(objectClassBuilder, klass, model);
// Make sure top types satisfy reified type
addReifiedTypeInterface(objectClassBuilder, klass);
if (supportsReifiedAlias(klass))
objectClassBuilder.reifiedAlias(klass.getType());
CeylonVisitor visitor = gen().visitor;
final ListBuffer<JCTree> prevDefs = visitor.defs;
final boolean prevInInitializer = visitor.inInitializer;
final ClassDefinitionBuilder prevClassBuilder = visitor.classBuilder;
List<JCStatement> childDefs;
try {
visitor.defs = new ListBuffer<JCTree>();
visitor.inInitializer = true;
visitor.classBuilder = objectClassBuilder;
def.visitChildren(visitor);
childDefs = (List<JCStatement>) visitor.getResult().toList();
} finally {
visitor.classBuilder = prevClassBuilder;
visitor.inInitializer = prevInInitializer;
visitor.defs = prevDefs;
}
addMissingUnrefinedMembers(def, klass, objectClassBuilder);
satisfaction(satisfiesTypes, klass, objectClassBuilder);
serialization(klass, objectClassBuilder);
if (model != null && Decl.isToplevel(model) && def instanceof Tree.ObjectDefinition) {
// generate a field and getter
AttributeDefinitionBuilder builder = AttributeDefinitionBuilder.wrapped(this, null, objectClassBuilder, model.getName(), model, true).userAnnotations(makeAtIgnore()).userAnnotationsSetter(makeAtIgnore()).immutable().initialValue(makeNewClass(naming.makeName(model, Naming.NA_FQ | Naming.NA_WRAPPER))).is(PUBLIC, Decl.isShared(klass)).is(STATIC, true);
if (annotated != null) {
builder.fieldAnnotations(expressionGen().transformAnnotations(OutputElement.FIELD, annotated));
builder.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, annotated));
}
objectClassBuilder.defs(builder.build());
}
if (annotated != null) {
objectClassBuilder.annotations(expressionGen().transformAnnotations(OutputElement.TYPE, annotated));
objectClassBuilder.getInitBuilder().userAnnotations(expressionGen().transformAnnotations(OutputElement.CONSTRUCTOR, annotated));
}
// make sure we set the container in case we move it out
addAtContainer(objectClassBuilder, klass);
objectClassBuilder.annotations(makeAtObject()).satisfies(klass.getSatisfiedTypes()).defs((List) childDefs);
objectClassBuilder.getInitBuilder().modifiers(PRIVATE);
objectClassBuilder.addGetTypeMethod(klass.getType());
if (model != null)
objectClassBuilder.modelAnnotations(model.getAnnotations()).modifiers(transformObjectDeclFlags(model));
List<JCTree> result = objectClassBuilder.build();
if (makeLocalInstance) {
if (model.isSelfCaptured()) {
// if it's captured we need to box it and define the var before the class, so it can access it
JCNewClass newInstance = makeNewClass(objectClassBuilder.getClassName(), false, null);
JCFieldAccess setter = naming.makeSelect(Naming.getLocalValueName(model), Naming.getSetterName(model));
JCStatement assign = make().Exec(make().Assign(setter, newInstance));
result = result.prepend(assign);
JCVariableDecl localDecl = makeVariableBoxDecl(null, model);
result = result.prepend(localDecl);
} else {
// not captured, we can define the var after the class
JCVariableDecl localDecl = makeLocalIdentityInstance(name, objectClassBuilder.getClassName(), false);
result = result.append(localDecl);
}
} else if (model != null && Decl.withinClassOrInterface(model)) {
boolean generateGetter = Decl.isCaptured(model);
JCExpression type = makeJavaType(klass.getType());
if (generateGetter) {
int modifiers = TRANSIENT | PRIVATE;
JCExpression initialValue = makeNull();
containingClassBuilder.field(modifiers, name, type, initialValue, false);
AttributeDefinitionBuilder getter = AttributeDefinitionBuilder.getter(this, name, model).modifiers(transformAttributeGetSetDeclFlags(model, false));
if (def instanceof Tree.ObjectDefinition) {
getter.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, ((Tree.ObjectDefinition) def)));
}
ListBuffer<JCStatement> stmts = ListBuffer.<JCStatement>lb();
stmts.add(make().If(make().Binary(JCTree.EQ, naming.makeUnquotedIdent(Naming.quoteFieldName(name)), makeNull()), make().Exec(make().Assign(naming.makeUnquotedIdent(Naming.quoteFieldName(name)), makeNewClass(makeJavaType(klass.getType()), null))), null));
stmts.add(make().Return(naming.makeUnquotedIdent(Naming.quoteFieldName(name))));
getter.getterBlock(make().Block(0, stmts.toList()));
result = result.appendList(getter.build());
} else {
int modifiers = FINAL;
JCExpression initialValue = makeNewClass(makeJavaType(klass.getType()), null);
containingClassBuilder.field(modifiers, name, type, initialValue, true);
}
}
return result;
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class ClassTransformer method transformConstructorName.
protected void transformConstructorName(ClassDefinitionBuilder classBuilder, ListBuffer<JCTree> result, Constructor ctor, Class clz, int classMods, String ctorName, DeclNameFlag... declFlags) {
ClassDefinitionBuilder constructorNameClass = ClassDefinitionBuilder.klass(this, ctorName, null, true);
JCVariableDecl constructorNameConst;
if (Decl.isEnumeratedConstructor(ctor)) {
if (clz.isToplevel()) {
classMods &= ~(PRIVATE | PROTECTED | PUBLIC);
classMods |= PRIVATE | STATIC | FINAL;
} else if (clz.isMember() && Decl.isToplevel((Declaration) clz.getContainer())) {
classMods &= ~(PRIVATE | PROTECTED | PUBLIC);
classMods |= FINAL;
if (!Decl.isAncestorLocal(ctor)) {
classMods |= STATIC;
}
if (!ctor.isShared()) {
classMods |= PRIVATE;
}
} else {
classMods &= ~(PRIVATE | PROTECTED | PUBLIC);
classMods |= FINAL;
}
constructorNameConst = null;
} else {
if (clz.isToplevel() || (clz.isMember() && Decl.isToplevel((Declaration) clz.getContainer()))) {
classMods |= STATIC | FINAL;
constructorNameConst = make().VarDef(make().Modifiers(classMods, makeAtIgnore()), names().fromString(ctorName), naming.makeTypeDeclarationExpression(null, ctor, declFlags), makeNull());
} else {
classMods &= ~(PRIVATE | PROTECTED | PUBLIC);
constructorNameConst = null;
}
}
constructorNameClass.modifiers(classMods);
constructorNameClass.annotations(makeAtIgnore());
constructorNameClass.annotations(makeAtConstructorName(ctor.getName(), contains(declFlags, DeclNameFlag.DELEGATION)));
constructorNameClass.getInitBuilder().modifiers(PRIVATE);
List<JCTree> ctorNameClassDecl = constructorNameClass.build();
if (clz.isToplevel()) {
result.addAll(ctorNameClassDecl);
classBuilder.defs(constructorNameConst);
} else if (clz.isClassMember()) {
classBuilder.getContainingClassBuilder().defs(ctorNameClassDecl);
classBuilder.getContainingClassBuilder().defs(constructorNameConst);
} else if (clz.isInterfaceMember()) {
classBuilder.getContainingClassBuilder().getCompanionBuilder(clz).defs(ctorNameClassDecl);
classBuilder.getContainingClassBuilder().getCompanionBuilder(clz).defs(constructorNameConst);
} else {
classBuilder.defs(ctorNameClassDecl);
}
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class ClassTransformer method transformAnnotationClass.
/**
* Transforms an annotation class into a Java annotation type.
* <pre>
* annotation class Foo(String s, Integer i=1) {}
* </pre>
* is transformed into
* <pre>
* @Retention(RetentionPolicy.RUNTIME)
* @interface Foo$annotation$ {
* String s();
* long i() default 1;
* }
* </pre>
* If the annotation class is a subtype of SequencedAnnotation a wrapper
* annotation is also generated:
* <pre>
* @Retention(RetentionPolicy.RUNTIME)
* @interface Foo$annotations${
* Foo$annotation$[] value();
* }
* </pre>
*/
private List<JCTree> transformAnnotationClass(Tree.AnyClass def) {
Class klass = (Class) def.getDeclarationModel();
String annotationName = Naming.suffixName(Suffix.$annotation$, klass.getName());
ClassDefinitionBuilder annoBuilder = ClassDefinitionBuilder.klass(this, annotationName, null, false);
// annotations are never explicitly final in Java
annoBuilder.modifiers(Flags.ANNOTATION | Flags.INTERFACE | (transformClassDeclFlags(klass) & ~FINAL));
annoBuilder.getInitBuilder().modifiers(transformClassDeclFlags(klass) & ~FINAL);
annoBuilder.annotations(makeAtRetention(RetentionPolicy.RUNTIME));
annoBuilder.annotations(makeAtIgnore());
annoBuilder.annotations(expressionGen().transformAnnotations(OutputElement.ANNOTATION_TYPE, def));
for (Tree.Parameter p : def.getParameterList().getParameters()) {
Parameter parameterModel = p.getParameterModel();
annoBuilder.method(makeAnnotationMethod(p));
}
List<JCTree> result;
if (isSequencedAnnotation(klass)) {
result = annoBuilder.annotations(makeAtAnnotationTarget(EnumSet.noneOf(AnnotationTarget.class))).build();
String wrapperName = Naming.suffixName(Suffix.$annotations$, klass.getName());
ClassDefinitionBuilder sequencedBuilder = ClassDefinitionBuilder.klass(this, wrapperName, null, false);
// annotations are never explicitely final in Java
sequencedBuilder.modifiers(Flags.ANNOTATION | Flags.INTERFACE | (transformClassDeclFlags(klass) & ~FINAL));
sequencedBuilder.annotations(makeAtRetention(RetentionPolicy.RUNTIME));
MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, naming.getSequencedAnnotationMethodName());
mdb.annotationFlags(Annotations.MODEL_AND_USER);
mdb.modifiers(PUBLIC | ABSTRACT);
mdb.resultType(null, make().TypeArray(makeJavaType(klass.getType(), JT_ANNOTATION)));
mdb.noBody();
ClassDefinitionBuilder sequencedAnnotation = sequencedBuilder.method(mdb);
sequencedAnnotation.annotations(transformAnnotationConstraints(klass));
sequencedAnnotation.annotations(makeAtIgnore());
result = result.appendList(sequencedAnnotation.build());
} else {
result = annoBuilder.annotations(transformAnnotationConstraints(klass)).build();
}
return result;
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transform.
public JCTree transform(Tree.TypeLiteral expr) {
at(expr);
if (!expr.getWantsDeclaration()) {
if (expr.getDeclaration() instanceof Constructor) {
JCExpression classLiteral = makeTypeLiteralCall(expr.getType().getTypeModel().getQualifyingType(), false, expr.getTypeModel());
TypeDeclaration classModelDeclaration = (TypeDeclaration) typeFact().getLanguageModuleModelDeclaration(expr.getType().getTypeModel().getQualifyingType().getDeclaration().isMember() ? "MemberClass" : "Class");
JCTypeCast typeCast = make().TypeCast(makeJavaType(classModelDeclaration.appliedType(null, List.of(expr.getType().getTypeModel().getQualifyingType(), typeFact().getNothingType()))), classLiteral);
Type callableType = expr.getTypeModel().getFullType();
JCExpression reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
return make().Apply(null, naming.makeQualIdent(typeCast, "getConstructor"), List.<JCExpression>of(reifiedArgumentsExpr, make().Literal(expr.getDeclaration().getName())));
} else {
return makeTypeLiteralCall(expr.getType().getTypeModel(), true, expr.getTypeModel());
}
} else if (expr.getDeclaration() instanceof TypeParameter) {
// we must get it from its container
TypeParameter declaration = (TypeParameter) expr.getDeclaration();
Node node = expr;
return makeTypeParameterDeclaration(node, declaration);
} else if (expr.getDeclaration() instanceof Constructor || expr instanceof Tree.NewLiteral) {
Constructor ctor;
if (expr.getDeclaration() instanceof Constructor) {
ctor = (Constructor) expr.getDeclaration();
} else {
ctor = Decl.getDefaultConstructor((Class) expr.getDeclaration());
}
JCExpression metamodelCall = makeTypeDeclarationLiteral(Decl.getConstructedClass(ctor));
metamodelCall = make().TypeCast(makeJavaType(typeFact().getClassDeclarationType(), JT_RAW), metamodelCall);
metamodelCall = make().Apply(null, naming.makeQualIdent(metamodelCall, "getConstructorDeclaration"), List.<JCExpression>of(make().Literal(ctor.getName() == null ? "" : ctor.getName())));
if (Decl.isEnumeratedConstructor(ctor)) {
metamodelCall = make().TypeCast(makeJavaType(typeFact().getValueConstructorDeclarationType(), JT_RAW), metamodelCall);
} else /*else if (Decl.isDefaultConstructor(ctor)){
metamodelCall = make().TypeCast(
makeJavaType(typeFact().getDefaultConstructorDeclarationType(), JT_RAW), metamodelCall);
} */
{
metamodelCall = make().TypeCast(makeJavaType(typeFact().getCallableConstructorDeclarationType(), JT_RAW), metamodelCall);
}
return metamodelCall;
} else if (expr.getDeclaration() instanceof ClassOrInterface || expr.getDeclaration() instanceof TypeAlias) {
// use the generated class to get to the declaration literal
JCExpression metamodelCall = makeTypeDeclarationLiteral((TypeDeclaration) expr.getDeclaration());
Type exprType = expr.getTypeModel().resolveAliases();
// now cast if required
if (!exprType.isExactly(((TypeDeclaration) typeFact().getLanguageModuleDeclarationDeclaration("NestableDeclaration")).getType())) {
JCExpression type = makeJavaType(exprType, JT_NO_PRIMITIVES);
return make().TypeCast(type, metamodelCall);
}
return metamodelCall;
} else {
return makeErroneous(expr, "compiler bug: " + expr.getDeclaration() + " is an unsupported declaration type");
}
}
Aggregations