< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java

Print this page
rev 54093 : 8177068: incomplete classpath causes NPE in Flow
Summary: Undo completions that failed during speculative attribution, so that the appropriate CompletionFailures are thrown again and properly reported.
Reviewed-by: vromero

*** 92,101 **** --- 92,102 ---- final TypeMapping<Void> deferredCopier; final Types types; final Flow flow; final Names names; final TypeEnvs typeEnvs; + final DeferredCompletionFailureHandler dcfh; public static DeferredAttr instance(Context context) { DeferredAttr instance = context.get(deferredAttrKey); if (instance == null) instance = new DeferredAttr(context);
*** 117,126 **** --- 118,128 ---- types = Types.instance(context); flow = Flow.instance(context); names = Names.instance(context); stuckTree = make.Ident(names.empty).setType(Type.stuckType); typeEnvs = TypeEnvs.instance(context); + dcfh = DeferredCompletionFailureHandler.instance(context); emptyDeferredAttrContext = new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) { @Override void addDeferredAttrNode(DeferredType dt, ResultInfo ri, DeferredStuckPolicy deferredStuckPolicy) { Assert.error("Empty deferred context!");
*** 477,505 **** * restored after type-checking. All diagnostics (but critical ones) are * disabled during speculative type-checking. */ JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) { return attribSpeculative(tree, env, resultInfo, treeCopier, ! (newTree)->new DeferredAttrDiagHandler(log, newTree), null); } JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, LocalCacheContext localCache) { return attribSpeculative(tree, env, resultInfo, treeCopier, ! (newTree)->new DeferredAttrDiagHandler(log, newTree), localCache); } <Z> JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, TreeCopier<Z> deferredCopier, Function<JCTree, DeferredDiagnosticHandler> diagHandlerCreator, LocalCacheContext localCache) { final JCTree newTree = deferredCopier.copy(tree); Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner))); speculativeEnv.info.isSpeculative = true; Log.DeferredDiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator.apply(newTree); try { attr.attribTree(newTree, speculativeEnv, resultInfo); return newTree; } finally { new UnenterScanner(env.toplevel.modle).scan(newTree); log.popDiagnosticHandler(deferredDiagnosticHandler); if (localCache != null) { localCache.leave(); } --- 479,509 ---- * restored after type-checking. All diagnostics (but critical ones) are * disabled during speculative type-checking. */ JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) { return attribSpeculative(tree, env, resultInfo, treeCopier, ! newTree->new DeferredDiagnosticHandler(log), null); } JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, LocalCacheContext localCache) { return attribSpeculative(tree, env, resultInfo, treeCopier, ! newTree->new DeferredDiagnosticHandler(log), localCache); } <Z> JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, TreeCopier<Z> deferredCopier, Function<JCTree, DeferredDiagnosticHandler> diagHandlerCreator, LocalCacheContext localCache) { final JCTree newTree = deferredCopier.copy(tree); Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner))); speculativeEnv.info.isSpeculative = true; Log.DeferredDiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator.apply(newTree); + DeferredCompletionFailureHandler.Handler prevCFHandler = dcfh.setHandler(dcfh.speculativeCodeHandler); try { attr.attribTree(newTree, speculativeEnv, resultInfo); return newTree; } finally { + dcfh.setHandler(prevCFHandler); new UnenterScanner(env.toplevel.modle).scan(newTree); log.popDiagnosticHandler(deferredDiagnosticHandler); if (localCache != null) { localCache.leave(); }
*** 527,565 **** syms.removeClass(msym, csym.flatname); super.visitClassDef(tree); } } - static class DeferredAttrDiagHandler extends Log.DeferredDiagnosticHandler { - - static class PosScanner extends TreeScanner { - DiagnosticPosition pos; - boolean found = false; - - PosScanner(DiagnosticPosition pos) { - this.pos = pos; - } - - @Override - public void scan(JCTree tree) { - if (tree != null && - tree.pos() == pos) { - found = true; - } - super.scan(tree); - } - } - - DeferredAttrDiagHandler(Log log, JCTree newTree) { - super(log, d -> { - PosScanner posScanner = new PosScanner(d.getDiagnosticPosition()); - posScanner.scan(newTree); - return posScanner.found; - }); - } - } - /** * A deferred context is created on each method check. A deferred context is * used to keep track of information associated with the method check, such as * the symbol of the method being checked, the overload resolution phase, * the kind of attribution mode to be applied to deferred types and so forth. --- 531,540 ----
< prev index next >