use of com.sun.tools.javac.util.ListBuffer in project ceylon-compiler by ceylon.
the class AbstractTransformer method makeAtLocalDeclarations.
private List<JCAnnotation> makeAtLocalDeclarations(Set<String> localDeclarations, Set<Interface> localInterfaces) {
if (localDeclarations.isEmpty() && localInterfaces.isEmpty())
return List.nil();
ListBuffer<JCExpression> array = new ListBuffer<JCTree.JCExpression>();
// sort them to get the same behaviour on every JDK
SortedSet<String> sortedNames = new TreeSet<String>();
sortedNames.addAll(localDeclarations);
for (Interface iface : localInterfaces) {
sortedNames.add("::" + naming.makeTypeDeclarationName(iface));
}
for (String val : sortedNames) array.add(make().Literal(val));
JCExpression attr = make().Assign(naming.makeUnquotedIdent("value"), make().NewArray(null, null, array.toList()));
return makeModelAnnotation(syms().ceylonAtLocalDeclarationsType, List.of(attr));
}
use of com.sun.tools.javac.util.ListBuffer in project ceylon-compiler by ceylon.
the class AbstractTransformer method getLicenseAuthorsDocAnnotationArguments.
/** Returns a ListBuffer with assignment expressions for the doc, license and by arguments, as well as name,
* to be used in an annotation which requires them (such as Module and Package) */
ListBuffer<JCExpression> getLicenseAuthorsDocAnnotationArguments(String name, java.util.List<Annotation> anns) {
ListBuffer<JCExpression> authors = new ListBuffer<JCTree.JCExpression>();
ListBuffer<JCExpression> res = new ListBuffer<JCExpression>();
res.add(make().Assign(naming.makeUnquotedIdent("name"), make().Literal(name)));
for (Annotation a : anns) {
if (a.getPositionalArguments() != null && !a.getPositionalArguments().isEmpty()) {
if (a.getName().equals("doc")) {
res.add(make().Assign(naming.makeUnquotedIdent("doc"), make().Literal(a.getPositionalArguments().get(0))));
} else if (a.getName().equals("license")) {
res.add(make().Assign(naming.makeUnquotedIdent("license"), make().Literal(a.getPositionalArguments().get(0))));
} else if (a.getName().equals("by")) {
for (String author : a.getPositionalArguments()) {
authors.add(make().Literal(author));
}
}
}
}
if (!authors.isEmpty()) {
res.add(make().Assign(naming.makeUnquotedIdent("by"), make().NewArray(null, null, authors.toList())));
}
return res;
}
use of com.sun.tools.javac.util.ListBuffer in project ceylon-compiler by ceylon.
the class AbstractTransformer method makeAtLocalContainer.
protected List<JCAnnotation> makeAtLocalContainer(List<String> path, String companionClassName) {
if (path.isEmpty())
return List.nil();
ListBuffer<JCExpression> array = new ListBuffer<JCTree.JCExpression>();
for (String val : path) array.add(make().Literal(val));
JCExpression pathAttr = make().Assign(naming.makeUnquotedIdent("path"), make().NewArray(null, null, array.toList()));
JCExpression companionAttr = make().Assign(naming.makeUnquotedIdent("companionClassName"), make().Literal(companionClassName == null ? "" : companionClassName));
return makeModelAnnotation(syms().ceylonAtLocalContainerType, List.of(pathAttr, companionAttr));
}
use of com.sun.tools.javac.util.ListBuffer in project ceylon-compiler by ceylon.
the class AbstractTransformer method makeTupleTypeDescriptor.
private JCExpression makeTupleTypeDescriptor(Type pt, boolean firstElementOptional) {
java.util.List<Type> tupleElementTypes = typeFact().getTupleElementTypes(pt);
boolean isVariadic = typeFact().isTupleLengthUnbounded(pt);
boolean atLeastOne = false;
boolean needsRestSplit = false;
Type restType = null;
if (isVariadic) {
// unwrap the last element
restType = tupleElementTypes.get(tupleElementTypes.size() - 1);
// to optimise
if (restType.isUnknown())
return null;
tupleElementTypes.set(tupleElementTypes.size() - 1, typeFact.getSequentialElementType(restType));
atLeastOne = restType.getDeclaration().inherits(typeFact().getSequenceDeclaration());
// the last rest element may be a type param, in which case we resolve it at runtime
needsRestSplit = !restType.getDeclaration().equals(typeFact.getSequenceDeclaration()) && !restType.getDeclaration().equals(typeFact.getSequentialDeclaration());
}
int firstDefaulted;
if (!firstElementOptional) {
// only do this crazy computation if the first element is not optional (case of []|[A] which is a union type really)
int minimumLength = typeFact().getTupleMinimumLength(pt);
// [B+] -> 1
if (atLeastOne)
minimumLength--;
// [A,B=] -> 1
// [A=,B*] -> 0
// [A,B+] -> 1
// [B*] -> 0
// [B+] -> 0
// [A,B=] -> 2
// [A=,B*] -> 1
// [A,B+] -> 1
// [B*] -> 0
// [B+] -> 0
int nonVariadicParams = tupleElementTypes.size();
if (isVariadic)
nonVariadicParams--;
// [A,B=] -> 2!=1 -> 1
// [A=,B*] -> 1!=0 -> 0
// [A,B+] -> 1==1 -> -1
// [B*] -> 0==0 -> -1
// [B+] -> 0==0 -> -1
firstDefaulted = nonVariadicParams != minimumLength ? minimumLength : -1;
} else {
firstDefaulted = 0;
}
JCExpression restTypeDescriptor = null;
JCExpression restElementTypeDescriptor = null;
if (needsRestSplit) {
Type restElementType = tupleElementTypes.get(tupleElementTypes.size() - 1);
tupleElementTypes.remove(tupleElementTypes.size() - 1);
restTypeDescriptor = makeReifiedTypeArgumentResolved(restType, false);
restElementTypeDescriptor = makeReifiedTypeArgumentResolved(restElementType, false);
}
ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
if (needsRestSplit) {
args.append(restTypeDescriptor);
args.append(restElementTypeDescriptor);
} else {
args.append(makeBoolean(isVariadic));
args.append(makeBoolean(atLeastOne));
}
args.append(makeInteger(firstDefaulted));
for (Type element : tupleElementTypes) {
args.append(makeReifiedTypeArgumentResolved(element, false));
}
JCExpression tupleDescriptor = make().Apply(null, makeSelect(makeTypeDescriptorType(), needsRestSplit ? "tupleWithRest" : "tuple"), args.toList());
return tupleDescriptor;
}
use of com.sun.tools.javac.util.ListBuffer 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;
}
Aggregations