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

Print this page




 175      * Switch: name of source level; used for error reporting.
 176      */
 177     String sourceName;
 178 
 179     /** Check kind and type of given tree against protokind and prototype.
 180      *  If check succeeds, store type in tree and return it.
 181      *  If check fails, store errType in tree and return it.
 182      *  No checks are performed if the prototype is a method type.
 183      *  It is not necessary in this case since we know that kind and type
 184      *  are correct.
 185      *
 186      *  @param tree     The tree whose kind and type is checked
 187      *  @param owntype  The computed type of the tree
 188      *  @param ownkind  The computed kind of the tree
 189      *  @param pkind    The expected kind (or: protokind) of the tree
 190      *  @param pt       The expected type (or: prototype) of the tree
 191      */
 192     Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) {
 193         if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) {
 194             if ((ownkind & ~pkind) == 0) {
 195                 owntype = chk.checkType(tree.pos(), owntype, pt);
 196             } else {
 197                 log.error(tree.pos(), "unexpected.type",
 198                           kindNames(pkind),
 199                           kindName(ownkind));
 200                 owntype = types.createErrorType(owntype);
 201             }
 202         }
 203         tree.type = owntype;
 204         return owntype;
 205     }
 206 
 207     /** Is given blank final variable assignable, i.e. in a scope where it
 208      *  may be assigned to even though it is final?
 209      *  @param v      The blank final variable.
 210      *  @param env    The current environment.
 211      */
 212     boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) {
 213         Symbol owner = env.info.scope.owner;
 214            // owner refers to the innermost variable, method or
 215            // initializer block declaration at this point.


 222              &&
 223              v.owner == owner.owner
 224              &&
 225              ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
 226     }
 227 
 228     /** Check that variable can be assigned to.
 229      *  @param pos    The current source code position.
 230      *  @param v      The assigned varaible
 231      *  @param base   If the variable is referred to in a Select, the part
 232      *                to the left of the `.', null otherwise.
 233      *  @param env    The current environment.
 234      */
 235     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
 236         if ((v.flags() & FINAL) != 0 &&
 237             ((v.flags() & HASINIT) != 0
 238              ||
 239              !((base == null ||
 240                (base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) &&
 241                isAssignableAsBlankFinal(v, env)))) {



 242             log.error(pos, "cant.assign.val.to.final.var", v);
 243         }
 244     }

 245 
 246     /** Does tree represent a static reference to an identifier?
 247      *  It is assumed that tree is either a SELECT or an IDENT.
 248      *  We have to weed out selects from non-type names here.
 249      *  @param tree    The candidate tree.
 250      */
 251     boolean isStaticReference(JCTree tree) {
 252         if (tree.getTag() == JCTree.SELECT) {
 253             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
 254             if (lsym == null || lsym.kind != TYP) {
 255                 return false;
 256             }
 257         }
 258         return true;
 259     }
 260 
 261     /** Is this symbol a type?
 262      */
 263     static boolean isType(Symbol sym) {
 264         return sym != null && sym.kind == TYP;


 355         }
 356     }
 357 
 358 
 359 /* ************************************************************************
 360  * Visitor methods
 361  *************************************************************************/
 362 
 363     /** Visitor argument: the current environment.
 364      */
 365     Env<AttrContext> env;
 366 
 367     /** Visitor argument: the currently expected proto-kind.
 368      */
 369     int pkind;
 370 
 371     /** Visitor argument: the currently expected proto-type.
 372      */
 373     Type pt;
 374 




 375     /** Visitor result: the computed type.
 376      */
 377     Type result;
 378 
 379     /** Visitor method: attribute a tree, catching any completion failure
 380      *  exceptions. Return the tree's type.
 381      *
 382      *  @param tree    The tree to be visited.
 383      *  @param env     The environment visitor argument.
 384      *  @param pkind   The protokind visitor argument.
 385      *  @param pt      The prototype visitor argument.
 386      */
 387     Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt) {




 388         Env<AttrContext> prevEnv = this.env;
 389         int prevPkind = this.pkind;
 390         Type prevPt = this.pt;

 391         try {
 392             this.env = env;
 393             this.pkind = pkind;
 394             this.pt = pt;

 395             tree.accept(this);
 396             if (tree == breakTree)
 397                 throw new BreakAttr(env);
 398             return result;
 399         } catch (CompletionFailure ex) {
 400             tree.type = syms.errType;
 401             return chk.completionError(tree.pos(), ex);
 402         } finally {
 403             this.env = prevEnv;
 404             this.pkind = prevPkind;
 405             this.pt = prevPt;

 406         }
 407     }
 408 
 409     /** Derived visitor method: attribute an expression tree.
 410      */
 411     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
 412         return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType);
 413     }
 414 




 415     /** Derived visitor method: attribute an expression tree with
 416      *  no constraints on the computed type.
 417      */
 418     Type attribExpr(JCTree tree, Env<AttrContext> env) {
 419         return attribTree(tree, env, VAL, Type.noType);
 420     }
 421 
 422     /** Derived visitor method: attribute a type tree.
 423      */
 424     Type attribType(JCTree tree, Env<AttrContext> env) {
 425         Type result = attribType(tree, env, Type.noType);
 426         return result;
 427     }
 428 
 429     /** Derived visitor method: attribute a type tree.
 430      */
 431     Type attribType(JCTree tree, Env<AttrContext> env, Type pt) {
 432         Type result = attribTree(tree, env, TYP, pt);
 433         return result;
 434     }


 959         for (Scope.Entry e = enumType.tsym.members().lookup(name);
 960              e.scope != null; e = e.next()) {
 961             if (e.sym.kind == VAR) {
 962                 Symbol s = ident.sym = e.sym;
 963                 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
 964                 ident.type = s.type;
 965                 return ((s.flags_field & Flags.ENUM) == 0)
 966                     ? null : s;
 967             }
 968         }
 969         return null;
 970     }
 971 
 972     public void visitSynchronized(JCSynchronized tree) {
 973         chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
 974         attribStat(tree.body, env);
 975         result = null;
 976     }
 977 
 978     public void visitTry(JCTry tree) {


















 979         // Attribute body
 980         attribStat(tree.body, env.dup(tree, env.info.dup()));


 981 
 982         // Attribute catch clauses
 983         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
 984             JCCatch c = l.head;
 985             Env<AttrContext> catchEnv =
 986                 env.dup(c, env.info.dup(env.info.scope.dup()));
 987             Type ctype = attribStat(c.param, catchEnv);
 988             if (TreeInfo.isMultiCatch(c)) {
 989                 //check that multi-catch parameter is marked as final
 990                 if ((c.param.sym.flags() & FINAL) == 0) {
 991                     log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym);
 992                 }
 993                 c.param.sym.flags_field = c.param.sym.flags() | DISJOINT;
 994             }
 995             if (c.param.type.tsym.kind == Kinds.VAR) {
 996                 c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
 997             }
 998             chk.checkType(c.param.vartype.pos(),
 999                           chk.checkClassType(c.param.vartype.pos(), ctype),
1000                           syms.throwableType);
1001             attribStat(c.body, catchEnv);
1002             catchEnv.info.scope.leave();
1003         }
1004 
1005         // Attribute finalizer
1006         if (tree.finalizer != null) attribStat(tree.finalizer, env);


1007         result = null;
1008     }
1009 
1010     public void visitConditional(JCConditional tree) {
1011         attribExpr(tree.cond, env, syms.booleanType);
1012         attribExpr(tree.truepart, env);
1013         attribExpr(tree.falsepart, env);
1014         result = check(tree,
1015                        capture(condType(tree.pos(), tree.cond.type,
1016                                         tree.truepart.type, tree.falsepart.type)),
1017                        VAL, pkind, pt);
1018     }
1019     //where
1020         /** Compute the type of a conditional expression, after
1021          *  checking that it exists. See Spec 15.25.
1022          *
1023          *  @param pos      The source position to be used for
1024          *                  error diagnostics.
1025          *  @param condtype The type of the expression's condition.
1026          *  @param thentype The type of the expression's then-part.


2122 
2123         if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR) {
2124             while (site.tag == TYPEVAR) site = site.getUpperBound();
2125             site = capture(site);
2126         }
2127 
2128         // If that symbol is a variable, ...
2129         if (sym.kind == VAR) {
2130             VarSymbol v = (VarSymbol)sym;
2131 
2132             // ..., evaluate its initializer, if it has one, and check for
2133             // illegal forward reference.
2134             checkInit(tree, env, v, true);
2135 
2136             // If we are expecting a variable (as opposed to a value), check
2137             // that the variable is assignable in the current environment.
2138             if (pkind == VAR)
2139                 checkAssignable(tree.pos(), v, tree.selected, env);
2140         }
2141 









2142         // Disallow selecting a type from an expression
2143         if (isType(sym) && (sitesym==null || (sitesym.kind&(TYP|PCK)) == 0)) {
2144             tree.type = check(tree.selected, pt,
2145                               sitesym == null ? VAL : sitesym.kind, TYP|PCK, pt);
2146         }
2147 
2148         if (isType(sitesym)) {
2149             if (sym.name == names._this) {
2150                 // If `C' is the currently compiled class, check that
2151                 // C.this' does not appear in a call to a super(...)
2152                 if (env.info.isSelfCall &&
2153                     site.tsym == env.enclClass.sym) {
2154                     chk.earlyRefError(tree.pos(), sym);
2155                 }
2156             } else {
2157                 // Check if type-qualified fields or methods are static (JLS)
2158                 if ((sym.flags() & STATIC) == 0 &&
2159                     sym.name != names._super &&
2160                     (sym.kind == VAR || sym.kind == MTH)) {
2161                     rs.access(rs.new StaticError(sym),




 175      * Switch: name of source level; used for error reporting.
 176      */
 177     String sourceName;
 178 
 179     /** Check kind and type of given tree against protokind and prototype.
 180      *  If check succeeds, store type in tree and return it.
 181      *  If check fails, store errType in tree and return it.
 182      *  No checks are performed if the prototype is a method type.
 183      *  It is not necessary in this case since we know that kind and type
 184      *  are correct.
 185      *
 186      *  @param tree     The tree whose kind and type is checked
 187      *  @param owntype  The computed type of the tree
 188      *  @param ownkind  The computed kind of the tree
 189      *  @param pkind    The expected kind (or: protokind) of the tree
 190      *  @param pt       The expected type (or: prototype) of the tree
 191      */
 192     Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) {
 193         if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) {
 194             if ((ownkind & ~pkind) == 0) {
 195                 owntype = chk.checkType(tree.pos(), owntype, pt, errKey);
 196             } else {
 197                 log.error(tree.pos(), "unexpected.type",
 198                           kindNames(pkind),
 199                           kindName(ownkind));
 200                 owntype = types.createErrorType(owntype);
 201             }
 202         }
 203         tree.type = owntype;
 204         return owntype;
 205     }
 206 
 207     /** Is given blank final variable assignable, i.e. in a scope where it
 208      *  may be assigned to even though it is final?
 209      *  @param v      The blank final variable.
 210      *  @param env    The current environment.
 211      */
 212     boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) {
 213         Symbol owner = env.info.scope.owner;
 214            // owner refers to the innermost variable, method or
 215            // initializer block declaration at this point.


 222              &&
 223              v.owner == owner.owner
 224              &&
 225              ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
 226     }
 227 
 228     /** Check that variable can be assigned to.
 229      *  @param pos    The current source code position.
 230      *  @param v      The assigned varaible
 231      *  @param base   If the variable is referred to in a Select, the part
 232      *                to the left of the `.', null otherwise.
 233      *  @param env    The current environment.
 234      */
 235     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
 236         if ((v.flags() & FINAL) != 0 &&
 237             ((v.flags() & HASINIT) != 0
 238              ||
 239              !((base == null ||
 240                (base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) &&
 241                isAssignableAsBlankFinal(v, env)))) {
 242             if (v.isResourceVariable()) { //TWR resource
 243                 log.error(pos, "twr.resource.may.not.be.assigned", v);
 244             } else {
 245                 log.error(pos, "cant.assign.val.to.final.var", v);
 246             }
 247         }
 248     }
 249 
 250     /** Does tree represent a static reference to an identifier?
 251      *  It is assumed that tree is either a SELECT or an IDENT.
 252      *  We have to weed out selects from non-type names here.
 253      *  @param tree    The candidate tree.
 254      */
 255     boolean isStaticReference(JCTree tree) {
 256         if (tree.getTag() == JCTree.SELECT) {
 257             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
 258             if (lsym == null || lsym.kind != TYP) {
 259                 return false;
 260             }
 261         }
 262         return true;
 263     }
 264 
 265     /** Is this symbol a type?
 266      */
 267     static boolean isType(Symbol sym) {
 268         return sym != null && sym.kind == TYP;


 359         }
 360     }
 361 
 362 
 363 /* ************************************************************************
 364  * Visitor methods
 365  *************************************************************************/
 366 
 367     /** Visitor argument: the current environment.
 368      */
 369     Env<AttrContext> env;
 370 
 371     /** Visitor argument: the currently expected proto-kind.
 372      */
 373     int pkind;
 374 
 375     /** Visitor argument: the currently expected proto-type.
 376      */
 377     Type pt;
 378 
 379     /** Visitor argument: the error key to be generated when a type error occurs
 380      */
 381     String errKey;
 382 
 383     /** Visitor result: the computed type.
 384      */
 385     Type result;
 386 
 387     /** Visitor method: attribute a tree, catching any completion failure
 388      *  exceptions. Return the tree's type.
 389      *
 390      *  @param tree    The tree to be visited.
 391      *  @param env     The environment visitor argument.
 392      *  @param pkind   The protokind visitor argument.
 393      *  @param pt      The prototype visitor argument.
 394      */
 395     Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt) {
 396         return attribTree(tree, env, pkind, pt, "incompatible.types");
 397     }
 398 
 399     Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt, String errKey) {
 400         Env<AttrContext> prevEnv = this.env;
 401         int prevPkind = this.pkind;
 402         Type prevPt = this.pt;
 403         String prevErrKey = this.errKey;
 404         try {
 405             this.env = env;
 406             this.pkind = pkind;
 407             this.pt = pt;
 408             this.errKey = errKey;
 409             tree.accept(this);
 410             if (tree == breakTree)
 411                 throw new BreakAttr(env);
 412             return result;
 413         } catch (CompletionFailure ex) {
 414             tree.type = syms.errType;
 415             return chk.completionError(tree.pos(), ex);
 416         } finally {
 417             this.env = prevEnv;
 418             this.pkind = prevPkind;
 419             this.pt = prevPt;
 420             this.errKey = prevErrKey;
 421         }
 422     }
 423 
 424     /** Derived visitor method: attribute an expression tree.
 425      */
 426     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
 427         return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType);
 428     }
 429 
 430     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt, String key) {
 431         return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType, key);
 432     }
 433 
 434     /** Derived visitor method: attribute an expression tree with
 435      *  no constraints on the computed type.
 436      */
 437     Type attribExpr(JCTree tree, Env<AttrContext> env) {
 438         return attribTree(tree, env, VAL, Type.noType);
 439     }
 440 
 441     /** Derived visitor method: attribute a type tree.
 442      */
 443     Type attribType(JCTree tree, Env<AttrContext> env) {
 444         Type result = attribType(tree, env, Type.noType);
 445         return result;
 446     }
 447 
 448     /** Derived visitor method: attribute a type tree.
 449      */
 450     Type attribType(JCTree tree, Env<AttrContext> env, Type pt) {
 451         Type result = attribTree(tree, env, TYP, pt);
 452         return result;
 453     }


 978         for (Scope.Entry e = enumType.tsym.members().lookup(name);
 979              e.scope != null; e = e.next()) {
 980             if (e.sym.kind == VAR) {
 981                 Symbol s = ident.sym = e.sym;
 982                 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
 983                 ident.type = s.type;
 984                 return ((s.flags_field & Flags.ENUM) == 0)
 985                     ? null : s;
 986             }
 987         }
 988         return null;
 989     }
 990 
 991     public void visitSynchronized(JCSynchronized tree) {
 992         chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
 993         attribStat(tree.body, env);
 994         result = null;
 995     }
 996 
 997     public void visitTry(JCTry tree) {
 998         // Create a new local environment with a local
 999         Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
1000         boolean isTryWithResource = tree.resources.nonEmpty();
1001         // Create a nested environment for attributing the try block if needed
1002         Env<AttrContext> tryEnv = isTryWithResource ?
1003             env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
1004             localEnv;
1005         // Attribute resource declarations
1006         for (JCTree resource : tree.resources) {
1007             if (resource.getTag() == JCTree.VARDEF) {
1008                 attribStat(resource, tryEnv);
1009                 chk.checkType(resource, resource.type, syms.autoCloseableType, "twr.not.applicable.to.type");
1010                 VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
1011                 var.setData(ElementKind.RESOURCE_VARIABLE);
1012             } else {
1013                 attribExpr(resource, tryEnv, syms.autoCloseableType, "twr.not.applicable.to.type");
1014             }
1015         }
1016         // Attribute body
1017         attribStat(tree.body, tryEnv);
1018         if (isTryWithResource)
1019             tryEnv.info.scope.leave();
1020 
1021         // Attribute catch clauses
1022         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
1023             JCCatch c = l.head;
1024             Env<AttrContext> catchEnv =
1025                 localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
1026             Type ctype = attribStat(c.param, catchEnv);
1027             if (TreeInfo.isMultiCatch(c)) {
1028                 //check that multi-catch parameter is marked as final
1029                 if ((c.param.sym.flags() & FINAL) == 0) {
1030                     log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym);
1031                 }
1032                 c.param.sym.flags_field = c.param.sym.flags() | DISJOINT;
1033             }
1034             if (c.param.type.tsym.kind == Kinds.VAR) {
1035                 c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
1036             }
1037             chk.checkType(c.param.vartype.pos(),
1038                           chk.checkClassType(c.param.vartype.pos(), ctype),
1039                           syms.throwableType);
1040             attribStat(c.body, catchEnv);
1041             catchEnv.info.scope.leave();
1042         }
1043 
1044         // Attribute finalizer
1045         if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
1046 
1047         localEnv.info.scope.leave();
1048         result = null;
1049     }
1050 
1051     public void visitConditional(JCConditional tree) {
1052         attribExpr(tree.cond, env, syms.booleanType);
1053         attribExpr(tree.truepart, env);
1054         attribExpr(tree.falsepart, env);
1055         result = check(tree,
1056                        capture(condType(tree.pos(), tree.cond.type,
1057                                         tree.truepart.type, tree.falsepart.type)),
1058                        VAL, pkind, pt);
1059     }
1060     //where
1061         /** Compute the type of a conditional expression, after
1062          *  checking that it exists. See Spec 15.25.
1063          *
1064          *  @param pos      The source position to be used for
1065          *                  error diagnostics.
1066          *  @param condtype The type of the expression's condition.
1067          *  @param thentype The type of the expression's then-part.


2163 
2164         if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR) {
2165             while (site.tag == TYPEVAR) site = site.getUpperBound();
2166             site = capture(site);
2167         }
2168 
2169         // If that symbol is a variable, ...
2170         if (sym.kind == VAR) {
2171             VarSymbol v = (VarSymbol)sym;
2172 
2173             // ..., evaluate its initializer, if it has one, and check for
2174             // illegal forward reference.
2175             checkInit(tree, env, v, true);
2176 
2177             // If we are expecting a variable (as opposed to a value), check
2178             // that the variable is assignable in the current environment.
2179             if (pkind == VAR)
2180                 checkAssignable(tree.pos(), v, tree.selected, env);
2181         }
2182 
2183         if (sitesym != null &&
2184                 sitesym.kind == VAR &&
2185                 ((VarSymbol)sitesym).isResourceVariable() &&
2186                 sym.kind == MTH &&
2187                 sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true) &&
2188                 env.info.lint.isEnabled(Lint.LintCategory.ARM)) {
2189             log.warning(tree, "twr.explicit.close.call");
2190         }
2191 
2192         // Disallow selecting a type from an expression
2193         if (isType(sym) && (sitesym==null || (sitesym.kind&(TYP|PCK)) == 0)) {
2194             tree.type = check(tree.selected, pt,
2195                               sitesym == null ? VAL : sitesym.kind, TYP|PCK, pt);
2196         }
2197 
2198         if (isType(sitesym)) {
2199             if (sym.name == names._this) {
2200                 // If `C' is the currently compiled class, check that
2201                 // C.this' does not appear in a call to a super(...)
2202                 if (env.info.isSelfCall &&
2203                     site.tsym == env.enclClass.sym) {
2204                     chk.earlyRefError(tree.pos(), sym);
2205                 }
2206             } else {
2207                 // Check if type-qualified fields or methods are static (JLS)
2208                 if ((sym.flags() & STATIC) == 0 &&
2209                     sym.name != names._super &&
2210                     (sym.kind == VAR || sym.kind == MTH)) {
2211                     rs.access(rs.new StaticError(sym),