use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Attr method visitMethodDef.
public void visitMethodDef(JCMethodDecl tree) {
MethodSymbol m = tree.sym;
Lint lint = env.info.lint.augment(m.attributes_field, m.flags());
Lint prevLint = chk.setLint(lint);
MethodSymbol prevMethod = chk.setMethod(m);
try {
deferredLintHandler.flush(tree.pos());
chk.checkDeprecatedAnnotation(tree.pos(), m);
attribBounds(tree.typarams);
// JLS ???
if (m.isStatic()) {
chk.checkHideClashes(tree.pos(), env.enclClass.type, m);
} else {
chk.checkOverrideClashes(tree.pos(), env.enclClass.type, m);
}
chk.checkOverride(tree, m);
// Create a new environment with local scope
// for attributing the method.
Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
localEnv.info.lint = lint;
// Enter all type parameters into the local method scope.
for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail) localEnv.info.scope.enterIfAbsent(l.head.type.tsym);
ClassSymbol owner = env.enclClass.sym;
if ((owner.flags() & ANNOTATION) != 0 && tree.params.nonEmpty())
log.error(tree.params.head.pos(), "intf.annotation.members.cant.have.params");
// Attribute all value parameters.
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
attribStat(l.head, localEnv);
}
chk.checkVarargsMethodDecl(localEnv, tree);
// Check that type parameters are well-formed.
chk.validate(tree.typarams, localEnv);
// Check that result type is well-formed.
chk.validate(tree.restype, localEnv);
// annotation method checks
if ((owner.flags() & ANNOTATION) != 0) {
// annotation method cannot have throws clause
if (tree.thrown.nonEmpty()) {
log.error(tree.thrown.head.pos(), "throws.not.allowed.in.intf.annotation");
}
// annotation method cannot declare type-parameters
if (tree.typarams.nonEmpty()) {
log.error(tree.typarams.head.pos(), "intf.annotation.members.cant.have.type.params");
}
// validate annotation method's return type (could be an annotation type)
chk.validateAnnotationType(tree.restype);
// ensure that annotation method does not clash with members of Object/Annotation
chk.validateAnnotationMethod(tree.pos(), m);
if (tree.defaultValue != null) {
// if default value is an annotation, check it is a well-formed
// annotation value (e.g. no duplicate values, no missing values, etc.)
chk.validateAnnotationTree(tree.defaultValue);
}
}
for (List<JCExpression> l = tree.thrown; l.nonEmpty(); l = l.tail) chk.checkType(l.head.pos(), l.head.type, syms.throwableType);
if (tree.body == null) {
// in a retrofit signature class.
if ((owner.flags() & INTERFACE) == 0 && (tree.mods.flags & (ABSTRACT | NATIVE)) == 0 && !relax)
log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
if (tree.defaultValue != null) {
if ((owner.flags() & ANNOTATION) == 0)
log.error(tree.pos(), "default.allowed.in.intf.annotation.member");
}
} else if ((owner.flags() & INTERFACE) != 0) {
log.error(tree.body.pos(), "intf.meth.cant.have.body");
} else if ((tree.mods.flags & ABSTRACT) != 0) {
log.error(tree.pos(), "abstract.meth.cant.have.body");
} else if ((tree.mods.flags & NATIVE) != 0) {
log.error(tree.pos(), "native.meth.cant.have.body");
} else {
// or we are compiling class java.lang.Object.
if (tree.name == names.init && owner.type != syms.objectType) {
JCBlock body = tree.body;
if (body.stats.isEmpty() || !TreeInfo.isSelfCall(names, body.stats.head)) {
body.stats = body.stats.prepend(memberEnter.SuperCall(make.at(body.pos), List.<Type>nil(), List.<JCVariableDecl>nil(), false));
} else if ((env.enclClass.sym.flags() & ENUM) != 0 && (tree.mods.flags & GENERATEDCONSTR) == 0 && TreeInfo.isSuperCall(names, body.stats.head)) {
// enum constructors are not allowed to call super
// directly, so make sure there aren't any super calls
// in enum constructors, except in the compiler
// generated one.
log.error(tree.body.stats.head.pos(), "call.to.super.not.allowed.in.enum.ctor", env.enclClass.sym);
}
}
// Attribute method body.
attribStat(tree.body, localEnv);
}
localEnv.info.scope.leave();
result = tree.type = m.type;
chk.validateAnnotations(tree.mods.annotations, m);
} finally {
chk.setLint(prevLint);
chk.setMethod(prevMethod);
}
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Attr method visitParens.
public void visitParens(JCParens tree) {
Type owntype = attribTree(tree.expr, env, pkind, pt);
result = check(tree, owntype, pkind, pkind, pt);
Symbol sym = TreeInfo.symbol(tree);
if (sym != null && (sym.kind & (TYP | PCK)) != 0)
log.error(tree.pos(), "illegal.start.of.type");
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Attr method visitAssign.
public void visitAssign(JCAssign tree) {
Type owntype = attribTree(tree.lhs, env.dup(tree), VAR, Type.noType);
Type capturedType = capture(owntype);
attribExpr(tree.rhs, env, owntype);
result = check(tree, capturedType, VAL, pkind, pt);
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Attr method selectSym.
private Symbol selectSym(JCFieldAccess tree, Symbol location, Type site, Env<AttrContext> env, Type pt, int pkind) {
DiagnosticPosition pos = tree.pos();
Name name = tree.name;
switch(site.tag) {
case PACKAGE:
return rs.access(rs.findIdentInPackage(env, site.tsym, name, pkind), pos, location, site, name, true);
case ARRAY:
case CLASS:
if (pt.tag == METHOD || pt.tag == FORALL) {
return rs.resolveQualifiedMethod(pos, env, location, site, name, pt.getParameterTypes(), pt.getTypeArguments());
} else if (name == names._this || name == names._super) {
return rs.resolveSelf(pos, env, site.tsym, name);
} else if (name == names._class) {
// In this case, we have already made sure in
// visitSelect that qualifier expression is a type.
Type t = syms.classType;
List<Type> typeargs = allowGenerics ? List.of(types.erasure(site)) : List.<Type>nil();
t = new ClassType(t.getEnclosingType(), typeargs, t.tsym);
return new VarSymbol(STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
} else {
// We are seeing a plain identifier as selector.
Symbol sym = rs.findIdentInType(env, site, name, pkind);
if ((pkind & ERRONEOUS) == 0)
sym = rs.access(sym, pos, location, site, name, true);
return sym;
}
case WILDCARD:
throw new AssertionError(tree);
case TYPEVAR:
// Normally, site.getUpperBound() shouldn't be null.
// It should only happen during memberEnter/attribBase
// when determining the super type which *must* beac
// done before attributing the type variables. In
// other words, we are seeing this illegal program:
// class B<T> extends A<T.foo> {}
Symbol sym = (site.getUpperBound() != null) ? selectSym(tree, location, capture(site.getUpperBound()), env, pt, pkind) : null;
if (sym == null) {
log.error(pos, "type.var.cant.be.deref");
return syms.errSymbol;
} else {
// Ceylon: relax the rules for private methods in wildcards, damnit, we want the private
// method to be called, not any subtype's method we can't possibly know about, this is really
// a lame Java decision.
Symbol sym2 = (!sourceLanguage.isCeylon() && (sym.flags() & Flags.PRIVATE) != 0) ? rs.new AccessError(env, site, sym) : sym;
rs.access(sym2, pos, location, site, name, true);
return sym;
}
case ERROR:
// preserve identifier names through errors
return types.createErrorType(name, site.tsym, site).tsym;
default:
// .class is allowed for these.
if (name == names._class) {
// In this case, we have already made sure in Select that
// qualifier expression is a type.
Type t = syms.classType;
Type arg = types.boxedClass(site).type;
t = new ClassType(t.getEnclosingType(), List.of(arg), t.tsym);
return new VarSymbol(STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
} else {
log.error(pos, "cant.deref", site);
return syms.errSymbol;
}
}
}
use of com.sun.tools.javac.code.Type in project ceylon-compiler by ceylon.
the class Attr method condType1.
/** Compute the type of a conditional expression, after
* checking that it exists. Does not take into
* account the special case where condition and both arms
* are constants.
*
* @param pos The source position to be used for error
* diagnostics.
* @param condtype The type of the expression's condition.
* @param thentype The type of the expression's then-part.
* @param elsetype The type of the expression's else-part.
*/
private Type condType1(DiagnosticPosition pos, Type condtype, Type thentype, Type elsetype) {
// If same type, that is the result
if (types.isSameType(thentype, elsetype))
return thentype.baseType();
Type thenUnboxed = (!allowBoxing || thentype.isPrimitive()) ? thentype : types.unboxedType(thentype);
Type elseUnboxed = (!allowBoxing || elsetype.isPrimitive()) ? elsetype : types.unboxedType(elsetype);
// arm is short, the other is char).
if (thenUnboxed.isPrimitive() && elseUnboxed.isPrimitive()) {
// that fits into the subrange, return the subrange type.
if (thenUnboxed.tag < INT && elseUnboxed.tag == INT && types.isAssignable(elseUnboxed, thenUnboxed))
return thenUnboxed.baseType();
if (elseUnboxed.tag < INT && thenUnboxed.tag == INT && types.isAssignable(thenUnboxed, elseUnboxed))
return elseUnboxed.baseType();
for (int i = BYTE; i < VOID; i++) {
Type candidate = syms.typeOfTag[i];
if (types.isSubtype(thenUnboxed, candidate) && types.isSubtype(elseUnboxed, candidate))
return candidate;
}
}
// Those were all the cases that could result in a primitive
if (allowBoxing) {
if (thentype.isPrimitive())
thentype = types.boxedClass(thentype).type;
if (elsetype.isPrimitive())
elsetype = types.boxedClass(elsetype).type;
}
if (types.isSubtype(thentype, elsetype))
return elsetype.baseType();
if (types.isSubtype(elsetype, thentype))
return thentype.baseType();
if (!allowBoxing || thentype.tag == VOID || elsetype.tag == VOID) {
log.error(pos, "neither.conditional.subtype", thentype, elsetype);
return thentype.baseType();
}
// always be possible to infer "Object" if nothing better.
return types.lub(thentype.baseType(), elsetype.baseType());
}
Aggregations