< 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,10 +92,11 @@
     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,10 +118,11 @@
         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,29 +479,31 @@
      * 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);
+                newTree->new DeferredDiagnosticHandler(log), null);
     }
 
     JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, LocalCacheContext localCache) {
         return attribSpeculative(tree, env, resultInfo, treeCopier,
-                (newTree)->new DeferredAttrDiagHandler(log, newTree), localCache);
+                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,39 +531,10 @@
                 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.
< prev index next >