use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class Lower method visitMethodDefInternal.
// where
private void visitMethodDefInternal(JCMethodDecl tree) {
if (tree.name == names.init && (currentClass.isInner() || currentClass.isLocal())) {
// We are seeing a constructor of an inner class.
MethodSymbol m = tree.sym;
// Push a new proxy scope for constructor parameters.
// and create definitions for any this$n and proxy parameters.
proxies = proxies.dup(m);
List<VarSymbol> prevOuterThisStack = outerThisStack;
List<VarSymbol> fvs = freevars(currentClass);
JCVariableDecl otdef = null;
if (currentClass.hasOuterInstance())
otdef = outerThisDef(tree.pos, m);
List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER);
// Recursively translate result type, parameters and thrown list.
tree.restype = translate(tree.restype);
tree.params = translateVarDefs(tree.params);
tree.thrown = translate(tree.thrown);
// when compiling stubs, don't process body
if (tree.body == null) {
result = tree;
return;
}
// Add this$n (if needed) in front of and free variables behind
// constructor parameter list.
tree.params = tree.params.appendList(fvdefs);
if (currentClass.hasOuterInstance())
tree.params = tree.params.prepend(otdef);
// If this is an initial constructor, i.e., it does not start with
// this(...), insert initializers for this$n and proxies
// before (pre-1.4, after) the call to superclass constructor.
JCStatement selfCall = translate(tree.body.stats.head);
List<JCStatement> added = List.nil();
if (fvs.nonEmpty()) {
List<Type> addedargtypes = List.nil();
for (List<VarSymbol> l = fvs; l.nonEmpty(); l = l.tail) {
if (TreeInfo.isInitialConstructor(tree)) {
final Name pName = proxyName(l.head.name);
m.capturedLocals = m.capturedLocals.append((VarSymbol) (proxies.lookup(pName).sym));
added = added.prepend(initField(tree.body.pos, pName));
}
addedargtypes = addedargtypes.prepend(l.head.erasure(types));
}
Type olderasure = m.erasure(types);
m.erasure_field = new MethodType(olderasure.getParameterTypes().appendList(addedargtypes), olderasure.getReturnType(), olderasure.getThrownTypes(), syms.methodClass);
}
if (currentClass.hasOuterInstance() && TreeInfo.isInitialConstructor(tree)) {
added = added.prepend(initOuterThis(tree.body.pos));
}
// pop local variables from proxy stack
proxies = proxies.leave();
// recursively translate following local statements and
// combine with this- or super-call
List<JCStatement> stats = translate(tree.body.stats.tail);
if (target.initializeFieldsBeforeSuper())
tree.body.stats = stats.prepend(selfCall).prependList(added);
else
tree.body.stats = stats.prependList(added).prepend(selfCall);
outerThisStack = prevOuterThisStack;
} else {
Map<Symbol, Symbol> prevLambdaTranslationMap = lambdaTranslationMap;
try {
lambdaTranslationMap = (tree.sym.flags() & SYNTHETIC) != 0 && tree.sym.name.startsWith(names.lambda) ? makeTranslationMap(tree) : null;
super.visitMethodDef(tree);
} finally {
lambdaTranslationMap = prevLambdaTranslationMap;
}
}
result = tree;
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class Lower method unbox.
/**
* Unbox an object to a primitive value.
*/
JCExpression unbox(JCExpression tree, Type primitive) {
Type unboxedType = types.unboxedType(tree.type);
if (unboxedType.hasTag(NONE)) {
unboxedType = primitive;
if (!unboxedType.isPrimitive())
throw new AssertionError(unboxedType);
make_at(tree.pos());
tree = make.TypeCast(types.boxedClass(unboxedType).type, tree);
} else {
// There must be a conversion from unboxedType to primitive.
if (!types.isSubtype(unboxedType, primitive))
throw new AssertionError(tree);
}
make_at(tree.pos());
Symbol valueSym = lookupMethod(tree.pos(), // x.intValue()
unboxedType.tsym.name.append(names.Value), tree.type, List.<Type>nil());
return make.App(make.Select(tree, valueSym));
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class Lower method visitEnumDef.
/**
* Translate an enum class.
*/
private void visitEnumDef(JCClassDecl tree) {
make_at(tree.pos());
// add the supertype, if needed
if (tree.extending == null)
tree.extending = make.Type(types.supertype(tree.type));
// classOfType adds a cache field to tree.defs unless
// target.hasClassLiterals().
JCExpression e_class = classOfType(tree.sym.type, tree.pos()).setType(types.erasure(syms.classType));
// process each enumeration constant, adding implicit constructor parameters
int nextOrdinal = 0;
ListBuffer<JCExpression> values = new ListBuffer<JCExpression>();
ListBuffer<JCTree> enumDefs = new ListBuffer<JCTree>();
ListBuffer<JCTree> otherDefs = new ListBuffer<JCTree>();
for (List<JCTree> defs = tree.defs; defs.nonEmpty(); defs = defs.tail) {
if (defs.head.hasTag(VARDEF) && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) {
JCVariableDecl var = (JCVariableDecl) defs.head;
visitEnumConstantDef(var, nextOrdinal++);
values.append(make.QualIdent(var.sym));
enumDefs.append(var);
} else {
otherDefs.append(defs.head);
}
}
// private static final T[] #VALUES = { a, b, c };
Name valuesName = names.fromString(target.syntheticNameChar() + "VALUES");
while (// avoid name clash
tree.sym.members().lookup(valuesName).scope != null) valuesName = names.fromString(valuesName + "" + target.syntheticNameChar());
Type arrayType = new ArrayType(types.erasure(tree.type), syms.arrayClass);
VarSymbol valuesVar = new VarSymbol(PRIVATE | FINAL | STATIC | SYNTHETIC, valuesName, arrayType, tree.type.tsym);
JCNewArray newArray = make.NewArray(make.Type(types.erasure(tree.type)), List.<JCExpression>nil(), values.toList());
newArray.type = arrayType;
enumDefs.append(make.VarDef(valuesVar, newArray));
tree.sym.members().enter(valuesVar);
Symbol valuesSym = lookupMethod(tree.pos(), names.values, tree.type, List.<Type>nil());
List<JCStatement> valuesBody;
if (useClone()) {
// return (T[]) $VALUES.clone();
JCTypeCast valuesResult = make.TypeCast(valuesSym.type.getReturnType(), make.App(make.Select(make.Ident(valuesVar), syms.arrayCloneMethod)));
valuesBody = List.<JCStatement>of(make.Return(valuesResult));
} else {
// template: T[] $result = new T[$values.length];
Name resultName = names.fromString(target.syntheticNameChar() + "result");
while (// avoid name clash
tree.sym.members().lookup(resultName).scope != null) resultName = names.fromString(resultName + "" + target.syntheticNameChar());
VarSymbol resultVar = new VarSymbol(FINAL | SYNTHETIC, resultName, arrayType, valuesSym);
JCNewArray resultArray = make.NewArray(make.Type(types.erasure(tree.type)), List.of(make.Select(make.Ident(valuesVar), syms.lengthVar)), null);
resultArray.type = arrayType;
JCVariableDecl decl = make.VarDef(resultVar, resultArray);
// template: System.arraycopy($VALUES, 0, $result, 0, $VALUES.length);
if (systemArraycopyMethod == null) {
systemArraycopyMethod = new MethodSymbol(PUBLIC | STATIC, names.fromString("arraycopy"), new MethodType(List.<Type>of(syms.objectType, syms.intType, syms.objectType, syms.intType, syms.intType), syms.voidType, List.<Type>nil(), syms.methodClass), syms.systemType.tsym);
}
JCStatement copy = make.Exec(make.App(make.Select(make.Ident(syms.systemType.tsym), systemArraycopyMethod), List.of(make.Ident(valuesVar), make.Literal(0), make.Ident(resultVar), make.Literal(0), make.Select(make.Ident(valuesVar), syms.lengthVar))));
// template: return $result;
JCStatement ret = make.Return(make.Ident(resultVar));
valuesBody = List.<JCStatement>of(decl, copy, ret);
}
JCMethodDecl valuesDef = make.MethodDef((MethodSymbol) valuesSym, make.Block(0, valuesBody));
enumDefs.append(valuesDef);
if (debugLower)
System.err.println(tree.sym + ".valuesDef = " + valuesDef);
/**
* The template for the following code is:
*
* public static E valueOf(String name) {
* return (E)Enum.valueOf(E.class, name);
* }
*
* where E is tree.sym
*/
MethodSymbol valueOfSym = lookupMethod(tree.pos(), names.valueOf, tree.sym.type, List.of(syms.stringType));
Assert.check((valueOfSym.flags() & STATIC) != 0);
VarSymbol nameArgSym = valueOfSym.params.head;
JCIdent nameVal = make.Ident(nameArgSym);
JCStatement enum_ValueOf = make.Return(make.TypeCast(tree.sym.type, makeCall(make.Ident(syms.enumSym), names.valueOf, List.of(e_class, nameVal))));
JCMethodDecl valueOf = make.MethodDef(valueOfSym, make.Block(0, List.of(enum_ValueOf)));
nameVal.sym = valueOf.params.head.sym;
if (debugLower)
System.err.println(tree.sym + ".valueOf = " + valueOf);
enumDefs.append(valueOf);
enumDefs.appendList(otherDefs.toList());
tree.defs = enumDefs.toList();
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class Lower method visitNewClass.
public void visitNewClass(JCNewClass tree) {
ClassSymbol c = (ClassSymbol) tree.constructor.owner;
// Box arguments, if necessary
boolean isEnum = (tree.constructor.owner.flags() & ENUM) != 0;
List<Type> argTypes = tree.constructor.type.getParameterTypes();
if (isEnum)
argTypes = argTypes.prepend(syms.intType).prepend(syms.stringType);
tree.args = boxArgs(argTypes, tree.args, tree.varargsElement);
tree.varargsElement = null;
// explicit constructor arguments.
if (c.isLocal()) {
tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
}
// If an access constructor is used, append null as a last argument.
Symbol constructor = accessConstructor(tree.pos(), tree.constructor);
if (constructor != tree.constructor) {
tree.args = tree.args.append(makeNull());
tree.constructor = constructor;
}
// correct outer instance as first argument.
if (c.hasOuterInstance()) {
JCExpression thisArg;
if (tree.encl != null) {
thisArg = attr.makeNullCheck(translate(tree.encl));
thisArg.type = tree.encl.type;
} else if (c.isLocal()) {
// local class
thisArg = makeThis(tree.pos(), c.type.getEnclosingType().tsym);
} else {
// nested class
thisArg = makeOwnerThis(tree.pos(), c, false);
}
tree.args = tree.args.prepend(thisArg);
}
tree.encl = null;
// than the class or interface following new.
if (tree.def != null) {
translate(tree.def);
tree.clazz = access(make_at(tree.clazz.pos()).Ident(tree.def.sym));
tree.def = null;
} else {
tree.clazz = access(c, tree.clazz, enclOp, false);
}
result = tree;
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class MemberEnter method importNamedStatic.
/**
* Import statics types of a given name. Non-types are handled in Attr.
* @param pos Position to be used for error reporting.
* @param tsym The class from which the name is imported.
* @param name The (simple) name being imported.
* @param env The environment containing the named import
* scope to add to.
*/
private void importNamedStatic(final DiagnosticPosition pos, final TypeSymbol tsym, final Name name, final Env<AttrContext> env) {
if (tsym.kind != TYP) {
log.error(DiagnosticFlag.RECOVERABLE, pos, "static.imp.only.classes.and.interfaces");
return;
}
final Scope toScope = env.toplevel.namedImportScope;
final PackageSymbol packge = env.toplevel.packge;
final TypeSymbol origin = tsym;
// enter imported types immediately
new Object() {
Set<Symbol> processed = new HashSet<Symbol>();
void importFrom(TypeSymbol tsym) {
if (tsym == null || !processed.add(tsym))
return;
// also import inherited names
importFrom(types.supertype(tsym.type).tsym);
for (Type t : types.interfaces(tsym.type)) importFrom(t.tsym);
for (Scope.Entry e = tsym.members().lookup(name); e.scope != null; e = e.next()) {
Symbol sym = e.sym;
if (sym.isStatic() && sym.kind == TYP && staticImportAccessible(sym, packge) && sym.isMemberOf(origin, types) && chk.checkUniqueStaticImport(pos, sym, toScope))
toScope.enter(sym, sym.owner.members(), origin.members(), true);
}
}
}.importFrom(tsym);
// enter non-types before annotations that might use them
annotate.earlier(new Annotate.Worker() {
Set<Symbol> processed = new HashSet<Symbol>();
boolean found = false;
public String toString() {
return "import static " + tsym + "." + name;
}
void importFrom(TypeSymbol tsym) {
if (tsym == null || !processed.add(tsym))
return;
// also import inherited names
importFrom(types.supertype(tsym.type).tsym);
for (Type t : types.interfaces(tsym.type)) importFrom(t.tsym);
for (Scope.Entry e = tsym.members().lookup(name); e.scope != null; e = e.next()) {
Symbol sym = e.sym;
if (sym.isStatic() && staticImportAccessible(sym, packge) && sym.isMemberOf(origin, types)) {
found = true;
if (sym.kind != TYP) {
toScope.enter(sym, sym.owner.members(), origin.members(), true);
}
}
}
}
public void run() {
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
try {
importFrom(tsym);
if (!found) {
log.error(pos, "cant.resolve.location", KindName.STATIC, name, List.<Type>nil(), List.<Type>nil(), Kinds.typeKindName(tsym.type), tsym.type);
}
} finally {
log.useSource(prev);
}
}
});
}
Aggregations