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 scope.
1004 Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
1005 // Attribute resource declarations
1006 ListBuffer<VarSymbol> resourceVars = ListBuffer.lb();
1007 for (JCTree resource : tree.resources) {
1008 if (resource.getTag() == JCTree.VARDEF) {
1009 attribStat(resource, localEnv);
1010 chk.checkType(resource, resource.type, syms.autoCloseableType, "arm.not.applicable.to.type");
1011 VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
1012 var.setData(ElementKind.RESOURCE_VARIABLE);
1013 resourceVars.append(var);
1014 } else {
1015 attribExpr(resource, localEnv, syms.autoCloseableType, "arm.not.applicable.to.type");
1016 }
1017 }
1018 // Attribute body
1019 attribStat(tree.body, localEnv.dup(tree, localEnv.info.dup()));
1020
1021 //remove arm resource vars from local scope - such variables cannot be
1022 //accessed from catch/finally clauses
1023 for (VarSymbol resourceVar : resourceVars) {
1024 localEnv.info.scope.remove(resourceVar);
1025 }
1026
1027 // Attribute catch clauses
1028 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
1029 JCCatch c = l.head;
1030 Env<AttrContext> catchEnv =
1031 localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
1032 Type ctype = attribStat(c.param, catchEnv);
1033 if (TreeInfo.isMultiCatch(c)) {
1034 //check that multi-catch parameter is marked as final
1035 if ((c.param.sym.flags() & FINAL) == 0) {
1036 log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym);
1037 }
1038 c.param.sym.flags_field = c.param.sym.flags() | DISJOINT;
1039 }
1040 if (c.param.type.tsym.kind == Kinds.VAR) {
1041 c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
1042 }
1043 chk.checkType(c.param.vartype.pos(),
1044 chk.checkClassType(c.param.vartype.pos(), ctype),
1045 syms.throwableType);
1046 attribStat(c.body, catchEnv);
1047 catchEnv.info.scope.leave();
1048 }
1049
1050 // Attribute finalizer
1051 if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
1052
1053 localEnv.info.scope.leave();
1054 result = null;
1055 }
1056
1057 public void visitConditional(JCConditional tree) {
1058 attribExpr(tree.cond, env, syms.booleanType);
1059 attribExpr(tree.truepart, env);
1060 attribExpr(tree.falsepart, env);
1061 result = check(tree,
1062 capture(condType(tree.pos(), tree.cond.type,
1063 tree.truepart.type, tree.falsepart.type)),
1064 VAL, pkind, pt);
1065 }
1066 //where
1067 /** Compute the type of a conditional expression, after
1068 * checking that it exists. See Spec 15.25.
1069 *
1070 * @param pos The source position to be used for
1071 * error diagnostics.
1072 * @param condtype The type of the expression's condition.
1073 * @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.name == names.close &&
2188 env.info.lint.isEnabled(Lint.LintCategory.ARM)) {
2189 log.warning(tree, "arm.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),
|