langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 13439 3025d6ac1401
parent 13438 83729994273a
child 13689 4d519199a6aa
equal deleted inserted replaced
13438:83729994273a 13439:3025d6ac1401
   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) ?