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()) { //ARM resource
243 log.error(pos, "arm.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 // Create a nested environment for attributing the try block
1001 Env<AttrContext> tryEnv = env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup()));
1002 // Attribute resource declarations
1003 for (JCTree resource : tree.resources) {
1004 if (resource.getTag() == JCTree.VARDEF) {
1005 attribStat(resource, tryEnv);
1006 chk.checkType(resource, resource.type, syms.autoCloseableType, "arm.not.applicable.to.type");
1007 VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
1008 var.setData(ElementKind.RESOURCE_VARIABLE);
1009 } else {
1010 attribExpr(resource, tryEnv, syms.autoCloseableType, "arm.not.applicable.to.type");
1011 }
1012 }
1013 // Attribute body
1014 attribStat(tree.body, tryEnv);
1015 tryEnv.info.scope.leave();
1016
1017 // Attribute catch clauses
1018 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
1019 JCCatch c = l.head;
1020 Env<AttrContext> catchEnv =
1021 localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
1022 Type ctype = attribStat(c.param, catchEnv);
1023 if (TreeInfo.isMultiCatch(c)) {
1024 //check that multi-catch parameter is marked as final
1025 if ((c.param.sym.flags() & FINAL) == 0) {
1026 log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym);
1027 }
1028 c.param.sym.flags_field = c.param.sym.flags() | DISJOINT;
1029 }
1030 if (c.param.type.tsym.kind == Kinds.VAR) {
1031 c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
1032 }
1033 chk.checkType(c.param.vartype.pos(),
1034 chk.checkClassType(c.param.vartype.pos(), ctype),
1035 syms.throwableType);
1036 attribStat(c.body, catchEnv);
1037 catchEnv.info.scope.leave();
1038 }
1039
1040 // Attribute finalizer
1041 if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
1042
1043 localEnv.info.scope.leave();
1044 result = null;
1045 }
1046
1047 public void visitConditional(JCConditional tree) {
1048 attribExpr(tree.cond, env, syms.booleanType);
1049 attribExpr(tree.truepart, env);
1050 attribExpr(tree.falsepart, env);
1051 result = check(tree,
1052 capture(condType(tree.pos(), tree.cond.type,
1053 tree.truepart.type, tree.falsepart.type)),
1054 VAL, pkind, pt);
1055 }
1056 //where
1057 /** Compute the type of a conditional expression, after
1058 * checking that it exists. See Spec 15.25.
1059 *
1060 * @param pos The source position to be used for
1061 * error diagnostics.
1062 * @param condtype The type of the expression's condition.
1063 * @param thentype The type of the expression's then-part.
2159
2160 if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR) {
2161 while (site.tag == TYPEVAR) site = site.getUpperBound();
2162 site = capture(site);
2163 }
2164
2165 // If that symbol is a variable, ...
2166 if (sym.kind == VAR) {
2167 VarSymbol v = (VarSymbol)sym;
2168
2169 // ..., evaluate its initializer, if it has one, and check for
2170 // illegal forward reference.
2171 checkInit(tree, env, v, true);
2172
2173 // If we are expecting a variable (as opposed to a value), check
2174 // that the variable is assignable in the current environment.
2175 if (pkind == VAR)
2176 checkAssignable(tree.pos(), v, tree.selected, env);
2177 }
2178
2179 if (sitesym != null &&
2180 sitesym.kind == VAR &&
2181 ((VarSymbol)sitesym).isResourceVariable() &&
2182 sym.kind == MTH &&
2183 sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true) &&
2184 env.info.lint.isEnabled(Lint.LintCategory.ARM)) {
2185 log.warning(tree, "arm.explicit.close.call");
2186 }
2187
2188 // Disallow selecting a type from an expression
2189 if (isType(sym) && (sitesym==null || (sitesym.kind&(TYP|PCK)) == 0)) {
2190 tree.type = check(tree.selected, pt,
2191 sitesym == null ? VAL : sitesym.kind, TYP|PCK, pt);
2192 }
2193
2194 if (isType(sitesym)) {
2195 if (sym.name == names._this) {
2196 // If `C' is the currently compiled class, check that
2197 // C.this' does not appear in a call to a super(...)
2198 if (env.info.isSelfCall &&
2199 site.tsym == env.enclClass.sym) {
2200 chk.earlyRefError(tree.pos(), sym);
2201 }
2202 } else {
2203 // Check if type-qualified fields or methods are static (JLS)
2204 if ((sym.flags() & STATIC) == 0 &&
2205 sym.name != names._super &&
2206 (sym.kind == VAR || sym.kind == MTH)) {
2207 rs.access(rs.new StaticError(sym),
|