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

changeset 1297
e5cf1569d3a4
parent 1296
cddc2c894cc6
child 1313
873ddd9f4900
equal deleted inserted replaced
1296:cddc2c894cc6 1297:e5cf1569d3a4
226 * may be assigned to even though it is final? 226 * may be assigned to even though it is final?
227 * @param v The blank final variable. 227 * @param v The blank final variable.
228 * @param env The current environment. 228 * @param env The current environment.
229 */ 229 */
230 boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) { 230 boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) {
231 Symbol owner = env.info.scope.owner; 231 Symbol owner = owner(env);
232 // owner refers to the innermost variable, method or 232 // owner refers to the innermost variable, method or
233 // initializer block declaration at this point. 233 // initializer block declaration at this point.
234 return 234 return
235 v.owner == owner 235 v.owner == owner
236 || 236 ||
239 (owner.flags() & BLOCK) != 0) // i.e. we are in an initializer block 239 (owner.flags() & BLOCK) != 0) // i.e. we are in an initializer block
240 && 240 &&
241 v.owner == owner.owner 241 v.owner == owner.owner
242 && 242 &&
243 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env)); 243 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
244 }
245
246 /**
247 * Return the innermost enclosing owner symbol in a given attribution context
248 */
249 Symbol owner(Env<AttrContext> env) {
250 while (true) {
251 switch (env.tree.getTag()) {
252 case VARDEF:
253 //a field can be owner
254 VarSymbol vsym = ((JCVariableDecl)env.tree).sym;
255 if (vsym.owner.kind == TYP) {
256 return vsym;
257 }
258 break;
259 case METHODDEF:
260 //method def is always an owner
261 return ((JCMethodDecl)env.tree).sym;
262 case CLASSDEF:
263 //class def is always an owner
264 return ((JCClassDecl)env.tree).sym;
265 case BLOCK:
266 //static/instance init blocks are owner
267 Symbol blockSym = env.info.scope.owner;
268 if ((blockSym.flags() & BLOCK) != 0) {
269 return blockSym;
270 }
271 break;
272 case TOPLEVEL:
273 //toplevel is always an owner (for pkge decls)
274 return env.info.scope.owner;
275 }
276 Assert.checkNonNull(env.next);
277 env = env.next;
278 }
244 } 279 }
245 280
246 /** Check that variable can be assigned to. 281 /** Check that variable can be assigned to.
247 * @param pos The current source code position. 282 * @param pos The current source code position.
248 * @param v The assigned varaible 283 * @param v The assigned varaible
881 env.info.scope.enter(tree.sym); 916 env.info.scope.enter(tree.sym);
882 } else { 917 } else {
883 memberEnter.memberEnter(tree, env); 918 memberEnter.memberEnter(tree, env);
884 annotate.flush(); 919 annotate.flush();
885 } 920 }
886 tree.sym.flags_field |= EFFECTIVELY_FINAL;
887 } 921 }
888 922
889 VarSymbol v = tree.sym; 923 VarSymbol v = tree.sym;
890 Lint lint = env.info.lint.augment(v.attributes_field, v.flags()); 924 Lint lint = env.info.lint.augment(v.attributes_field, v.flags());
891 Lint prevLint = chk.setLint(lint); 925 Lint prevLint = chk.setLint(lint);
2185 2219
2186 // ..., evaluate its initializer, if it has one, and check for 2220 // ..., evaluate its initializer, if it has one, and check for
2187 // illegal forward reference. 2221 // illegal forward reference.
2188 checkInit(tree, env, v, false); 2222 checkInit(tree, env, v, false);
2189 2223
2190 // If symbol is a local variable accessed from an embedded
2191 // inner class check that it is final.
2192 if (v.owner.kind == MTH &&
2193 v.owner != env.info.scope.owner &&
2194 (v.flags_field & FINAL) == 0) {
2195 log.error(tree.pos(),
2196 "local.var.accessed.from.icls.needs.final",
2197 v);
2198 }
2199
2200 // If we are expecting a variable (as opposed to a value), check 2224 // If we are expecting a variable (as opposed to a value), check
2201 // that the variable is assignable in the current environment. 2225 // that the variable is assignable in the current environment.
2202 if (pkind() == VAR) 2226 if (pkind() == VAR)
2203 checkAssignable(tree.pos(), v, null, env); 2227 checkAssignable(tree.pos(), v, null, env);
2204 } 2228 }
2588 // This check applies only to class and instance 2612 // This check applies only to class and instance
2589 // variables. Local variables follow different scope rules, 2613 // variables. Local variables follow different scope rules,
2590 // and are subject to definite assignment checking. 2614 // and are subject to definite assignment checking.
2591 if ((env.info.enclVar == v || v.pos > tree.pos) && 2615 if ((env.info.enclVar == v || v.pos > tree.pos) &&
2592 v.owner.kind == TYP && 2616 v.owner.kind == TYP &&
2593 canOwnInitializer(env.info.scope.owner) && 2617 canOwnInitializer(owner(env)) &&
2594 v.owner == env.info.scope.owner.enclClass() && 2618 v.owner == env.info.scope.owner.enclClass() &&
2595 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) && 2619 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&
2596 (!env.tree.hasTag(ASSIGN) || 2620 (!env.tree.hasTag(ASSIGN) ||
2597 TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) { 2621 TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) {
2598 String suffix = (env.info.enclVar == v) ? 2622 String suffix = (env.info.enclVar == v) ?

mercurial