use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class AbstractTreeScannerTest method trim.
/**
* Get a trimmed string for a tree node, with normalized white space and limited length.
*/
String trim(Tree tree, int len) {
JCTree t = (JCTree) tree;
String s = t.toString().replaceAll("\\s+", " ");
return (s.length() < len) ? s : s.substring(0, len);
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class CeylonTransformer method makeDefs.
private List<JCTree> makeDefs(CompilationUnit t) {
final ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
t.visit(new SourceDeclarationVisitor() {
@Override
public void loadFromSource(Declaration decl) {
if (!checkNative(decl))
return;
long flags = decl instanceof Tree.AnyInterface ? Flags.INTERFACE : 0;
String name = Naming.toplevelClassName("", decl);
defs.add(makeClassDef(decl, flags, name, WantedDeclaration.Normal));
if (decl instanceof Tree.AnyInterface) {
String implName = Naming.getImplClassName(name);
defs.add(makeClassDef(decl, 0, implName, WantedDeclaration.Normal));
}
// only do it for Bootstrap where we control the annotations, because it's so dodgy ATM
if (options.get(OptionName.BOOTSTRAPCEYLON) != null && decl instanceof Tree.AnyClass && TreeUtil.hasAnnotation(decl.getAnnotationList(), "annotation", decl.getUnit())) {
String annotationName = Naming.suffixName(Suffix.$annotation$, name);
defs.add(makeClassDef(decl, Flags.ANNOTATION, annotationName, WantedDeclaration.Annotation));
for (Tree.StaticType sat : ((Tree.AnyClass) decl).getSatisfiedTypes().getTypes()) {
if (sat instanceof Tree.BaseType && ((Tree.BaseType) sat).getIdentifier().getText().equals("SequencedAnnotation")) {
String annotationsName = Naming.suffixName(Suffix.$annotations$, name);
defs.add(makeClassDef(decl, Flags.ANNOTATION, annotationsName, WantedDeclaration.AnnotationSequence));
}
}
}
}
private JCTree makeClassDef(Declaration decl, long flags, String name, WantedDeclaration wantedDeclaration) {
ListBuffer<JCTree.JCTypeParameter> typarams = new ListBuffer<JCTree.JCTypeParameter>();
if (decl instanceof Tree.ClassOrInterface) {
Tree.ClassOrInterface classDecl = (ClassOrInterface) decl;
if (classDecl.getTypeParameterList() != null) {
for (Tree.TypeParameterDeclaration typeParamDecl : classDecl.getTypeParameterList().getTypeParameterDeclarations()) {
// we don't need a valid name, just a name, and making it BOGUS helps us find it later if it turns out
// we failed to reset everything properly
typarams.add(make().TypeParameter(names().fromString("BOGUS-" + typeParamDecl.getIdentifier().getText()), List.<JCExpression>nil()));
}
}
}
return make().ClassDef(make().Modifiers(flags | Flags.PUBLIC), names().fromString(name), typarams.toList(), null, List.<JCExpression>nil(), makeClassBody(decl, wantedDeclaration));
}
private List<JCTree> makeClassBody(Declaration decl, WantedDeclaration wantedDeclaration) {
// only do it for Bootstrap where we control the annotations, because it's so dodgy ATM
if (wantedDeclaration == WantedDeclaration.Annotation) {
ListBuffer<JCTree> body = new ListBuffer<JCTree>();
for (Tree.Parameter param : ((Tree.ClassDefinition) decl).getParameterList().getParameters()) {
String name;
JCExpression type = make().TypeArray(make().Type(syms().stringType));
if (param instanceof Tree.InitializerParameter)
name = ((Tree.InitializerParameter) param).getIdentifier().getText();
else if (param instanceof Tree.ParameterDeclaration) {
Tree.TypedDeclaration typedDeclaration = ((Tree.ParameterDeclaration) param).getTypedDeclaration();
name = typedDeclaration.getIdentifier().getText();
type = getAnnotationTypeFor(typedDeclaration.getType());
} else
name = "ERROR";
JCMethodDecl method = make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString(name), type, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
body.append(method);
}
return body.toList();
}
if (wantedDeclaration == WantedDeclaration.AnnotationSequence) {
String name = Naming.toplevelClassName("", decl);
String annotationName = Naming.suffixName(Suffix.$annotation$, name);
JCExpression type = make().TypeArray(make().Ident(names().fromString(annotationName)));
JCMethodDecl method = make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString("value"), type, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
return List.<JCTree>of(method);
}
return List.<JCTree>nil();
}
private JCExpression getAnnotationTypeFor(Tree.Type type) {
if (type instanceof Tree.BaseType) {
String name = ((Tree.BaseType) type).getIdentifier().getText();
if (name.equals("String") || name.equals("Declaration"))
return make().Type(syms().stringType);
if (name.equals("Boolean"))
return make().Type(syms().booleanType);
if (name.equals("Integer"))
return make().Type(syms().longType);
if (name.equals("Float"))
return make().Type(syms().doubleType);
if (name.equals("Byte"))
return make().Type(syms().byteType);
if (name.equals("Character"))
return make().Type(syms().charType);
if (name.equals("Declaration") || name.equals("ClassDeclaration") || name.equals("InterfaceDeclaration") || name.equals("ClassOrInterfaceDeclaration"))
return make().Type(syms().stringType);
}
if (type instanceof Tree.SequencedType) {
return make().TypeArray(getAnnotationTypeFor(((Tree.SequencedType) type).getType()));
}
if (type instanceof Tree.SequenceType) {
return make().TypeArray(getAnnotationTypeFor(((Tree.SequenceType) type).getElementType()));
}
if (type instanceof Tree.IterableType) {
return make().TypeArray(getAnnotationTypeFor(((Tree.IterableType) type).getElementType()));
}
if (type instanceof Tree.TupleType) {
// can only be one, must be a SequencedType
Tree.Type sequencedType = ((Tree.TupleType) type).getElementTypes().get(0);
return getAnnotationTypeFor(sequencedType);
}
System.err.println("Unknown Annotation type: " + type);
return make().TypeArray(make().Type(syms().stringType));
}
@Override
public void loadFromSource(ModuleDescriptor that) {
// don't think we care about these
}
@Override
public void loadFromSource(PackageDescriptor that) {
// don't think we care about these
}
});
return defs.toList();
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class CeylonTransformer method makeJCCompilationUnitPlaceholder.
/**
* In this pass we only make an empty placeholder which we'll fill in the
* EnterCeylon phase later on
*/
public JCCompilationUnit makeJCCompilationUnitPlaceholder(Tree.CompilationUnit t, JavaFileObject file, String pkgName, PhasedUnit phasedUnit) {
JCExpression pkg = pkgName != null ? getPackage(pkgName) : null;
at(t);
List<JCTree> defs = makeDefs(t);
JCCompilationUnit topLev = new CeylonCompilationUnit(List.<JCTree.JCAnnotation>nil(), pkg, defs, null, null, null, null, t, phasedUnit);
topLev.lineMap = getMap();
topLev.sourcefile = file;
topLev.isCeylonProgram = true;
return topLev;
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
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
AttributeDefinitionBuilder builder = AttributeDefinitionBuilder.wrapped(this, attrClassName, null, attrName, declarationModel, declarationModel.isToplevel()).is(Flags.PUBLIC, declarationModel.isShared());
final JCExpression initialValue;
final HasErrorException expressionError;
if (expression != null) {
expressionError = errors().getFirstExpressionErrorAndMarkBrokenness(expression.getExpression());
if (expressionError != null) {
initialValue = make().Erroneous();
} else {
initialValue = transformValueInit(declarationModel, attrName, expression);
}
} else {
expressionError = null;
initialValue = transformValueInit(declarationModel, attrName, expression);
}
// For captured local variable Values, use a VariableBox
if (Decl.isBoxedVariable(declarationModel)) {
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 && !Decl.isToplevel(declarationModel)) {
JCExpression typeExpr = makeJavaType(getGetterInterfaceType(declarationModel));
JCTree.JCVariableDecl var = makeVar(attrClassName, typeExpr, null);
return List.<JCTree>of(var);
}
// Set the local declarations annotation
if (decl != null) {
List<JCAnnotation> scopeAnnotations;
if (Decl.isToplevel(declarationModel) && setterDecl != null) {
scopeAnnotations = makeAtLocalDeclarations(decl, setterDecl);
} else {
scopeAnnotations = makeAtLocalDeclarations(decl);
}
builder.classAnnotations(scopeAnnotations);
} else if (block != null) {
List<JCAnnotation> scopeAnnotations = makeAtLocalDeclarations(block);
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)) {
// 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;
if (Decl.isLocal(declarationModel)) {
prevSyntheticClassBody = expressionGen().withinSyntheticClassBody(true);
} else {
prevSyntheticClassBody = 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));
}
if (Decl.isLocal(declarationModel)) {
if (expressionError != null) {
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.build().append(makeLocalIdentityInstance(typeExpr, attrClassName, attrClassName, declarationModel.isShared(), initialValue));
} else {
if (expressionError != null) {
builder.initialValueError(expressionError);
} else if (initialValue != null) {
builder.initialValue(initialValue);
}
builder.is(Flags.STATIC, true);
return builder.build();
}
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class AbstractTransformer method makeLazyIterable.
/**
* Makes a lazy iterable literal, for a sequenced argument to a named invocation
* (<code>f{foo=""; expr1, expr2, *expr3}</code>) or
* for an iterable instantiation (<code>{expr1, expr2, *expr3}</code>)
*/
JCExpression makeLazyIterable(Tree.SequencedArgument sequencedArgument, Type seqElemType, Type absentType, int flags) {
java.util.List<PositionalArgument> list = sequencedArgument.getPositionalArguments();
int i = 0;
ListBuffer<JCStatement> returns = new ListBuffer<JCStatement>();
boolean spread = false;
boolean old = expressionGen().withinSyntheticClassBody(true);
try {
for (Tree.PositionalArgument arg : list) {
at(arg);
JCExpression jcExpression;
// last expression can be an Iterable<seqElemType>
if (arg instanceof Tree.SpreadArgument || arg instanceof Tree.Comprehension) {
// make sure we only have spread/comprehension as last
if (i != list.size() - 1) {
jcExpression = makeErroneous(arg, "compiler bug: spread or comprehension argument is not last in sequence literal");
} else {
Type type = typeFact().getIterableType(seqElemType);
spread = true;
if (arg instanceof Tree.SpreadArgument) {
Tree.Expression expr = ((Tree.SpreadArgument) arg).getExpression();
// always boxed since it is a sequence
jcExpression = expressionGen().transformExpression(expr, BoxingStrategy.BOXED, type);
} else {
jcExpression = expressionGen().transformComprehension((Comprehension) arg, type);
}
}
} else if (arg instanceof Tree.ListedArgument) {
Tree.Expression expr = ((Tree.ListedArgument) arg).getExpression();
// always boxed since we stuff them into a sequence
jcExpression = expressionGen().transformExpression(expr, BoxingStrategy.BOXED, seqElemType);
} else {
jcExpression = makeErroneous(arg, "compiler bug: " + arg.getNodeType() + " is not a supported sequenced argument");
}
at(arg);
// the last iterable goes first if spread
returns.add(make().Return(jcExpression));
i++;
}
at(sequencedArgument);
if (Strategy.preferLazySwitchingIterable(sequencedArgument.getPositionalArguments())) {
// use a LazySwitchingIterable
MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, Unfix.$evaluate$.toString());
mdb.isOverride(true);
mdb.modifiers(PROTECTED | FINAL);
mdb.resultType(null, make().Type(syms().objectType));
mdb.parameter(ParameterDefinitionBuilder.systemParameter(this, Unfix.$index$.toString()).type(make().Type(syms().intType), null));
JCSwitch swtch;
try (SavedPosition sp = noPosition()) {
ListBuffer<JCCase> cases = ListBuffer.<JCCase>lb();
i = 0;
for (JCStatement e : returns) {
cases.add(make().Case(make().Literal(i++), List.<JCStatement>of(e)));
}
cases.add(make().Case(null, List.<JCStatement>of(make().Return(makeNull()))));
swtch = make().Switch(naming.makeUnquotedIdent(Unfix.$index$), cases.toList());
}
mdb.body(swtch);
return make().NewClass(null, //of(makeJavaType(seqElemType), makeJavaType(absentType)),
List.<JCExpression>nil(), make().TypeApply(make().QualIdent(syms.ceylonLazyIterableType.tsym), List.<JCExpression>of(makeJavaType(seqElemType, JT_TYPE_ARGUMENT), makeJavaType(absentType, JT_TYPE_ARGUMENT))), // td,
List.of(// td,
makeReifiedTypeArgument(seqElemType), //td
makeReifiedTypeArgument(absentType), // numMethods
make().Literal(list.size()), // spread),
make().Literal(spread)), make().AnonymousClassDef(make().Modifiers(FINAL), List.<JCTree>of(mdb.build())));
} else {
// use a LazyInvokingIterable
ListBuffer<JCTree> methods = new ListBuffer<JCTree>();
MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, Unfix.$lookup$.toString());
mdb.isOverride(true);
mdb.modifiers(PROTECTED | FINAL);
mdb.resultType(null, naming.makeQualIdent(make().Type(syms().methodHandlesType), "Lookup"));
mdb.body(make().Return(make().Apply(List.<JCExpression>nil(), naming.makeQualIdent(make().Type(syms().methodHandlesType), "lookup"), List.<JCExpression>nil())));
methods.add(mdb.build());
mdb = MethodDefinitionBuilder.systemMethod(this, Unfix.$invoke$.toString());
mdb.isOverride(true);
mdb.modifiers(PROTECTED | FINAL);
mdb.resultType(null, make().Type(syms().objectType));
mdb.parameter(ParameterDefinitionBuilder.systemParameter(this, "handle").type(make().Type(syms().methodHandleType), null));
mdb.body(make().Return(make().Apply(List.<JCExpression>nil(), naming.makeQualIdent(naming.makeUnquotedIdent("handle"), "invokeExact"), List.<JCExpression>of(naming.makeThis()))));
methods.add(mdb.build());
i = 0;
for (JCStatement expr : returns) {
mdb = MethodDefinitionBuilder.systemMethod(this, "$" + i);
i++;
mdb.modifiers(PRIVATE | FINAL);
mdb.resultType(null, make().Type(syms().objectType));
mdb.body(expr);
methods.add(mdb.build());
}
return make().NewClass(null, //of(makeJavaType(seqElemType), makeJavaType(absentType)),
List.<JCExpression>nil(), make().TypeApply(make().QualIdent(syms.ceylonLazyInvokingIterableType.tsym), List.<JCExpression>of(makeJavaType(seqElemType, JT_TYPE_ARGUMENT), makeJavaType(absentType, JT_TYPE_ARGUMENT))), // td,
List.of(// td,
makeReifiedTypeArgument(seqElemType), //td
makeReifiedTypeArgument(absentType), // numMethods
make().Literal(list.size()), // spread),
make().Literal(spread)), make().AnonymousClassDef(make().Modifiers(FINAL), methods.toList()));
}
} finally {
expressionGen().withinSyntheticClassBody(old);
}
}
Aggregations