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),
|