Remove CompilationUnitImpl.isNonNullableLibrary

And plumb FeatureSet into more of the analysis engine.

Change-Id: I40f7061d48c5eb2a597f95a32738bd3133fe21d3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101224
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 19b5b21..0cc6216 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.36.4-dev (not yet published)
+* Deprecated the `isNonNullableUnit` parameter of the `TypeResolverVisitor`
+  constructor.  TypeResolverVisitor should now be configured using the
+  `featureSet` parameter.
+
 ## 0.36.3
 * Deprecated `AstFactory.compilationUnit`.  In a future analyzer release, this
   method will be changed so that all its parameters are named parameters.
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 33e6df3..1de0d3f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -59,7 +59,6 @@
   final TypeProvider _typeProvider;
 
   final TypeSystem _typeSystem;
-  bool isNonNullableLibrary = false;
   LibraryElement _libraryElement;
 
   LibraryScope _libraryScope;
@@ -114,9 +113,7 @@
     for (FileState file in _library.libraryFiles) {
       units[file] = _parse(file);
     }
-    // TODO(danrubel): Verify that all units are either nullable or non-nullable
-    isNonNullableLibrary =
-        (units.values.first as CompilationUnitImpl).isNonNullable;
+    // TODO(danrubel): Verify that all units have the same @dart override
 
     // Resolve URIs in directives to corresponding sources.
     units.forEach((file, unit) {
@@ -239,7 +236,7 @@
       errorListener.onError(pendingError.toAnalysisError());
     }
 
-    unit.accept(new DeadCodeVerifier(errorReporter, isNonNullableLibrary,
+    unit.accept(new DeadCodeVerifier(errorReporter, unit.featureSet,
         typeSystem: _context.typeSystem));
 
     // Dart2js analysis.
@@ -643,14 +640,13 @@
 
     // TODO(scheglov) remove EnumMemberBuilder class
 
-    new TypeParameterBoundsResolver(
-            _context.typeSystem, _libraryElement, source, errorListener,
-            isNonNullableUnit: isNonNullableLibrary)
+    new TypeParameterBoundsResolver(_context.typeSystem, _libraryElement,
+            source, errorListener, unit.featureSet)
         .resolveTypeBounds(unit);
 
     unit.accept(new TypeResolverVisitor(
         _libraryElement, source, _typeProvider, errorListener,
-        isNonNullableUnit: isNonNullableLibrary));
+        featureSet: unit.featureSet));
 
     unit.accept(new VariableResolverVisitor(
         _libraryElement, source, _typeProvider, errorListener,
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 1eee9ae..e3064ce 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -2057,9 +2057,6 @@
   /// has not yet been performed.
   LocalVariableInfo localVariableInfo = new LocalVariableInfo();
 
-  /// Is `true` if this unit has been parsed as non-nullable.
-  final bool isNonNullable;
-
   @override
   final FeatureSet featureSet;
 
@@ -2074,9 +2071,7 @@
       List<Directive> directives,
       List<CompilationUnitMember> declarations,
       this.endToken,
-      this.featureSet)
-      : this.isNonNullable =
-            featureSet?.isEnabled(Feature.non_nullable) ?? false {
+      this.featureSet) {
     _scriptTag = _becomeParentOf(scriptTag);
     _directives = new NodeListImpl<Directive>(this, directives);
     _declarations = new NodeListImpl<CompilationUnitMember>(this, declarations);
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index dae105c..daca3c7 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -5,6 +5,7 @@
 import 'dart:collection';
 import "dart:math" as math;
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -545,7 +546,7 @@
 
   @override
   void visitCompilationUnit(CompilationUnit node) {
-    _isNonNullable = (node as CompilationUnitImpl).isNonNullable;
+    _isNonNullable = node.featureSet.isEnabled(Feature.non_nullable);
     _checkDuplicateUnitMembers(node);
     _checkForDeferredPrefixCollisions(node);
     super.visitCompilationUnit(node);
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 71c2e91..edb112e 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1485,9 +1485,10 @@
   /// Initialize a newly created dead code verifier that will report dead code
   /// to the given [errorReporter] and will use the given [typeSystem] if one is
   /// provided.
-  DeadCodeVerifier(this._errorReporter, this._isNonNullableUnit,
+  DeadCodeVerifier(this._errorReporter, FeatureSet featureSet,
       {TypeSystem typeSystem})
-      : this._typeSystem = typeSystem ?? new Dart2TypeSystem(null);
+      : this._typeSystem = typeSystem ?? new Dart2TypeSystem(null),
+        _isNonNullableUnit = featureSet.isEnabled(Feature.non_nullable);
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
@@ -6974,14 +6975,13 @@
   Scope libraryScope = null;
   TypeNameResolver typeNameResolver = null;
 
-  TypeParameterBoundsResolver(
-      this.typeSystem, this.library, this.source, this.errorListener,
-      {bool isNonNullableUnit = false})
+  TypeParameterBoundsResolver(this.typeSystem, this.library, this.source,
+      this.errorListener, FeatureSet featureSet)
       : libraryScope = new LibraryScope(library),
         typeNameResolver = new TypeNameResolver(
             typeSystem,
             typeSystem.typeProvider,
-            isNonNullableUnit,
+            featureSet.isEnabled(Feature.non_nullable),
             library,
             source,
             errorListener);
@@ -7641,19 +7641,26 @@
   /// [nameScope] is the scope used to resolve identifiers in the node that will
   /// first be visited.  If `null` or unspecified, a new [LibraryScope] will be
   /// created based on [definingLibrary] and [typeProvider].
+  ///
+  /// Note: in a future release of the analyzer, the [featureSet] parameter will
+  /// be required.
   TypeResolverVisitor(LibraryElement definingLibrary, Source source,
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
       {Scope nameScope,
-      this.isNonNullableUnit: false,
+      @Deprecated('Use featureSet instead') bool isNonNullableUnit: false,
+      FeatureSet featureSet,
       this.mode: TypeResolverMode.everything,
       bool shouldUseWithClauseInferredTypes: true,
       this.shouldSetElementSupertypes: false})
-      : super(definingLibrary, source, typeProvider, errorListener,
+      : isNonNullableUnit = featureSet?.isEnabled(Feature.non_nullable) ??
+            // ignore: deprecated_member_use_from_same_package
+            isNonNullableUnit,
+        super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope) {
     _dynamicType = typeProvider.dynamicType;
     _typeSystem = TypeSystem.create(definingLibrary.context);
     _typeNameResolver = new TypeNameResolver(_typeSystem, typeProvider,
-        isNonNullableUnit, definingLibrary, source, errorListener,
+        this.isNonNullableUnit, definingLibrary, source, errorListener,
         shouldUseWithClauseInferredTypes: shouldUseWithClauseInferredTypes);
   }
 
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 8b77137..168e9cf 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -2471,7 +2471,7 @@
         reportConstEvaluationErrors: false);
     var typeResolverVisitor = new TypeResolverVisitor(
         library, source, typeProvider, errorListener,
-        nameScope: nameScope);
+        featureSet: featureSet, nameScope: nameScope);
     var variableResolverVisitor = new VariableResolverVisitor(
         library, source, typeProvider, errorListener,
         nameScope: nameScope, localVariableInfo: LocalVariableInfo());
diff --git a/pkg/analyzer/lib/src/summary2/ast_resolver.dart b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
index a98c541..1812c3e 100644
--- a/pkg/analyzer/lib/src/summary2/ast_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
@@ -30,7 +30,7 @@
 
     var typeResolverVisitor = new TypeResolverVisitor(
         _library, source, _linker.typeProvider, errorListener,
-        nameScope: _nameScope);
+        featureSet: featureSet, nameScope: _nameScope);
     node.accept(typeResolverVisitor);
 
     var variableResolverVisitor = new VariableResolverVisitor(
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 1723adb..fdd4710 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.36.3
+version: 0.36.4-dev
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 59f614f..5a190a0 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
@@ -1173,8 +1174,12 @@
     element.definingCompilationUnit = new CompilationUnitElementImpl();
     _typeProvider = new TestTypeProvider();
     libraryScope = new LibraryScope(element);
+    // TODO(paulberry): make it possible to override the feature set so we can
+    // test NNBD features.
+    var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
     _visitor = new TypeResolverVisitor(
         element, librarySource, _typeProvider, _listener,
+        featureSet: featureSet,
         nameScope: libraryScope,
         shouldSetElementSupertypes: shouldSetElementSupertypes);
   }
@@ -1209,9 +1214,14 @@
       var libraryElement = new LibraryElementImpl.forNode(context, null, null)
         ..definingCompilationUnit = unitElement;
       var libraryScope = new LibraryScope(libraryElement);
+      // TODO(paulberry): make it possible to override the feature set so we can
+      // test NNBD features.
+      var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
       var visitor = new TypeResolverVisitor(
           libraryElement, source, _typeProvider, _listener,
-          nameScope: libraryScope, mode: TypeResolverMode.api);
+          featureSet: featureSet,
+          nameScope: libraryScope,
+          mode: TypeResolverMode.api);
       libraryScope.define(A);
       unit.accept(visitor);
     }
@@ -2080,9 +2090,14 @@
       var libraryElement = new LibraryElementImpl.forNode(context, null, null)
         ..definingCompilationUnit = unitElement;
       libraryScope = new LibraryScope(libraryElement);
+      // TODO(paulberry): make it possible to override the feature set so we can
+      // test NNBD features.
+      var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
       visitor = new TypeResolverVisitor(
           libraryElement, source, _typeProvider, _listener,
-          nameScope: libraryScope, mode: TypeResolverMode.local);
+          featureSet: featureSet,
+          nameScope: libraryScope,
+          mode: TypeResolverMode.local);
     }
 
     // Define top-level types.