use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter in project ceylon by eclipse.
the class AbstractTransformer method makeTypeParameter.
JCTypeParameter makeTypeParameter(TypeParameter declarationModel, java.util.List<Type> satisfiedTypesForBounds) {
TypeParameter typeParameterForBounds = declarationModel;
if (satisfiedTypesForBounds == null) {
satisfiedTypesForBounds = declarationModel.getSatisfiedTypes();
}
// special case for method refinenement where Java doesn't let us refine the parameter bounds
if (declarationModel.getContainer() instanceof Function) {
Function method = (Function) declarationModel.getContainer();
Function refinedMethod = (Function) method.getRefinedDeclaration();
if (!Decl.equal(method, refinedMethod)) {
// find the param index
int index = method.getTypeParameters().indexOf(declarationModel);
if (index == -1) {
log.error("Failed to find type parameter index: " + declarationModel.getName());
} else if (refinedMethod.getTypeParameters().size() > index) {
// ignore smaller index than size since the typechecker would have found the error
TypeParameter refinedTP = refinedMethod.getTypeParameters().get(index);
if (!haveSameBounds(declarationModel, refinedTP)) {
// find the right instantiation of that type parameter
TypeDeclaration methodContainer = (TypeDeclaration) method.getContainer();
TypeDeclaration refinedMethodContainer = (TypeDeclaration) refinedMethod.getContainer();
// find the supertype that gave us that method and its type arguments
Type supertype = methodContainer.getType().getSupertype(refinedMethodContainer);
satisfiedTypesForBounds = new ArrayList<Type>(refinedTP.getSatisfiedTypes().size());
for (Type satisfiedType : refinedTP.getSatisfiedTypes()) {
// substitute the refined type parameter bounds with the right type arguments
satisfiedTypesForBounds.add(satisfiedType.substitute(supertype));
}
typeParameterForBounds = refinedTP;
}
}
}
}
return makeTypeParameter(declarationModel.getName(), satisfiedTypesForBounds, typeParameterForBounds.isCovariant(), typeParameterForBounds.isContravariant());
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter in project ceylon by eclipse.
the class CallableBuilder method buildTypeConstructor.
protected JCExpression buildTypeConstructor(Type callableType, JCNewClass callableInstance) {
JCExpression result;
// Wrap in an anonymous TypeConstructor subcla
MethodDefinitionBuilder rawApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.apply.toString());
rawApply.modifiers(Flags.PUBLIC);
rawApply.isOverride(true);
// for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
// apply.typeParameter(tp);
// }
rawApply.resultType(new TransformedType(gen.makeJavaType(callableType, AbstractTransformer.JT_RAW)));
{
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
pdb.modifiers(Flags.FINAL);
pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
rawApply.parameter(pdb);
}
rawApply.body(List.<JCStatement>of(gen.make().Return(gen.make().Apply(null, gen.naming.makeUnquotedIdent(Naming.Unfix.$apply$.toString()), List.<JCExpression>of(gen.naming.makeUnquotedIdent("applied"))))));
MethodDefinitionBuilder typedApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.$apply$.toString());
typedApply.modifiers(Flags.PRIVATE);
// for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
// apply.typeParameter(tp);
// }
typedApply.resultType(new TransformedType(gen.makeJavaType(callableType)));
{
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
pdb.modifiers(Flags.FINAL);
pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
typedApply.parameter(pdb);
}
ListBuffer<JCTypeParameter> typeParameters = new ListBuffer<JCTypeParameter>();
for (TypeParameter typeParameter : Strategy.getEffectiveTypeParameters(typeModel.getDeclaration())) {
Type typeArgument = typeModel.getTypeArguments().get(typeParameter);
typeParameters.add(gen.makeTypeParameter(typeParameter, null));
typedApply.body(gen.makeVar(Flags.FINAL, gen.naming.getTypeArgumentDescriptorName(typeParameter), gen.make().Type(gen.syms().ceylonTypeDescriptorType), gen.make().Indexed(gen.makeUnquotedIdent("applied"), gen.make().Literal(typeModel.getTypeArgumentList().indexOf(typeArgument)))));
}
typedApply.body(gen.make().Return(callableInstance));
// typedApply.body(body.toList());
MethodDefinitionBuilder ctor = MethodDefinitionBuilder.constructor(gen, false);
ctor.body(gen.make().Exec(gen.make().Apply(null, gen.naming.makeSuper(), List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))))));
SyntheticName n = gen.naming.synthetic(typeModel.getDeclaration().getName());
JCClassDecl classDef = gen.make().ClassDef(gen.make().Modifiers(0, List.<JCAnnotation>nil()), // name,
n.asName(), typeParameters.toList(), // extending
gen.make().QualIdent(gen.syms().ceylonAbstractTypeConstructorType.tsym), // implementing,
List.<JCExpression>nil(), List.<JCTree>of(ctor.build(), rawApply.build(), typedApply.build()));
result = gen.make().LetExpr(List.<JCStatement>of(classDef), gen.make().NewClass(null, null, n.makeIdent(), List.<JCExpression>nil(), // List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))),
null));
return result;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter in project ceylon by eclipse.
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;
Stack<Tree.Declaration> ancestors = new Stack<>();
long flags = decl instanceof Tree.AnyInterface ? Flags.INTERFACE : 0;
String name = Naming.toplevelClassName("", decl);
defs.add(makeClassDef(decl, flags, name, WantedDeclaration.Normal, defs, ancestors));
if (decl instanceof Tree.AnyInterface) {
String implName = Naming.getImplClassName(name);
defs.add(makeClassDef(decl, 0, implName, WantedDeclaration.InterfaceImpl, defs, ancestors));
}
if (Decl.isAnnotationClassNoModel(decl)) {
String annotationName = Naming.suffixName(Suffix.$annotation$, name);
defs.add(makeClassDef(decl, Flags.ANNOTATION | Flags.INTERFACE, annotationName, WantedDeclaration.Annotation, defs, ancestors));
if (Decl.isSequencedAnnotationClassNoModel((Tree.AnyClass) decl)) {
String annotationsName = Naming.suffixName(Suffix.$annotations$, name);
defs.add(makeClassDef(decl, Flags.ANNOTATION | Flags.INTERFACE, annotationsName, WantedDeclaration.AnnotationSequence, defs, ancestors));
}
}
}
private JCTree makeClassDef(Tree.Declaration decl, long flags, String name, WantedDeclaration wantedDeclaration, ListBuffer<JCTree> toplevelDeclarations, Stack<Tree.Declaration> ancestors) {
if (decl instanceof Tree.AnyInterface == false && TreeUtil.hasAnnotation(decl.getAnnotationList(), "static", null)) {
flags |= Flags.STATIC;
}
ListBuffer<JCTree.JCTypeParameter> typarams = new ListBuffer<JCTree.JCTypeParameter>();
if (decl instanceof Tree.ClassOrInterface) {
Tree.ClassOrInterface classDecl = (ClassOrInterface) decl;
if (decl instanceof Tree.AnyInterface) {
// interfaces are pulled up and catch container type params
for (Tree.Declaration ancestor : ancestors) {
if (ancestor instanceof Tree.ClassOrInterface) {
addTypeParameters(typarams, (Tree.ClassOrInterface) ancestor);
}
}
}
addTypeParameters(typarams, classDecl);
}
ancestors.push(decl);
JCTree ret = make().ClassDef(make().Modifiers(flags | Flags.PUBLIC), names().fromString(name), typarams.toList(), null, List.<JCExpression>nil(), makeClassBody(decl, wantedDeclaration, toplevelDeclarations, ancestors));
ancestors.pop();
return ret;
}
private void addTypeParameters(ListBuffer<JCTypeParameter> typarams, Tree.ClassOrInterface classDecl) {
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()));
}
}
}
private List<JCTree> makeClassBody(Declaration decl, WantedDeclaration wantedDeclaration, ListBuffer<JCTree> toplevelDeclarations, Stack<Tree.Declaration> ancestors) {
// 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);
}
ListBuffer<JCTree> defs = new ListBuffer<>();
java.util.List<Statement> statements = null;
if (decl instanceof Tree.ClassDefinition)
statements = ((Tree.ClassDefinition) decl).getClassBody().getStatements();
else if (decl instanceof Tree.InterfaceDefinition) {
// only walk interface members if we're generating the impl class
if (wantedDeclaration == WantedDeclaration.InterfaceImpl)
statements = ((Tree.InterfaceDefinition) decl).getInterfaceBody().getStatements();
}
if (statements != null) {
for (Tree.Statement member : statements) {
if (member instanceof Tree.ClassOrInterface && checkNative((Tree.Declaration) member)) {
long flags = member instanceof Tree.AnyInterface ? Flags.INTERFACE : 0;
String initialName = Naming.toplevelClassName("", (Tree.Declaration) member);
String name;
if (member instanceof Tree.AnyInterface) {
// interfaces are pulled to the toplevel
StringBuffer strbuf = new StringBuffer();
for (Tree.Declaration part : ancestors) strbuf.append(part.getIdentifier().getText()).append("$");
name = strbuf.append(initialName).toString();
} else {
name = initialName;
}
JCTree def = makeClassDef((Tree.Declaration) member, flags, name, WantedDeclaration.Normal, toplevelDeclarations, ancestors);
if (member instanceof Tree.AnyInterface) {
toplevelDeclarations.add(def);
String implName = Naming.getImplClassName(initialName);
defs.add(makeClassDef((Tree.Declaration) member, 0, implName, WantedDeclaration.InterfaceImpl, defs, ancestors));
} else
defs.add(def);
// FIXME: interfaces impl?
}
}
}
return defs.toList();
}
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);
// probably an enum value then
return make().TypeArray(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 org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter in project ceylon by eclipse.
the class JavaPositionsRetriever method getJavaSourceCodeWithCeylonPositions.
public String getJavaSourceCodeWithCeylonPositions() {
final CharArrayWriter writer = new CharArrayWriter();
Pretty printer = new Pretty(writer, true) {
int previousCeylonPosition = -1;
int previousPositionInString = 0;
private void outputCeylonPosition(JCTree tree) {
try {
int currentCeylonPosition = tree.getPreferredPosition();
int currentPositionInString = writer.size();
if (previousCeylonPosition != currentCeylonPosition || previousPositionInString != currentPositionInString) {
if (currentCeylonPosition != -1 && currentCeylonPosition != 0) {
writer.write("/* " + formatCeylonPosition(currentCeylonPosition) + " */");
}
previousCeylonPosition = currentCeylonPosition;
previousPositionInString = writer.size();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void visitTopLevel(JCCompilationUnit tree) {
outputCeylonPosition(tree);
super.visitTopLevel(tree);
}
@Override
public void visitImport(JCImport tree) {
outputCeylonPosition(tree);
super.visitImport(tree);
}
@Override
public void visitClassDef(JCClassDecl tree) {
outputCeylonPosition(tree);
super.visitClassDef(tree);
}
@Override
public void visitMethodDef(JCMethodDecl tree) {
outputCeylonPosition(tree);
super.visitMethodDef(tree);
}
@Override
public void visitVarDef(JCVariableDecl tree) {
outputCeylonPosition(tree);
super.visitVarDef(tree);
}
@Override
public void visitSkip(JCSkip tree) {
outputCeylonPosition(tree);
super.visitSkip(tree);
}
@Override
public void visitBlock(JCBlock tree) {
outputCeylonPosition(tree);
super.visitBlock(tree);
tree.endpos = currentPosition - 1;
}
@Override
public void visitDoLoop(JCDoWhileLoop tree) {
outputCeylonPosition(tree);
super.visitDoLoop(tree);
}
@Override
public void visitWhileLoop(JCWhileLoop tree) {
outputCeylonPosition(tree);
super.visitWhileLoop(tree);
}
@Override
public void visitForLoop(JCForLoop tree) {
outputCeylonPosition(tree);
super.visitForLoop(tree);
}
@Override
public void visitForeachLoop(JCEnhancedForLoop tree) {
outputCeylonPosition(tree);
super.visitForeachLoop(tree);
}
@Override
public void visitLabelled(JCLabeledStatement tree) {
outputCeylonPosition(tree);
super.visitLabelled(tree);
}
@Override
public void visitSwitch(JCSwitch tree) {
outputCeylonPosition(tree);
super.visitSwitch(tree);
}
@Override
public void visitCase(JCCase tree) {
outputCeylonPosition(tree);
super.visitCase(tree);
}
@Override
public void visitSynchronized(JCSynchronized tree) {
outputCeylonPosition(tree);
super.visitSynchronized(tree);
}
@Override
public void visitTry(JCTry tree) {
outputCeylonPosition(tree);
super.visitTry(tree);
}
@Override
public void visitCatch(JCCatch tree) {
outputCeylonPosition(tree);
super.visitCatch(tree);
}
@Override
public void visitConditional(JCConditional tree) {
outputCeylonPosition(tree);
super.visitConditional(tree);
}
@Override
public void visitIf(JCIf tree) {
outputCeylonPosition(tree);
super.visitIf(tree);
}
@Override
public void visitExec(JCExpressionStatement tree) {
outputCeylonPosition(tree);
super.visitExec(tree);
}
@Override
public void visitBreak(JCBreak tree) {
outputCeylonPosition(tree);
super.visitBreak(tree);
}
@Override
public void visitContinue(JCContinue tree) {
outputCeylonPosition(tree);
super.visitContinue(tree);
}
@Override
public void visitReturn(JCReturn tree) {
outputCeylonPosition(tree);
super.visitReturn(tree);
}
@Override
public void visitThrow(JCThrow tree) {
outputCeylonPosition(tree);
super.visitThrow(tree);
}
@Override
public void visitAssert(JCAssert tree) {
outputCeylonPosition(tree);
super.visitAssert(tree);
}
@Override
public void visitApply(JCMethodInvocation tree) {
outputCeylonPosition(tree);
super.visitApply(tree);
}
@Override
public void visitNewClass(JCNewClass tree) {
outputCeylonPosition(tree);
super.visitNewClass(tree);
}
@Override
public void visitNewArray(JCNewArray tree) {
outputCeylonPosition(tree);
super.visitNewArray(tree);
}
@Override
public void visitParens(JCParens tree) {
outputCeylonPosition(tree);
super.visitParens(tree);
}
@Override
public void visitAssign(JCAssign tree) {
outputCeylonPosition(tree);
super.visitAssign(tree);
}
@Override
public void visitAssignop(JCAssignOp tree) {
outputCeylonPosition(tree);
super.visitAssignop(tree);
}
@Override
public void visitUnary(JCUnary tree) {
outputCeylonPosition(tree);
super.visitUnary(tree);
}
@Override
public void visitBinary(JCBinary tree) {
outputCeylonPosition(tree);
super.visitBinary(tree);
}
@Override
public void visitTypeCast(JCTypeCast tree) {
outputCeylonPosition(tree);
super.visitTypeCast(tree);
}
@Override
public void visitTypeTest(JCInstanceOf tree) {
outputCeylonPosition(tree);
super.visitTypeTest(tree);
}
@Override
public void visitIndexed(JCArrayAccess tree) {
outputCeylonPosition(tree);
super.visitIndexed(tree);
}
@Override
public void visitSelect(JCFieldAccess tree) {
outputCeylonPosition(tree);
super.visitSelect(tree);
}
@Override
public void visitIdent(JCIdent tree) {
outputCeylonPosition(tree);
super.visitIdent(tree);
}
@Override
public void visitLiteral(JCLiteral tree) {
outputCeylonPosition(tree);
super.visitLiteral(tree);
}
@Override
public void visitTypeIdent(JCPrimitiveTypeTree tree) {
outputCeylonPosition(tree);
super.visitTypeIdent(tree);
}
@Override
public void visitTypeArray(JCArrayTypeTree tree) {
outputCeylonPosition(tree);
super.visitTypeArray(tree);
}
@Override
public void visitTypeApply(JCTypeApply tree) {
outputCeylonPosition(tree);
super.visitTypeApply(tree);
}
@Override
public void visitTypeParameter(JCTypeParameter tree) {
outputCeylonPosition(tree);
super.visitTypeParameter(tree);
}
@Override
public void visitWildcard(JCWildcard tree) {
outputCeylonPosition(tree);
super.visitWildcard(tree);
}
@Override
public void visitTypeBoundKind(TypeBoundKind tree) {
outputCeylonPosition(tree);
super.visitTypeBoundKind(tree);
}
@Override
public void visitErroneous(JCErroneous tree) {
outputCeylonPosition(tree);
super.visitErroneous(tree);
}
@Override
public void visitLetExpr(LetExpr tree) {
outputCeylonPosition(tree);
super.visitLetExpr(tree);
}
@Override
public void visitModifiers(JCModifiers mods) {
outputCeylonPosition(mods);
super.visitModifiers(mods);
}
@Override
public void visitAnnotation(JCAnnotation tree) {
outputCeylonPosition(tree);
super.visitAnnotation(tree);
}
@Override
public void visitTree(JCTree tree) {
outputCeylonPosition(tree);
super.visitTree(tree);
}
};
printer.visitTopLevel(unit);
return writer.toString();
}
Aggregations