use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Types method sideCast.
private boolean sideCast(Type from, Type to, Warner warn) {
// We are casting from type $from$ to type $to$, which are
// non-final unrelated types. This method
// tries to reject a cast by transferring type parameters
// from $to$ to $from$ by common superinterfaces.
boolean reverse = false;
Type target = to;
if ((to.tsym.flags() & INTERFACE) == 0) {
Assert.check((from.tsym.flags() & INTERFACE) != 0);
reverse = true;
to = from;
from = target;
}
List<Type> commonSupers = superClosure(to, erasure(from));
boolean giveWarning = commonSupers.isEmpty();
// get a more accurate analysis
while (commonSupers.nonEmpty()) {
Type t1 = asSuper(from, commonSupers.head.tsym);
// same as asSuper(to, commonSupers.head.tsym);
Type t2 = commonSupers.head;
if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
return false;
giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
commonSupers = commonSupers.tail;
}
if (giveWarning && !isReifiable(reverse ? from : to))
warn.warn(LintCategory.UNCHECKED);
if (!allowCovariantReturns)
// reject if there is a common method signature with
// incompatible return types.
chk.checkCompatibleAbstracts(warn.pos(), from, to);
return true;
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Types method asOuterSuper.
/**
* Return the base type of t or any of its outer types that starts
* with the given symbol. If none exists, return null.
*
* @param t a type
* @param sym a symbol
*/
public Type asOuterSuper(Type t, Symbol sym) {
switch(t.tag) {
case CLASS:
do {
Type s = asSuper(t, sym);
if (s != null)
return s;
t = t.getEnclosingType();
} while (t.tag == CLASS);
return null;
case ARRAY:
return isSubtype(t, sym.type) ? sym.type : null;
case TYPEVAR:
return asSuper(t, sym);
case ERROR:
return t;
default:
return null;
}
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Types method lub.
/**
* Return the least upper bound (lub) of set of types. If the lub
* does not exist return the type of null (bottom).
*/
public Type lub(List<Type> ts) {
final int ARRAY_BOUND = 1;
final int CLASS_BOUND = 2;
int boundkind = 0;
for (Type t : ts) {
switch(t.tag) {
case CLASS:
boundkind |= CLASS_BOUND;
break;
case ARRAY:
boundkind |= ARRAY_BOUND;
break;
case TYPEVAR:
do {
t = t.getUpperBound();
} while (t.tag == TYPEVAR);
if (t.tag == ARRAY) {
boundkind |= ARRAY_BOUND;
} else {
boundkind |= CLASS_BOUND;
}
break;
default:
if (t.isPrimitive())
return syms.errType;
}
}
switch(boundkind) {
case 0:
return syms.botType;
case ARRAY_BOUND:
// calculate lub(A[], B[])
List<Type> elements = Type.map(ts, elemTypeFun);
for (Type t : elements) {
if (t.isPrimitive()) {
// if a primitive type is found, then return
// arraySuperType unless all the types are the
// same
Type first = ts.head;
for (Type s : ts.tail) {
if (!isSameType(first, s)) {
// lub(int[], B[]) is Cloneable & Serializable
return arraySuperType();
}
}
// lub(int[], int[]) is int[]
return first;
}
}
// lub(A[], B[]) is lub(A, B)[]
return new ArrayType(lub(elements), syms.arrayClass);
case CLASS_BOUND:
// calculate lub(A, B)
while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR) ts = ts.tail;
Assert.check(!ts.isEmpty());
//step 1 - compute erased candidate set (EC)
List<Type> cl = erasedSupertypes(ts.head);
for (Type t : ts.tail) {
if (t.tag == CLASS || t.tag == TYPEVAR)
cl = intersect(cl, erasedSupertypes(t));
}
//step 2 - compute minimal erased candidate set (MEC)
List<Type> mec = closureMin(cl);
//step 3 - for each element G in MEC, compute lci(Inv(G))
List<Type> candidates = List.nil();
for (Type erasedSupertype : mec) {
List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym));
for (Type t : ts) {
lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym)));
}
candidates = candidates.appendList(lci);
}
//lub = lci(Inv(G1)) & lci(Inv(G2)) & ... & lci(Inv(Gn))
return compoundMin(candidates);
default:
// calculate lub(A, B[])
List<Type> classes = List.of(arraySuperType());
for (Type t : ts) {
if (// Filter out any arrays
t.tag != ARRAY)
classes = classes.prepend(t);
}
// lub(A, B[]) is lub(A, arraySuperType)
return lub(classes);
}
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class ClassReader method readClass.
/** Read contents of a given class symbol `c'. Both external and internal
* versions of an inner class are read.
*/
void readClass(ClassSymbol c) {
ClassType ct = (ClassType) c.type;
// allocate scope for members
c.members_field = new Scope(c);
// prepare type variable table
typevars = typevars.dup(currentOwner);
if (ct.getEnclosingType().tag == CLASS)
enterTypevars(ct.getEnclosingType());
// read flags, or skip if this is an inner class
long flags = adjustClassFlags(nextChar());
if (c.owner.kind == PCK)
c.flags_field = flags;
// read own class name and check that it matches
ClassSymbol self = readClassSymbol(nextChar());
if (c != self)
throw badClassFile("class.file.wrong.class", self.flatname);
// class attributes must be read before class
// skip ahead to read class attributes
int startbp = bp;
nextChar();
char interfaceCount = nextChar();
bp += interfaceCount * 2;
char fieldCount = nextChar();
for (int i = 0; i < fieldCount; i++) skipMember();
char methodCount = nextChar();
for (int i = 0; i < methodCount; i++) skipMember();
readClassAttrs(c);
if (readAllOfClassFile) {
for (int i = 1; i < poolObj.length; i++) readPool(i);
c.pool = new Pool(poolObj.length, poolObj);
}
// reset and read rest of classinfo
bp = startbp;
int n = nextChar();
if (ct.supertype_field == null)
ct.supertype_field = (n == 0) ? Type.noType : readClassSymbol(n).erasure(types);
n = nextChar();
List<Type> is = List.nil();
for (int i = 0; i < n; i++) {
Type _inter = readClassSymbol(nextChar()).erasure(types);
is = is.prepend(_inter);
}
if (ct.interfaces_field == null)
ct.interfaces_field = is.reverse();
Assert.check(fieldCount == nextChar());
for (int i = 0; i < fieldCount; i++) enterMember(c, readField());
Assert.check(methodCount == nextChar());
for (int i = 0; i < methodCount; i++) enterMember(c, readMethod());
typevars = typevars.leave();
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class ClassReader method readEnclosingMethodAttr.
void readEnclosingMethodAttr(Symbol sym) {
// sym is a nested class with an "Enclosing Method" attribute
// remove sym from it's current owners scope and place it in
// the scope specified by the attribute
sym.owner.members().remove(sym);
ClassSymbol self = (ClassSymbol) sym;
ClassSymbol c = readClassSymbol(nextChar());
NameAndType nt = (NameAndType) readPool(nextChar());
if (c.members_field == null)
throw badClassFile("bad.enclosing.class", self, c);
MethodSymbol m = findMethod(nt, c.members_field, self.flags());
if (nt != null && m == null)
throw badClassFile("bad.enclosing.method", self);
self.name = simpleBinaryName(self.flatname, c.flatname);
self.owner = m != null ? m : c;
if (self.name.isEmpty())
self.fullname = names.empty;
else
self.fullname = ClassSymbol.formFullName(self.name, self.owner);
if (m != null) {
((ClassType) sym.type).setEnclosingType(m.type);
} else if ((self.flags_field & STATIC) == 0) {
((ClassType) sym.type).setEnclosingType(c.type);
} else {
((ClassType) sym.type).setEnclosingType(Type.noType);
}
enterTypevars(self);
if (!missingTypeVariables.isEmpty()) {
ListBuffer<Type> typeVars = new ListBuffer<Type>();
for (Type typevar : missingTypeVariables) {
typeVars.append(findTypeVar(typevar.tsym.name));
}
foundTypeVariables = typeVars.toList();
} else {
foundTypeVariables = List.nil();
}
}
Aggregations