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