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