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

Print this page




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


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



 247             log.error(pos, "cant.assign.val.to.final.var", v);
 248         }
 249     }

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


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




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




 393         Env<AttrContext> prevEnv = this.env;
 394         int prevPkind = this.pkind;
 395         Type prevPt = this.pt;

 396         try {
 397             this.env = env;
 398             this.pkind = pkind;
 399             this.pt = pt;

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

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




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


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















 984         // Attribute body
 985         attribStat(tree.body, env.dup(tree, env.info.dup()));

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


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


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









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




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


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


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


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


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