src/share/classes/com/sun/tools/javac/comp/Attr.java

Print this page

        

*** 190,200 **** * @param pt The expected type (or: prototype) of the tree */ Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) { if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) { if ((ownkind & ~pkind) == 0) { ! owntype = chk.checkType(tree.pos(), owntype, pt); } else { log.error(tree.pos(), "unexpected.type", kindNames(pkind), kindName(ownkind)); owntype = types.createErrorType(owntype); --- 190,200 ---- * @param pt The expected type (or: prototype) of the tree */ Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) { if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) { if ((ownkind & ~pkind) == 0) { ! owntype = chk.checkType(tree.pos(), owntype, pt, errKey); } else { log.error(tree.pos(), "unexpected.type", kindNames(pkind), kindName(ownkind)); owntype = types.createErrorType(owntype);
*** 237,249 **** --- 237,253 ---- ((v.flags() & HASINIT) != 0 || !((base == null || (base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) && isAssignableAsBlankFinal(v, env)))) { + if (v.isResourceVariable()) { //ARM resource + log.error(pos, "arm.resource.may.not.be.assigned", v); + } else { log.error(pos, "cant.assign.val.to.final.var", v); } } + } /** Does tree represent a static reference to an identifier? * It is assumed that tree is either a SELECT or an IDENT. * We have to weed out selects from non-type names here. * @param tree The candidate tree.
*** 370,379 **** --- 374,387 ---- /** Visitor argument: the currently expected proto-type. */ Type pt; + /** Visitor argument: the error key to be generated when a type error occurs + */ + String errKey; + /** Visitor result: the computed type. */ Type result; /** Visitor method: attribute a tree, catching any completion failure
*** 383,399 **** --- 391,413 ---- * @param env The environment visitor argument. * @param pkind The protokind visitor argument. * @param pt The prototype visitor argument. */ Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt) { + return attribTree(tree, env, pkind, pt, "incompatible.types"); + } + + Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt, String errKey) { Env<AttrContext> prevEnv = this.env; int prevPkind = this.pkind; Type prevPt = this.pt; + String prevErrKey = this.errKey; try { this.env = env; this.pkind = pkind; this.pt = pt; + this.errKey = errKey; tree.accept(this); if (tree == breakTree) throw new BreakAttr(env); return result; } catch (CompletionFailure ex) {
*** 401,419 **** --- 415,438 ---- return chk.completionError(tree.pos(), ex); } finally { this.env = prevEnv; this.pkind = prevPkind; this.pt = prevPt; + this.errKey = prevErrKey; } } /** Derived visitor method: attribute an expression tree. */ public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) { return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType); } + public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt, String key) { + return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType, key); + } + /** Derived visitor method: attribute an expression tree with * no constraints on the computed type. */ Type attribExpr(JCTree tree, Env<AttrContext> env) { return attribTree(tree, env, VAL, Type.noType);
*** 974,991 **** attribStat(tree.body, env); result = null; } public void visitTry(JCTry tree) { // Attribute body ! attribStat(tree.body, env.dup(tree, env.info.dup())); // Attribute catch clauses for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { JCCatch c = l.head; Env<AttrContext> catchEnv = ! env.dup(c, env.info.dup(env.info.scope.dup())); Type ctype = attribStat(c.param, catchEnv); if (TreeInfo.isMultiCatch(c)) { //check that multi-catch parameter is marked as final if ((c.param.sym.flags() & FINAL) == 0) { log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym); --- 993,1026 ---- attribStat(tree.body, env); result = null; } 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())); + // Create a nested environment for attributing the try block + Env<AttrContext> tryEnv = env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())); + // Attribute resource declarations + for (JCTree resource : tree.resources) { + if (resource.getTag() == JCTree.VARDEF) { + attribStat(resource, tryEnv); + chk.checkType(resource, resource.type, syms.autoCloseableType, "arm.not.applicable.to.type"); + VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource); + var.setData(ElementKind.RESOURCE_VARIABLE); + } else { + attribExpr(resource, tryEnv, syms.autoCloseableType, "arm.not.applicable.to.type"); + } + } // Attribute body ! attribStat(tree.body, tryEnv); ! 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)) { //check that multi-catch parameter is marked as final if ((c.param.sym.flags() & FINAL) == 0) { log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym);
*** 1001,1011 **** attribStat(c.body, catchEnv); catchEnv.info.scope.leave(); } // Attribute finalizer ! if (tree.finalizer != null) attribStat(tree.finalizer, env); result = null; } public void visitConditional(JCConditional tree) { attribExpr(tree.cond, env, syms.booleanType); --- 1036,1048 ---- attribStat(c.body, catchEnv); catchEnv.info.scope.leave(); } // Attribute finalizer ! if (tree.finalizer != null) attribStat(tree.finalizer, localEnv); ! ! localEnv.info.scope.leave(); result = null; } public void visitConditional(JCConditional tree) { attribExpr(tree.cond, env, syms.booleanType);
*** 2137,2146 **** --- 2174,2192 ---- // that the variable is assignable in the current environment. if (pkind == VAR) checkAssignable(tree.pos(), v, tree.selected, env); } + if (sitesym != null && + sitesym.kind == VAR && + ((VarSymbol)sitesym).isResourceVariable() && + sym.kind == MTH && + sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true) && + env.info.lint.isEnabled(Lint.LintCategory.ARM)) { + log.warning(tree, "arm.explicit.close.call"); + } + // Disallow selecting a type from an expression if (isType(sym) && (sitesym==null || (sitesym.kind&(TYP|PCK)) == 0)) { tree.type = check(tree.selected, pt, sitesym == null ? VAL : sitesym.kind, TYP|PCK, pt); }