[dart2js] Ignore specific impacts in deferred_load.

Change-Id: Ide1f6b26e523c802119412f7df8da54b4681f8b2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/158640
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 129ecf0..a0395e5 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -108,6 +108,7 @@
   static const String noSoundNullSafety = '--no-sound-null-safety';
 
   static const String newDeferredSplit = '--new-deferred-split';
+  static const String noNewDeferredSplit = '--no-new-deferred-split';
   static const String reportInvalidInferredDeferredTypes =
       '--report-invalid-deferred-types';
   static const String deferClassTypes = '--defer-class-types';
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index c09c0cc..d47da8e 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -311,17 +311,21 @@
         worldImpact,
         WorldImpactVisitorImpl(
             visitStaticUse: (MemberEntity member, StaticUse staticUse) {
-          Entity usedEntity = staticUse.element;
-          if (usedEntity is MemberEntity) {
-            dependencies.addMember(usedEntity, staticUse.deferredImport);
-          } else {
-            assert(usedEntity is KLocalFunction,
-                failedAt(usedEntity, "Unexpected static use $staticUse."));
-            KLocalFunction localFunction = usedEntity;
-            // TODO(sra): Consult KClosedWorld to see if signature is needed.
-            _collectTypeDependencies(localFunction.functionType, dependencies);
-            dependencies.localFunctions.add(localFunction);
+          void processEntity() {
+            Entity usedEntity = staticUse.element;
+            if (usedEntity is MemberEntity) {
+              dependencies.addMember(usedEntity, staticUse.deferredImport);
+            } else {
+              assert(usedEntity is KLocalFunction,
+                  failedAt(usedEntity, "Unexpected static use $staticUse."));
+              KLocalFunction localFunction = usedEntity;
+              // TODO(sra): Consult KClosedWorld to see if signature is needed.
+              _collectTypeDependencies(
+                  localFunction.functionType, dependencies);
+              dependencies.localFunctions.add(localFunction);
+            }
           }
+
           switch (staticUse.kind) {
             case StaticUseKind.CONSTRUCTOR_INVOKE:
             case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
@@ -334,6 +338,7 @@
               // arguments.
               _collectTypeArgumentDependencies(
                   staticUse.type.typeArguments, dependencies);
+              processEntity();
               break;
             case StaticUseKind.STATIC_INVOKE:
             case StaticUseKind.CLOSURE_CALL:
@@ -342,8 +347,29 @@
               // arguments.
               _collectTypeArgumentDependencies(
                   staticUse.typeArguments, dependencies);
+              processEntity();
               break;
-            default:
+            case StaticUseKind.STATIC_TEAR_OFF:
+            case StaticUseKind.CLOSURE:
+            case StaticUseKind.STATIC_GET:
+            case StaticUseKind.STATIC_SET:
+              processEntity();
+              break;
+            case StaticUseKind.SUPER_TEAR_OFF:
+            case StaticUseKind.SUPER_FIELD_SET:
+            case StaticUseKind.SUPER_GET:
+            case StaticUseKind.SUPER_SETTER_SET:
+            case StaticUseKind.SUPER_INVOKE:
+            case StaticUseKind.INSTANCE_FIELD_GET:
+            case StaticUseKind.INSTANCE_FIELD_SET:
+            case StaticUseKind.FIELD_INIT:
+            case StaticUseKind.FIELD_CONSTANT_INIT:
+              // These static uses are not relevant for this algorithm.
+              break;
+            case StaticUseKind.CALL_METHOD:
+            case StaticUseKind.INLINING:
+              failedAt(element, "Unexpected static use: $staticUse.");
+              break;
           }
         }, visitTypeUse: (MemberEntity member, TypeUse typeUse) {
           void addClassIfInterfaceType(DartType t, [ImportEntity import]) {
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index f4bc3a6..40d9dc6 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -146,7 +146,9 @@
   /// When [reportInvalidInferredDeferredTypes] shows no errors, we expect this
   /// flag to produce the same or better results than the current unsound
   /// implementation.
-  bool newDeferredSplit = false;
+  bool newDeferredSplit = false; // default value.
+  bool _newDeferredSplit = false;
+  bool _noNewDeferredSplit = false;
 
   /// Show errors when a deferred type is inferred as a return type of a closure
   /// or in a type parameter. Those cases cause the compiler today to behave
@@ -443,7 +445,8 @@
           _extractStringOption(options, '--build-id=', _UNDETERMINED_BUILD_ID)
       ..compileForServer = _hasOption(options, Flags.serverMode)
       ..deferredMapUri = _extractUriOption(options, '--deferred-map=')
-      ..newDeferredSplit = _hasOption(options, Flags.newDeferredSplit)
+      .._newDeferredSplit = _hasOption(options, Flags.newDeferredSplit)
+      .._noNewDeferredSplit = _hasOption(options, Flags.noNewDeferredSplit)
       ..reportInvalidInferredDeferredTypes =
           _hasOption(options, Flags.reportInvalidInferredDeferredTypes)
       .._deferClassTypes = _hasOption(options, Flags.deferClassTypes)
@@ -556,6 +559,10 @@
       throw ArgumentError("'${Flags.deferClassTypes}' incompatible with "
           "'${Flags.noDeferClassTypes}'");
     }
+    if (_newDeferredSplit && _noNewDeferredSplit) {
+      throw ArgumentError("'${Flags.newDeferredSplit}' incompatible with "
+          "'${Flags.noNewDeferredSplit}'");
+    }
   }
 
   void deriveOptions() {
@@ -625,6 +632,9 @@
       // TODO(sra): Add a command-line flag to control this independently.
       enableNativeReturnNullAssertions = true;
     }
+
+    if (_newDeferredSplit) newDeferredSplit = true;
+    if (_noNewDeferredSplit) newDeferredSplit = false;
   }
 
   /// Returns `true` if warnings and hints are shown for all packages.