use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class MemberEnter method DefaultConstructor.
/* ***************************************************************************
* tree building
****************************************************************************/
/**
* Generate default constructor for given class. For classes different
* from java.lang.Object, this is:
*
* c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
* super(x_0, ..., x_n)
* }
*
* or, if based == true:
*
* c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
* x_0.super(x_1, ..., x_n)
* }
*
* @param make The tree factory.
* @param c The class owning the default constructor.
* @param argtypes The parameter types of the constructor.
* @param thrown The thrown exceptions of the constructor.
* @param based Is first parameter a this$n?
*/
JCTree DefaultConstructor(TreeMaker make, ClassSymbol c, MethodSymbol baseInit, List<Type> typarams, List<Type> argtypes, List<Type> thrown, long flags, boolean based) {
JCTree result;
if ((c.flags() & ENUM) != 0 && (types.supertype(c.type).tsym == syms.enumSym)) {
// constructors of true enums are private
flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR;
} else
flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR;
if (c.name.isEmpty()) {
flags |= ANONCONSTR;
}
Type mType = new MethodType(argtypes, null, thrown, c);
Type initType = typarams.nonEmpty() ? new ForAll(typarams, mType) : mType;
MethodSymbol init = new MethodSymbol(flags, names.init, initType, c);
init.params = createDefaultConstructorParams(make, baseInit, init, argtypes, based);
List<JCVariableDecl> params = make.Params(argtypes, init);
List<JCStatement> stats = List.nil();
if (c.type != syms.objectType) {
stats = stats.prepend(SuperCall(make, typarams, params, based));
}
result = make.MethodDef(init, make.Block(0, stats));
return result;
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class MemberEnter method signature.
/**
* Construct method type from method signature.
* @param typarams The method's type parameters.
* @param params The method's value parameters.
* @param res The method's result type,
* null if it is a constructor.
* @param recvparam The method's receiver parameter,
* null if none given; TODO: or already set here?
* @param thrown The method's thrown exceptions.
* @param env The method's (local) environment.
*/
Type signature(MethodSymbol msym, List<JCTypeParameter> typarams, List<JCVariableDecl> params, JCTree res, JCVariableDecl recvparam, List<JCExpression> thrown, Env<AttrContext> env) {
// Enter and attribute type parameters.
List<Type> tvars = enter.classEnter(typarams, env);
attr.attribTypeVariables(typarams, env);
// Enter and attribute value parameters.
ListBuffer<Type> argbuf = new ListBuffer<Type>();
for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail) {
memberEnter(l.head, env);
argbuf.append(l.head.vartype.type);
}
// Attribute result type, if one is given.
Type restype = res == null ? syms.voidType : attr.attribType(res, env);
// Attribute receiver type, if one is given.
Type recvtype;
if (recvparam != null) {
memberEnter(recvparam, env);
recvtype = recvparam.vartype.type;
} else {
recvtype = null;
}
// Attribute thrown exceptions.
ListBuffer<Type> thrownbuf = new ListBuffer<Type>();
for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
Type exc = attr.attribType(l.head, env);
if (!exc.hasTag(TYPEVAR)) {
exc = chk.checkClassType(l.head.pos(), exc);
} else if (exc.tsym.owner == msym) {
// mark inference variables in 'throws' clause
exc.tsym.flags_field |= THROWS;
}
thrownbuf.append(exc);
}
MethodType mtype = new MethodType(argbuf.toList(), restype, thrownbuf.toList(), syms.methodClass);
mtype.recvtype = recvtype;
return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class MemberEnter method complete.
/* ********************************************************************
* Source completer
*********************************************************************/
/**
* Complete entering a class.
* @param sym The symbol of the class to be completed.
*/
public void complete(Symbol sym) throws CompletionFailure {
// Suppress some (recursive) MemberEnter invocations
if (!completionEnabled) {
// Re-install same completer for next time around and return.
Assert.check((sym.flags() & Flags.COMPOUND) == 0);
sym.completer = this;
return;
}
ClassSymbol c = (ClassSymbol) sym;
ClassType ct = (ClassType) c.type;
Env<AttrContext> env = typeEnvs.get(c);
JCClassDecl tree = (JCClassDecl) env.tree;
boolean wasFirst = isFirst;
isFirst = false;
try {
annotate.enterStart();
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
try {
// Save class environment for later member enter (2) processing.
halfcompleted.append(env);
// Mark class as not yet attributed.
c.flags_field |= UNATTRIBUTED;
// clauses have been seen.
if (c.owner.kind == PCK) {
memberEnter(env.toplevel, env.enclosing(TOPLEVEL));
todo.append(env);
}
if (c.owner.kind == TYP)
c.owner.complete();
// create an environment for evaluating the base clauses
Env<AttrContext> baseEnv = baseEnv(tree, env);
if (tree.extending != null)
typeAnnotate(tree.extending, baseEnv, sym, tree.pos());
for (JCExpression impl : tree.implementing) typeAnnotate(impl, baseEnv, sym, tree.pos());
annotate.flush();
// Determine supertype.
Type supertype = (tree.extending != null) ? attr.attribBase(tree.extending, baseEnv, true, false, true) : ((tree.mods.flags & Flags.ENUM) != 0) ? attr.attribBase(enumBase(tree.pos, c), baseEnv, true, false, false) : (c.fullname == names.java_lang_Object) ? Type.noType : syms.objectType;
ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
// Determine interfaces.
ListBuffer<Type> interfaces = new ListBuffer<Type>();
// lazy init
ListBuffer<Type> all_interfaces = null;
Set<Type> interfaceSet = new HashSet<Type>();
List<JCExpression> interfaceTrees = tree.implementing;
for (JCExpression iface : interfaceTrees) {
Type i = attr.attribBase(iface, baseEnv, false, true, true);
if (i.hasTag(CLASS)) {
interfaces.append(i);
if (all_interfaces != null)
all_interfaces.append(i);
chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
} else {
if (all_interfaces == null)
all_interfaces = new ListBuffer<Type>().appendList(interfaces);
all_interfaces.append(modelMissingTypes(i, iface, true));
}
}
if ((c.flags_field & Flags.ANNOTATION) != 0) {
ct.interfaces_field = List.of(syms.annotationType);
ct.all_interfaces_field = ct.interfaces_field;
} else {
ct.interfaces_field = interfaces.toList();
ct.all_interfaces_field = (all_interfaces == null) ? ct.interfaces_field : all_interfaces.toList();
}
if (c.fullname == names.java_lang_Object) {
if (tree.extending != null) {
chk.checkNonCyclic(tree.extending.pos(), supertype);
ct.supertype_field = Type.noType;
} else if (tree.implementing.nonEmpty()) {
chk.checkNonCyclic(tree.implementing.head.pos(), ct.interfaces_field.head);
ct.interfaces_field = List.nil();
}
}
// Annotations.
// In general, we cannot fully process annotations yet, but we
// can attribute the annotation types and then check to see if the
// @Deprecated annotation is present.
attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
if (hasDeprecatedAnnotation(tree.mods.annotations))
c.flags_field |= DEPRECATED;
annotateLater(tree.mods.annotations, baseEnv, c, tree.pos());
// class type parameters use baseEnv but everything uses env
chk.checkNonCyclicDecl(tree);
attr.attribTypeVariables(tree.typarams, baseEnv);
// Do this here, where we have the symbol.
for (JCTypeParameter tp : tree.typarams) typeAnnotate(tp, baseEnv, sym, tree.pos());
// Add default constructor if needed.
if ((c.flags() & INTERFACE) == 0 && !TreeInfo.hasConstructors(tree.defs)) {
List<Type> argtypes = List.nil();
List<Type> typarams = List.nil();
List<Type> thrown = List.nil();
long ctorFlags = 0;
boolean based = false;
boolean addConstructor = true;
JCNewClass nc = null;
if (c.name.isEmpty()) {
nc = (JCNewClass) env.next.tree;
if (nc.constructor != null) {
addConstructor = nc.constructor.kind != ERR;
Type superConstrType = types.memberType(c.type, nc.constructor);
argtypes = superConstrType.getParameterTypes();
typarams = superConstrType.getTypeArguments();
ctorFlags = nc.constructor.flags() & VARARGS;
if (nc.encl != null) {
argtypes = argtypes.prepend(nc.encl.type);
based = true;
}
thrown = superConstrType.getThrownTypes();
}
}
if (addConstructor) {
MethodSymbol basedConstructor = nc != null ? (MethodSymbol) nc.constructor : null;
JCTree constrDef = DefaultConstructor(make.at(tree.pos), c, basedConstructor, typarams, argtypes, thrown, ctorFlags, based);
tree.defs = tree.defs.prepend(constrDef);
}
}
// enter symbols for 'this' into current scope.
VarSymbol thisSym = new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
thisSym.pos = Position.FIRSTPOS;
env.info.scope.enter(thisSym);
// if this is a class, enter symbol for 'super' into current scope.
if ((c.flags_field & INTERFACE) == 0 && ct.supertype_field.hasTag(CLASS)) {
VarSymbol superSym = new VarSymbol(FINAL | HASINIT, names._super, ct.supertype_field, c);
superSym.pos = Position.FIRSTPOS;
env.info.scope.enter(superSym);
}
// name as a top-level package.
if (checkClash && c.owner.kind == PCK && c.owner != syms.unnamedPackage && reader.packageExists(c.fullname)) {
log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
}
if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 && !env.toplevel.sourcefile.isNameCompatible(c.name.toString(), JavaFileObject.Kind.SOURCE)) {
c.flags_field |= AUXILIARY;
}
} catch (CompletionFailure ex) {
chk.completionError(tree.pos(), ex);
} finally {
deferredLintHandler.setPos(prevLintPos);
log.useSource(prev);
}
// classes in a second phase.
if (wasFirst) {
try {
while (halfcompleted.nonEmpty()) {
Env<AttrContext> toFinish = halfcompleted.next();
finish(toFinish);
if (allowTypeAnnos) {
typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl) toFinish.tree);
typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl) toFinish.tree);
}
}
} finally {
isFirst = true;
}
}
} finally {
annotate.enterDone();
}
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class MemberEnter method importStaticAll.
/**
* Import all static members of a class or package on demand.
* @param pos Position to be used for error reporting.
* @param tsym The class or package the members of which are imported.
* @param env The env in which the imported classes will be entered.
*/
private void importStaticAll(int pos, final TypeSymbol tsym, Env<AttrContext> env) {
final JavaFileObject sourcefile = env.toplevel.sourcefile;
final Scope toScope = env.toplevel.starImportScope;
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);
final Scope fromScope = tsym.members();
for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
Symbol sym = e.sym;
if (sym.kind == TYP && (sym.flags() & STATIC) != 0 && staticImportAccessible(sym, packge) && sym.isMemberOf(origin, types) && !toScope.includes(sym))
toScope.enter(sym, fromScope, 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>();
public String toString() {
return "import static " + tsym + ".*" + " in " + sourcefile;
}
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);
final Scope fromScope = tsym.members();
for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
Symbol sym = e.sym;
if (sym.isStatic() && sym.kind != TYP && staticImportAccessible(sym, packge) && !toScope.includes(sym) && sym.isMemberOf(origin, types)) {
toScope.enter(sym, fromScope, origin.members(), true);
}
}
}
public void run() {
importFrom(tsym);
}
});
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.
the class Resolve method mostSpecificReturnType.
// where
Type mostSpecificReturnType(Type mt1, Type mt2) {
Type rt1 = mt1.getReturnType();
Type rt2 = mt2.getReturnType();
if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) {
// if both are generic methods, adjust return type ahead of subtyping check
rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
}
// first use subtyping, then return type substitutability
if (types.isSubtype(rt1, rt2)) {
return mt1;
} else if (types.isSubtype(rt2, rt1)) {
return mt2;
} else if (types.returnTypeSubstitutable(mt1, mt2)) {
return mt1;
} else if (types.returnTypeSubstitutable(mt2, mt1)) {
return mt2;
} else {
return null;
}
}
Aggregations