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

changeset 1238
e28a06a3c5d9
parent 1237
568e70bbd9aa
child 1268
af6a4c24f4e3
equal deleted inserted replaced
1237:568e70bbd9aa 1238:e28a06a3c5d9
40 import com.sun.tools.javac.jvm.Target; 40 import com.sun.tools.javac.jvm.Target;
41 import com.sun.tools.javac.code.Lint.LintCategory; 41 import com.sun.tools.javac.code.Lint.LintCategory;
42 import com.sun.tools.javac.code.Symbol.*; 42 import com.sun.tools.javac.code.Symbol.*;
43 import com.sun.tools.javac.tree.JCTree.*; 43 import com.sun.tools.javac.tree.JCTree.*;
44 import com.sun.tools.javac.code.Type.*; 44 import com.sun.tools.javac.code.Type.*;
45 import com.sun.tools.javac.comp.Check.CheckContext;
45 46
46 import com.sun.source.tree.IdentifierTree; 47 import com.sun.source.tree.IdentifierTree;
47 import com.sun.source.tree.MemberSelectTree; 48 import com.sun.source.tree.MemberSelectTree;
48 import com.sun.source.tree.TreeVisitor; 49 import com.sun.source.tree.TreeVisitor;
49 import com.sun.source.util.SimpleTreeVisitor; 50 import com.sun.source.util.SimpleTreeVisitor;
130 relax = (options.isSet("-retrofit") || 131 relax = (options.isSet("-retrofit") ||
131 options.isSet("-relax")); 132 options.isSet("-relax"));
132 findDiamonds = options.get("findDiamond") != null && 133 findDiamonds = options.get("findDiamond") != null &&
133 source.allowDiamond(); 134 source.allowDiamond();
134 useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning"); 135 useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
136
137 statInfo = new ResultInfo(NIL, Type.noType);
138 varInfo = new ResultInfo(VAR, Type.noType);
139 unknownExprInfo = new ResultInfo(VAL, Type.noType);
140 unknownTypeInfo = new ResultInfo(TYP, Type.noType);
135 } 141 }
136 142
137 /** Switch: relax some constraints for retrofit mode. 143 /** Switch: relax some constraints for retrofit mode.
138 */ 144 */
139 boolean relax; 145 boolean relax;
202 * @param resultInfo The expected result of the tree 208 * @param resultInfo The expected result of the tree
203 */ 209 */
204 Type check(JCTree tree, Type owntype, int ownkind, ResultInfo resultInfo) { 210 Type check(JCTree tree, Type owntype, int ownkind, ResultInfo resultInfo) {
205 if (owntype.tag != ERROR && resultInfo.pt.tag != METHOD && resultInfo.pt.tag != FORALL) { 211 if (owntype.tag != ERROR && resultInfo.pt.tag != METHOD && resultInfo.pt.tag != FORALL) {
206 if ((ownkind & ~resultInfo.pkind) == 0) { 212 if ((ownkind & ~resultInfo.pkind) == 0) {
207 owntype = chk.checkType(tree.pos(), owntype, resultInfo.pt, errKey); 213 owntype = resultInfo.check(tree, owntype);
208 } else { 214 } else {
209 log.error(tree.pos(), "unexpected.type", 215 log.error(tree.pos(), "unexpected.type",
210 kindNames(resultInfo.pkind), 216 kindNames(resultInfo.pkind),
211 kindName(ownkind)); 217 kindName(ownkind));
212 owntype = types.createErrorType(owntype); 218 owntype = types.createErrorType(owntype);
392 private BreakAttr(Env<AttrContext> env) { 398 private BreakAttr(Env<AttrContext> env) {
393 this.env = env; 399 this.env = env;
394 } 400 }
395 } 401 }
396 402
397 static class ResultInfo { 403 class ResultInfo {
398 int pkind; 404 int pkind;
399 Type pt; 405 Type pt;
406 CheckContext checkContext;
400 407
401 ResultInfo(int pkind, Type pt) { 408 ResultInfo(int pkind, Type pt) {
409 this(pkind, pt, chk.basicHandler);
410 }
411
412 protected ResultInfo(int pkind, Type pt, CheckContext checkContext) {
402 this.pkind = pkind; 413 this.pkind = pkind;
403 this.pt = pt; 414 this.pt = pt;
404 } 415 this.checkContext = checkContext;
405 } 416 }
406 417
407 private final ResultInfo statInfo = new ResultInfo(NIL, Type.noType); 418 protected Type check(DiagnosticPosition pos, Type found) {
408 private final ResultInfo varInfo = new ResultInfo(VAR, Type.noType); 419 return chk.checkType(pos, found, pt, checkContext);
409 private final ResultInfo unknownExprInfo = new ResultInfo(VAL, Type.noType); 420 }
410 private final ResultInfo unknownTypeInfo = new ResultInfo(TYP, Type.noType); 421 }
422
423 private final ResultInfo statInfo;
424 private final ResultInfo varInfo;
425 private final ResultInfo unknownExprInfo;
426 private final ResultInfo unknownTypeInfo;
411 427
412 Type pt() { 428 Type pt() {
413 return resultInfo.pt; 429 return resultInfo.pt;
414 } 430 }
415 431
426 Env<AttrContext> env; 442 Env<AttrContext> env;
427 443
428 /** Visitor argument: the currently expected attribution result. 444 /** Visitor argument: the currently expected attribution result.
429 */ 445 */
430 ResultInfo resultInfo; 446 ResultInfo resultInfo;
431
432 /** Visitor argument: the error key to be generated when a type error occurs
433 */
434 String errKey;
435 447
436 /** Visitor result: the computed type. 448 /** Visitor result: the computed type.
437 */ 449 */
438 Type result; 450 Type result;
439 451
443 * @param tree The tree to be visited. 455 * @param tree The tree to be visited.
444 * @param env The environment visitor argument. 456 * @param env The environment visitor argument.
445 * @param resultInfo The result info visitor argument. 457 * @param resultInfo The result info visitor argument.
446 */ 458 */
447 private Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) { 459 private Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
448 return attribTree(tree, env, resultInfo, "incompatible.types");
449 }
450
451 private Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, String errKey) {
452 Env<AttrContext> prevEnv = this.env; 460 Env<AttrContext> prevEnv = this.env;
453 ResultInfo prevResult = this.resultInfo; 461 ResultInfo prevResult = this.resultInfo;
454 String prevErrKey = this.errKey;
455 try { 462 try {
456 this.env = env; 463 this.env = env;
457 this.resultInfo = resultInfo; 464 this.resultInfo = resultInfo;
458 this.errKey = errKey;
459 tree.accept(this); 465 tree.accept(this);
460 if (tree == breakTree) 466 if (tree == breakTree)
461 throw new BreakAttr(env); 467 throw new BreakAttr(env);
462 return result; 468 return result;
463 } catch (CompletionFailure ex) { 469 } catch (CompletionFailure ex) {
464 tree.type = syms.errType; 470 tree.type = syms.errType;
465 return chk.completionError(tree.pos(), ex); 471 return chk.completionError(tree.pos(), ex);
466 } finally { 472 } finally {
467 this.env = prevEnv; 473 this.env = prevEnv;
468 this.resultInfo = prevResult; 474 this.resultInfo = prevResult;
469 this.errKey = prevErrKey;
470 } 475 }
471 } 476 }
472 477
473 /** Derived visitor method: attribute an expression tree. 478 /** Derived visitor method: attribute an expression tree.
474 */ 479 */
475 public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) { 480 public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
476 return attribExpr(tree, env, pt, "incompatible.types"); 481 return attribTree(tree, env, new ResultInfo(VAL, pt.tag != ERROR ? pt : Type.noType));
477 }
478
479 public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt, String key) {
480 return attribTree(tree, env, new ResultInfo(VAL, pt.tag != ERROR ? pt : Type.noType), key);
481 } 482 }
482 483
483 /** Derived visitor method: attribute an expression tree with 484 /** Derived visitor method: attribute an expression tree with
484 * no constraints on the computed type. 485 * no constraints on the computed type.
485 */ 486 */
1119 Env<AttrContext> tryEnv = isTryWithResource ? 1120 Env<AttrContext> tryEnv = isTryWithResource ?
1120 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) : 1121 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
1121 localEnv; 1122 localEnv;
1122 // Attribute resource declarations 1123 // Attribute resource declarations
1123 for (JCTree resource : tree.resources) { 1124 for (JCTree resource : tree.resources) {
1125 CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
1126 @Override
1127 public void report(DiagnosticPosition pos, Type found, Type req, JCDiagnostic details) {
1128 chk.basicHandler.report(pos, found, req, diags.fragment("try.not.applicable.to.type", found));
1129 }
1130 };
1131 ResultInfo twrResult = new ResultInfo(VAL, syms.autoCloseableType, twrContext);
1124 if (resource.hasTag(VARDEF)) { 1132 if (resource.hasTag(VARDEF)) {
1125 attribStat(resource, tryEnv); 1133 attribStat(resource, tryEnv);
1126 chk.checkType(resource, resource.type, syms.autoCloseableType, "try.not.applicable.to.type"); 1134 twrResult.check(resource, resource.type);
1127 1135
1128 //check that resource type cannot throw InterruptedException 1136 //check that resource type cannot throw InterruptedException
1129 checkAutoCloseable(resource.pos(), localEnv, resource.type); 1137 checkAutoCloseable(resource.pos(), localEnv, resource.type);
1130 1138
1131 VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource); 1139 VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
1132 var.setData(ElementKind.RESOURCE_VARIABLE); 1140 var.setData(ElementKind.RESOURCE_VARIABLE);
1133 } else { 1141 } else {
1134 attribExpr(resource, tryEnv, syms.autoCloseableType, "try.not.applicable.to.type"); 1142 attribTree(resource, tryEnv, twrResult);
1135 } 1143 }
1136 } 1144 }
1137 // Attribute body 1145 // Attribute body
1138 attribStat(tree.body, tryEnv); 1146 attribStat(tree.body, tryEnv);
1139 if (isTryWithResource) 1147 if (isTryWithResource)
1844 result = check(tree, owntype, VAL, resultInfo); 1852 result = check(tree, owntype, VAL, resultInfo);
1845 chk.validate(tree.typeargs, localEnv); 1853 chk.validate(tree.typeargs, localEnv);
1846 } 1854 }
1847 1855
1848 Type attribDiamond(Env<AttrContext> env, 1856 Type attribDiamond(Env<AttrContext> env,
1849 JCNewClass tree, 1857 final JCNewClass tree,
1850 Type clazztype, 1858 Type clazztype,
1851 List<Type> argtypes, 1859 List<Type> argtypes,
1852 List<Type> typeargtypes) { 1860 List<Type> typeargtypes) {
1853 if (clazztype.isErroneous() || 1861 if (clazztype.isErroneous() ||
1854 clazztype.isInterface()) { 1862 clazztype.isInterface()) {
1884 localEnv.info.varArgs).getReturnType(); 1892 localEnv.info.varArgs).getReturnType();
1885 } else { 1893 } else {
1886 clazztype = syms.errType; 1894 clazztype = syms.errType;
1887 } 1895 }
1888 1896
1889 if (clazztype.tag == FORALL && !pt().isErroneous()) { 1897 if (clazztype.tag == FORALL && !resultInfo.pt.isErroneous()) {
1890 //if the resolved constructor's return type has some uninferred
1891 //type-variables, infer them using the expected type and declared
1892 //bounds (JLS 15.12.2.8).
1893 try { 1898 try {
1894 clazztype = infer.instantiateExpr((ForAll) clazztype, 1899 clazztype = resultInfo.checkContext.rawInstantiatePoly((ForAll)clazztype, pt(), Warner.noWarnings);
1895 pt().tag == NONE ? syms.objectType : pt(),
1896 Warner.noWarnings);
1897 } catch (Infer.InferenceException ex) { 1900 } catch (Infer.InferenceException ex) {
1898 //an error occurred while inferring uninstantiated type-variables 1901 //an error occurred while inferring uninstantiated type-variables
1899 log.error(tree.clazz.pos(), 1902 resultInfo.checkContext.report(tree.clazz.pos(), clazztype, resultInfo.pt,
1900 "cant.apply.diamond.1", 1903 diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", clazztype.tsym), ex.diagnostic));
1901 diags.fragment("diamond", clazztype.tsym), 1904 }
1902 ex.diagnostic); 1905 }
1903 } 1906
1904 } 1907 return chk.checkClassType(tree.clazz.pos(), clazztype, true);
1905 return chk.checkClassType(tree.clazz.pos(),
1906 clazztype,
1907 true);
1908 } 1908 }
1909 1909
1910 /** Make an attributed null check tree. 1910 /** Make an attributed null check tree.
1911 */ 1911 */
1912 public JCExpression makeNullCheck(JCExpression arg) { 1912 public JCExpression makeNullCheck(JCExpression arg) {

mercurial