use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Check method checkCompatibleSupertypes.
/** Check that all abstract methods implemented by a class are
* mutually compatible.
* @param pos Position to be used for error reporting.
* @param c The class whose interfaces are checked.
*/
void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
List<Type> supertypes = types.interfaces(c);
Type supertype = types.supertype(c);
if (supertype.tag == CLASS && (supertype.tsym.flags() & ABSTRACT) != 0)
supertypes = supertypes.prepend(supertype);
for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
if (allowGenerics && !l.head.getTypeArguments().isEmpty() && !checkCompatibleAbstracts(pos, l.head, l.head, c))
return;
for (List<Type> m = supertypes; m != l; m = m.tail) if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
return;
}
checkCompatibleConcretes(pos, c);
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Check method isOverrider.
/** Is s a method symbol that overrides a method in a superclass? */
boolean isOverrider(Symbol s) {
if (s.kind != MTH || s.isStatic())
return false;
MethodSymbol m = (MethodSymbol) s;
TypeSymbol owner = (TypeSymbol) m.owner;
for (Type sup : types.closure(owner.type)) {
if (sup == owner.type)
// skip "this"
continue;
Scope scope = sup.tsym.members();
for (Scope.Entry e = scope.lookup(m.name); e.scope != null; e = e.next()) {
if (!e.sym.isStatic() && m.overrides(e.sym, owner, types, true))
return true;
}
}
return false;
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Infer method instantiatePolymorphicSignatureInstance.
/**
* Compute a synthetic method type corresponding to the requested polymorphic
* method signature. The target return type is computed from the immediately
* enclosing scope surrounding the polymorphic-signature call.
*/
Type instantiatePolymorphicSignatureInstance(Env<AttrContext> env, Type site, Name name, // sig. poly. method or null if none
MethodSymbol spMethod, List<Type> argtypes) {
final Type restype;
switch(env.next.tree.getTag()) {
case JCTree.TYPECAST:
JCTypeCast castTree = (JCTypeCast) env.next.tree;
restype = (TreeInfo.skipParens(castTree.expr) == env.tree) ? castTree.clazz.type : syms.objectType;
break;
case JCTree.EXEC:
JCTree.JCExpressionStatement execTree = (JCTree.JCExpressionStatement) env.next.tree;
restype = (TreeInfo.skipParens(execTree.expr) == env.tree) ? syms.voidType : syms.objectType;
break;
default:
restype = syms.objectType;
}
List<Type> paramtypes = Type.map(argtypes, implicitArgType);
List<Type> exType = spMethod != null ? spMethod.getThrownTypes() : // make it throw all exceptions
List.of(syms.throwableType);
MethodType mtype = new MethodType(paramtypes, restype, exType, syms.methodClass);
return mtype;
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
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.getTag() == JCTree.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();
// Add the necessary members for the EnumCompatibleMode
if (target.compilerBootstrap(tree.sym)) {
addEnumCompatibleMembers(tree);
}
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Attr method visitApply.
/** Visitor method for method invocations.
* NOTE: The method part of an application will have in its type field
* the return type of the method, not the method's type itself!
*/
public void visitApply(JCMethodInvocation tree) {
// The local environment of a method application is
// a new environment nested in the current one.
Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
// The types of the actual method arguments.
List<Type> argtypes;
// The types of the actual method type arguments.
List<Type> typeargtypes = null;
Name methName = TreeInfo.name(tree.meth);
boolean isConstructorCall = methName == names._this || methName == names._super;
if (isConstructorCall) {
// Check that this is the first statement in a constructor.
if (checkFirstConstructorStat(tree, env)) {
// Record the fact
// that this is a constructor call (using isSelfCall).
localEnv.info.isSelfCall = true;
// Attribute arguments, yielding list of argument types.
argtypes = attribArgs(tree.args, localEnv);
typeargtypes = attribTypes(tree.typeargs, localEnv);
// Variable `site' points to the class in which the called
// constructor is defined.
Type site = env.enclClass.sym.type;
if (methName == names._super) {
if (site == syms.objectType) {
log.error(tree.meth.pos(), "no.superclass", site);
site = types.createErrorType(syms.objectType);
} else {
site = types.supertype(site);
}
}
if (site.tag == CLASS) {
Type encl = site.getEnclosingType();
while (encl != null && encl.tag == TYPEVAR) encl = encl.getUpperBound();
if (encl.tag == CLASS) {
if (tree.meth.getTag() == JCTree.SELECT) {
JCTree qualifier = ((JCFieldAccess) tree.meth).selected;
// We are seeing a prefixed call, of the form
// <expr>.super(...).
// Check that the prefix expression conforms
// to the outer instance type of the class.
chk.checkRefType(qualifier.pos(), attribExpr(qualifier, localEnv, encl));
} else if (methName == names._super) {
// qualifier omitted; check for existence
// of an appropriate implicit qualifier.
rs.resolveImplicitThis(tree.meth.pos(), localEnv, site, true);
}
} else if (tree.meth.getTag() == JCTree.SELECT) {
log.error(tree.meth.pos(), "illegal.qual.not.icls", site.tsym);
}
// prefix the implicit String and int parameters
if (site.tsym == syms.enumSym && allowEnums)
argtypes = argtypes.prepend(syms.intType).prepend(syms.stringType);
// Resolve the called constructor under the assumption
// that we are referring to a superclass instance of the
// current instance (JLS ???).
boolean selectSuperPrev = localEnv.info.selectSuper;
localEnv.info.selectSuper = true;
localEnv.info.varArgs = false;
Symbol sym = rs.resolveConstructor(tree.meth.pos(), localEnv, site, argtypes, typeargtypes);
localEnv.info.selectSuper = selectSuperPrev;
// Set method symbol to resolved constructor...
TreeInfo.setSymbol(tree.meth, sym);
// ...and check that it is legal in the current context.
// (this will also set the tree's type)
Type mpt = newMethTemplate(argtypes, typeargtypes);
checkId(tree.meth, site, sym, localEnv, MTH, mpt, tree.varargsElement != null);
}
// Otherwise, `site' is an error type and we do nothing
}
result = tree.type = syms.voidType;
} else {
// Otherwise, we are seeing a regular method call.
// Attribute the arguments, yielding list of argument types, ...
argtypes = attribArgs(tree.args, localEnv);
typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
// ... and attribute the method using as a prototype a methodtype
// whose formal argument types is exactly the list of actual
// arguments (this will also set the method symbol).
Type mpt = newMethTemplate(argtypes, typeargtypes);
localEnv.info.varArgs = false;
Type mtype = attribExpr(tree.meth, localEnv, mpt);
if (localEnv.info.varArgs)
Assert.check(mtype.isErroneous() || tree.varargsElement != null);
// Compute the result type.
Type restype = mtype.getReturnType();
if (restype.tag == WILDCARD)
throw new AssertionError(mtype);
// the same as static type of the array being cloned
if (tree.meth.getTag() == JCTree.SELECT && allowCovariantReturns && methName == names.clone && types.isArray(((JCFieldAccess) tree.meth).selected.type))
restype = ((JCFieldAccess) tree.meth).selected.type;
// as a special case, x.getClass() has type Class<? extends |X|>
if (allowGenerics && methName == names.getClass && tree.args.isEmpty()) {
Type qualifier = (tree.meth.getTag() == JCTree.SELECT) ? ((JCFieldAccess) tree.meth).selected.type : env.enclClass.sym.type;
restype = new ClassType(restype.getEnclosingType(), List.<Type>of(new WildcardType(types.erasure(qualifier), BoundKind.EXTENDS, syms.boundClass)), restype.tsym);
}
chk.checkRefTypes(tree.typeargs, typeargtypes);
// Check that value of resulting type is admissible in the
// current context. Also, capture the return type
result = check(tree, capture(restype), VAL, pkind, pt);
}
chk.validate(tree.typeargs, localEnv);
}
Aggregations