use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class JavacType method getTypeArguments.
@Override
public List<TypeMirror> getTypeArguments() {
if (typeArguments == null) {
List<TypeMirror> args = new ArrayList<TypeMirror>(type.getTypeArguments().size());
for (Type typeArg : type.getTypeArguments()) {
args.add(new JavacType(typeArg));
}
typeArguments = Collections.unmodifiableList(args);
}
return typeArguments;
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class Lower method visitIterableForeachLoop.
/**
* A statement of the form
*
* <pre>
* for ( T v : coll ) stmt ;
* </pre>
*
* (where coll implements {@code Iterable<? extends T>}) gets translated to
*
* <pre>{@code
* for ( Iterator<? extends T> #i = coll.iterator(); #i.hasNext(); ) {
* T v = (T) #i.next();
* stmt;
* }
* }</pre>
*
* where #i is a freshly named synthetic local variable.
*/
private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
make_at(tree.expr.pos());
Type iteratorTarget = syms.objectType;
Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type), syms.iterableType.tsym);
if (iterableType.getTypeArguments().nonEmpty())
iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
Type eType = tree.expr.type;
while (eType.hasTag(TYPEVAR)) {
eType = eType.getUpperBound();
}
tree.expr.type = types.erasure(eType);
if (eType.isCompound())
tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr);
Symbol iterator = lookupMethod(tree.expr.pos(), names.iterator, eType, List.<Type>nil());
VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()), types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)), currentMethodSym);
JCStatement init = make.VarDef(itvar, make.App(make.Select(tree.expr, iterator).setType(types.erasure(iterator.type))));
Symbol hasNext = lookupMethod(tree.expr.pos(), names.hasNext, itvar.type, List.<Type>nil());
JCMethodInvocation cond = make.App(make.Select(make.Ident(itvar), hasNext));
Symbol next = lookupMethod(tree.expr.pos(), names.next, itvar.type, List.<Type>nil());
JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
if (tree.var.type.isPrimitive())
vardefinit = make.TypeCast(types.cvarUpperBound(iteratorTarget), vardefinit);
else
vardefinit = make.TypeCast(tree.var.type, vardefinit);
JCVariableDecl indexDef = (JCVariableDecl) make.VarDef(tree.var.mods, tree.var.name, tree.var.vartype, vardefinit).setType(tree.var.type);
indexDef.sym = tree.var.sym;
JCBlock body = make.Block(0, List.of(indexDef, tree.body));
body.endpos = TreeInfo.endPos(tree.body);
result = translate(make.ForLoop(List.of(init), cond, List.<JCExpressionStatement>nil(), body));
patchTargets(body, tree, result);
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class Lower method visitMethodDef.
public void visitMethodDef(JCMethodDecl tree) {
if (tree.name == names.init && (currentClass.flags_field & ENUM) != 0) {
// Add "String $enum$name, int $enum$ordinal" to the beginning of the
// argument list for each constructor of an enum.
JCVariableDecl nameParam = make_at(tree.pos()).Param(names.fromString(target.syntheticNameChar() + "enum" + target.syntheticNameChar() + "name"), syms.stringType, tree.sym);
nameParam.mods.flags |= SYNTHETIC;
nameParam.sym.flags_field |= SYNTHETIC;
JCVariableDecl ordParam = make.Param(names.fromString(target.syntheticNameChar() + "enum" + target.syntheticNameChar() + "ordinal"), syms.intType, tree.sym);
ordParam.mods.flags |= SYNTHETIC;
ordParam.sym.flags_field |= SYNTHETIC;
tree.params = tree.params.prepend(ordParam).prepend(nameParam);
MethodSymbol m = tree.sym;
m.extraParams = m.extraParams.prepend(ordParam.sym);
m.extraParams = m.extraParams.prepend(nameParam.sym);
Type olderasure = m.erasure(types);
m.erasure_field = new MethodType(olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType), olderasure.getReturnType(), olderasure.getThrownTypes(), syms.methodClass);
}
JCMethodDecl prevMethodDef = currentMethodDef;
MethodSymbol prevMethodSym = currentMethodSym;
try {
currentMethodDef = tree;
currentMethodSym = tree.sym;
visitMethodDefInternal(tree);
} finally {
currentMethodDef = prevMethodDef;
currentMethodSym = prevMethodSym;
}
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class Lower method visitArrayForeachLoop.
// where
/**
* A statement of the form
*
* <pre>
* for ( T v : arrayexpr ) stmt;
* </pre>
*
* (where arrayexpr is of an array type) gets translated to
*
* <pre>{@code
* for ( { arraytype #arr = arrayexpr;
* int #len = array.length;
* int #i = 0; };
* #i < #len; i$++ ) {
* T v = arr$[#i];
* stmt;
* }
* }</pre>
*
* where #arr, #len, and #i are freshly named synthetic local variables.
*/
private void visitArrayForeachLoop(JCEnhancedForLoop tree) {
make_at(tree.expr.pos());
VarSymbol arraycache = new VarSymbol(SYNTHETIC, names.fromString("arr" + target.syntheticNameChar()), tree.expr.type, currentMethodSym);
JCStatement arraycachedef = make.VarDef(arraycache, tree.expr);
VarSymbol lencache = new VarSymbol(SYNTHETIC, names.fromString("len" + target.syntheticNameChar()), syms.intType, currentMethodSym);
JCStatement lencachedef = make.VarDef(lencache, make.Select(make.Ident(arraycache), syms.lengthVar));
VarSymbol index = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()), syms.intType, currentMethodSym);
JCVariableDecl indexdef = make.VarDef(index, make.Literal(INT, 0));
indexdef.init.type = indexdef.type = syms.intType.constType(0);
List<JCStatement> loopinit = List.of(arraycachedef, lencachedef, indexdef);
JCBinary cond = makeBinary(LT, make.Ident(index), make.Ident(lencache));
JCExpressionStatement step = make.Exec(makeUnary(PREINC, make.Ident(index)));
Type elemtype = types.elemtype(tree.expr.type);
JCExpression loopvarinit = make.Indexed(make.Ident(arraycache), make.Ident(index)).setType(elemtype);
JCVariableDecl loopvardef = (JCVariableDecl) make.VarDef(tree.var.mods, tree.var.name, tree.var.vartype, loopvarinit).setType(tree.var.type);
loopvardef.sym = tree.var.sym;
JCBlock body = make.Block(0, List.of(loopvardef, tree.body));
result = translate(make.ForLoop(loopinit, cond, List.of(step), body));
patchTargets(body, tree, result);
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class Lower method visitApply.
public void visitApply(JCMethodInvocation tree) {
Symbol meth = TreeInfo.symbol(tree.meth);
List<Type> argtypes = meth.type.getParameterTypes();
if (allowEnums && meth.name == names.init && meth.owner == syms.enumSym)
argtypes = argtypes.tail.tail;
tree.args = boxArgs(argtypes, tree.args, tree.varargsElement);
tree.varargsElement = null;
Name methName = TreeInfo.name(tree.meth);
if (meth.name == names.init) {
// We are seeing a this(...) or super(...) constructor call.
// If an access constructor is used, append null as a last argument.
Symbol constructor = accessConstructor(tree.pos(), meth);
if (constructor != meth) {
tree.args = tree.args.append(makeNull());
TreeInfo.setSymbol(tree.meth, constructor);
}
// If we are calling a constructor of a local class, add
// free variables after explicit constructor arguments.
ClassSymbol c = (ClassSymbol) constructor.owner;
if (c.isLocal()) {
tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
}
// along the name and ordinal arguments
if ((c.flags_field & ENUM) != 0 || c.getQualifiedName() == names.java_lang_Enum) {
List<JCVariableDecl> params = currentMethodDef.params;
if (currentMethodSym.owner.hasOuterInstance())
// drop this$n
params = params.tail;
tree.args = tree.args.prepend(// ordinal
make_at(tree.pos()).Ident(params.tail.head.sym)).prepend(// name
make.Ident(params.head.sym));
}
// first argument.
if (c.hasOuterInstance()) {
JCExpression thisArg;
if (tree.meth.hasTag(SELECT)) {
thisArg = attr.makeNullCheck(translate(((JCFieldAccess) tree.meth).selected));
tree.meth = make.Ident(constructor);
((JCIdent) tree.meth).name = methName;
} else if (c.isLocal() || methName == names._this) {
// local class or this() call
thisArg = makeThis(tree.meth.pos(), c.type.getEnclosingType().tsym);
} else {
// super() call of nested class - never pick 'this'
thisArg = makeOwnerThisN(tree.meth.pos(), c, false);
}
tree.args = tree.args.prepend(thisArg);
}
} else {
// We are seeing a normal method invocation; translate this as usual.
tree.meth = translate(tree.meth);
// the method arguments to the arguments of the access method.
if (tree.meth.hasTag(APPLY)) {
JCMethodInvocation app = (JCMethodInvocation) tree.meth;
app.args = tree.args.prependList(app.args);
result = app;
return;
}
}
result = tree;
}
Aggregations