use of com.sun.tools.javac.tree.JCTree 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);
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class Attr method attribClassBody.
/** Finish the attribution of a class. */
private void attribClassBody(Env<AttrContext> env, ClassSymbol c) {
JCClassDecl tree = (JCClassDecl) env.tree;
Assert.check(c == tree.sym);
// Validate annotations
chk.validateAnnotations(tree.mods.annotations, c);
// Validate type parameters, supertype and interfaces.
attribBounds(tree.typarams);
if (!c.isAnonymous()) {
//already checked if anonymous
chk.validate(tree.typarams, env);
chk.validate(tree.extending, env);
chk.validate(tree.implementing, env);
}
// methods or unimplemented methods of an implemented interface.
if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
if (!relax)
chk.checkAllDefined(tree.pos(), c);
}
if ((c.flags() & ANNOTATION) != 0) {
if (tree.implementing.nonEmpty())
log.error(tree.implementing.head.pos(), "cant.extend.intf.annotation");
if (tree.typarams.nonEmpty())
log.error(tree.typarams.head.pos(), "intf.annotation.cant.have.type.params");
} else {
// Check that all extended classes and interfaces
// are compatible (i.e. no two define methods with same arguments
// yet different return types). (JLS 8.4.6.3)
chk.checkCompatibleSupertypes(tree.pos(), c.type);
}
// Check that class does not import the same parameterized interface
// with two different argument lists.
chk.checkClassBounds(tree.pos(), c.type);
tree.type = c.type;
for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail) {
Assert.checkNonNull(env.info.scope.lookup(l.head.name).scope);
}
// Check that a generic class doesn't extend Throwable
if (!sourceLanguage.isCeylon() && !c.type.allparams().isEmpty() && types.isSubtype(c.type, syms.throwableType))
log.error(tree.extending.pos(), "generic.throwable");
// Check that all methods which implement some
// method conform to the method they implement.
chk.checkImplementations(tree);
//check that a resource implementing AutoCloseable cannot throw InterruptedException
checkAutoCloseable(tree.pos(), env, c.type);
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
// Attribute declaration
attribStat(l.head, env);
// Make an exception for static constants.
if (c.owner.kind != PCK && ((c.flags() & STATIC) == 0 || c.name == names.empty) && (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) {
Symbol sym = null;
if (l.head.getTag() == JCTree.VARDEF)
sym = ((JCVariableDecl) l.head).sym;
if (sym == null || sym.kind != VAR || ((VarSymbol) sym).getConstValue() == null)
log.error(l.head.pos(), "icls.cant.have.static.decl", c);
}
}
// Check for cycles among non-initial constructors.
chk.checkCyclicConstructors(tree);
// Check for cycles among annotation elements.
chk.checkNonCyclicElements(tree);
// Check for proper use of serialVersionUID
if (env.info.lint.isEnabled(LintCategory.SERIAL) && isSerializable(c) && (c.flags() & Flags.ENUM) == 0 && (c.flags() & ABSTRACT) == 0) {
checkSerialVersionUID(tree, c);
}
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class Attr method visitTry.
public void visitTry(JCTry tree) {
// Create a new local environment with a local
Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
boolean isTryWithResource = tree.resources.nonEmpty();
// Create a nested environment for attributing the try block if needed
Env<AttrContext> tryEnv = isTryWithResource ? env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) : localEnv;
// Attribute resource declarations
for (JCTree resource : tree.resources) {
if (resource.getTag() == JCTree.VARDEF) {
attribStat(resource, tryEnv);
chk.checkType(resource, resource.type, syms.autoCloseableType, "try.not.applicable.to.type");
//check that resource type cannot throw InterruptedException
checkAutoCloseable(resource.pos(), localEnv, resource.type);
VarSymbol var = (VarSymbol) TreeInfo.symbolFor(resource);
var.setData(ElementKind.RESOURCE_VARIABLE);
} else {
attribExpr(resource, tryEnv, syms.autoCloseableType, "try.not.applicable.to.type");
}
}
// Attribute body
attribStat(tree.body, tryEnv);
if (isTryWithResource)
tryEnv.info.scope.leave();
// Attribute catch clauses
for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
JCCatch c = l.head;
Env<AttrContext> catchEnv = localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
Type ctype = attribStat(c.param, catchEnv);
if (TreeInfo.isMultiCatch(c)) {
//multi-catch parameter is implicitly marked as final
c.param.sym.flags_field |= FINAL | UNION;
}
if (c.param.sym.kind == Kinds.VAR) {
c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
}
chk.checkType(c.param.vartype.pos(), chk.checkClassType(c.param.vartype.pos(), ctype), syms.throwableType);
attribStat(c.body, catchEnv);
catchEnv.info.scope.leave();
}
// Attribute finalizer
if (tree.finalizer != null)
attribStat(tree.finalizer, localEnv);
localEnv.info.scope.leave();
result = null;
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class Flow method analyzeTree.
/**************************************************************************
* main method
*************************************************************************/
/** Perform definite assignment/unassignment analysis on a tree.
*/
public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
try {
attrEnv = env;
JCTree tree = env.tree;
this.make = make;
inits = new Bits();
uninits = new Bits();
uninitsTry = new Bits();
initsWhenTrue = initsWhenFalse = uninitsWhenTrue = uninitsWhenFalse = null;
if (vars == null)
vars = new VarSymbol[32];
else
for (int i = 0; i < vars.length; i++) vars[i] = null;
firstadr = 0;
nextadr = 0;
pendingExits = new ListBuffer<PendingExit>();
preciseRethrowTypes = new HashMap<Symbol, List<Type>>();
alive = true;
this.thrown = this.caught = null;
this.classDef = null;
unrefdResources = new Scope(env.enclClass.sym);
scan(tree);
} finally {
// note that recursive invocations of this method fail hard
inits = uninits = uninitsTry = null;
initsWhenTrue = initsWhenFalse = uninitsWhenTrue = uninitsWhenFalse = null;
if (vars != null)
for (int i = 0; i < vars.length; i++) vars[i] = null;
firstadr = 0;
nextadr = 0;
pendingExits = null;
this.make = null;
this.thrown = this.caught = null;
this.classDef = null;
unrefdResources = null;
}
}
use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.
the class Flow method visitAssign.
public void visitAssign(JCAssign tree) {
JCTree lhs = TreeInfo.skipParens(tree.lhs);
if (!(lhs instanceof JCIdent))
scanExpr(lhs);
scanExpr(tree.rhs);
letInit(lhs);
}
Aggregations