Handle _FROM_DEFERRED_LIBRARY codes for ui as code

Change-Id: Ie75eea20cd692331c25e2bb20bc11db30fbd749a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/96851
Commit-Queue: Mike Fairhurst <mfairhurst@google.com>
Auto-Submit: Mike Fairhurst <mfairhurst@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 1fc81eb..8642f19 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -228,6 +228,8 @@
   CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT,
   CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
+  CompileTimeErrorCode.NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
+  CompileTimeErrorCode.NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
   CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT,
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index cec76ec..f3c1805 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -578,11 +578,28 @@
     this.forSet = false,
   });
 
+  ErrorCode get _fromDeferredErrorCode {
+    if (forList) {
+      return CompileTimeErrorCode
+          .NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY;
+    } else if (forSet) {
+      return CompileTimeErrorCode
+          .NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY;
+    }
+
+    return null;
+  }
+
   bool verify(CollectionElement element) {
     if (element is Expression) {
       var value = verifier._validate(element, errorCode);
       if (value == null) return false;
 
+      if (_fromDeferredErrorCode != null) {
+        verifier._reportErrorIfFromDeferredLibrary(
+            element, _fromDeferredErrorCode);
+      }
+
       if (forList) {
         return _validateListExpression(element, value);
       }
@@ -602,6 +619,11 @@
       // The errors have already been reported.
       if (conditionBool == null) return false;
 
+      verifier._reportErrorIfFromDeferredLibrary(
+          element.condition,
+          CompileTimeErrorCode
+              .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY);
+
       var thenValid = true;
       var elseValid = true;
       if (conditionBool) {
@@ -623,6 +645,11 @@
       var value = verifier._validate(element.expression, errorCode);
       if (value == null) return false;
 
+      verifier._reportErrorIfFromDeferredLibrary(
+          element.expression,
+          CompileTimeErrorCode
+              .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY);
+
       if (forList || forSet) {
         return _validateListOrSetSpread(element, value);
       }
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 03b8654..ec5fe7b 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2243,6 +2243,22 @@
           correction: "Try removing the keyword 'const' from the set literal.");
 
   static const CompileTimeErrorCode
+      NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY =
+      const CompileTimeErrorCode(
+          'NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY',
+          "Constant values from a deferred library can't be spread into a "
+          "const literal.",
+          correction: "Try making the deferred import non-deferred.");
+
+  static const CompileTimeErrorCode
+      NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY =
+      const CompileTimeErrorCode(
+          'NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY',
+          "Constant values from a deferred library can't be used as values in "
+          "an if condition inside a const collection literal.",
+          correction: "Try making the deferred import non-deferred.");
+
+  static const CompileTimeErrorCode
       NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY',
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart
new file mode 100644
index 0000000..2da7688
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(NonConstantIfElementConditionFromDeferredLibraryTest);
+  });
+}
+
+@reflectiveTest
+class NonConstantIfElementConditionFromDeferredLibraryTest
+    extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [
+      EnableString.control_flow_collections,
+      EnableString.spread_collections
+    ];
+
+  test_inList_deferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const bool c = true;''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return const [if(a.c) 0];
+}''', [
+      CompileTimeErrorCode
+          .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_inList_nonConst() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const bool c = true;''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return [if(a.c) 0];
+}''');
+  }
+
+  test_inList_notDeferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const bool c = true;''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' as a;
+f() {
+  return const [if(a.c) 0];
+}''');
+  }
+
+  test_inMap_deferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const bool c = true;''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return const {if(a.c) 0 : 0};
+}''', [
+      CompileTimeErrorCode
+          .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_inMap_notConst() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const bool c = true;''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return {if(a.c) 0 : 0};
+}''');
+  }
+
+  test_inMap_notDeferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const bool c = true;''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' as a;
+f() {
+  return const {if(a.c) 0 : 0};
+}''');
+  }
+
+  test_inSet_deferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const bool c = true;''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return const {if(a.c) 0};
+}''', [
+      CompileTimeErrorCode
+          .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_inSet_notConst() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const bool c = true;''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return {if(a.c) 0};
+}''');
+  }
+
+  test_inSet_notDeferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const bool c = true;''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' as a;
+f() {
+  return const {if(a.c) 0};
+}''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart
new file mode 100644
index 0000000..c7f752bd
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(NonConstantSpreadExpressionFromDeferredLibraryTest);
+  });
+}
+
+@reflectiveTest
+class NonConstantSpreadExpressionFromDeferredLibraryTest
+    extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [
+      EnableString.control_flow_collections,
+      EnableString.spread_collections
+    ];
+
+  test_inList_deferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const List c = [];''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return const [...a.c];
+}''', [
+      CompileTimeErrorCode.NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_inList_deferred_notConst() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const List c = [];''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return [...a.c];
+}''');
+  }
+
+  test_inList_notDeferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const List c = [];''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' as a;
+f() {
+  return const [...a.c];
+}''');
+  }
+
+  test_inMap_deferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const Map c = <int, int>{};''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return const {...a.c};
+}''', [
+      CompileTimeErrorCode.NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_inMap_notConst() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const Map c = <int, int>{};''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return {...a.c};
+}''');
+  }
+
+  test_inMap_notDeferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const Map c = <int, int>{};''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' as a;
+f() {
+  return const {...a.c};
+}''');
+  }
+
+  test_inSet_deferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const Set c = <int>{};''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return const {...a.c};
+}''', [
+      CompileTimeErrorCode.NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_inSet_notConst() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const Set c = <int>{};''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' deferred as a;
+f() {
+  return {...a.c};
+}''');
+  }
+
+  test_inSet_notDeferred() async {
+    newFile(convertPath('/test/lib/lib1.dart'), content: r'''
+const Set c = <int>{};''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' as a;
+f() {
+  return const {...a.c};
+}''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 1068979..357bdaa 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -48,6 +48,8 @@
 import 'must_be_immutable_test.dart' as must_be_immutable;
 import 'must_call_super_test.dart' as must_call_super;
 import 'non_bool_condition_test.dart' as non_bool_condition;
+import 'non_constant_if_element_condition_from_deferred_library_test.dart'
+    as non_constant_if_element_condition_from_deferred_library;
 import 'non_constant_list_element_from_deferred_library_test.dart'
     as non_constant_list_element_from_deferred_library;
 import 'non_constant_list_element_test.dart' as non_constant_list_element;
@@ -61,6 +63,8 @@
 import 'non_constant_set_element_from_deferred_library_test.dart'
     as non_constant_set_element_from_deferred_library;
 import 'non_constant_set_element_test.dart' as non_constant_set_element;
+import 'non_constant_spread_expression_from_deferred_library_test.dart'
+    as non_constant_spread_expression_from_deferred_library;
 import 'not_iterable_spread_test.dart' as not_iterable_spread;
 import 'not_map_spread_test.dart' as not_map_spread;
 import 'sdk_version_async_exported_from_core_test.dart'
@@ -135,6 +139,7 @@
     must_be_immutable.main();
     must_call_super.main();
     non_bool_condition.main();
+    non_constant_if_element_condition_from_deferred_library.main();
     non_constant_list_element.main();
     non_constant_list_element_from_deferred_library.main();
     non_constant_map_key.main();
@@ -144,6 +149,7 @@
     non_constant_map_value_from_deferred_library.main();
     non_constant_set_element.main();
     non_constant_set_element_from_deferred_library.main();
+    non_constant_spread_expression_from_deferred_library.main();
     not_iterable_spread.main();
     not_map_spread.main();
     sdk_version_async_exported_from_core.main();