Use the right type provider based on the feature set of the library
Change-Id: I82a22cef142b89579c19e2063fb888e2827f2bb8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104362
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 699c335..f3b0f77 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/declared_variables.dart';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -62,7 +63,7 @@
final AnalysisContext _context;
final ElementResynthesizer _resynthesizer;
final LinkedElementFactory _elementFactory;
- final TypeProvider _typeProvider;
+ TypeProvider _typeProvider;
final TypeSystem _typeSystem;
LibraryElement _libraryElement;
@@ -97,8 +98,7 @@
this._inheritance,
this._library,
this._resourceProvider)
- : _typeProvider = _context.typeProvider,
- _typeSystem = _context.typeSystem;
+ : _typeSystem = _context.typeSystem;
/**
* Compute analysis results for all units of the library.
@@ -124,7 +124,19 @@
timerLibraryAnalyzerFreshUnit.stop();
// Resolve URIs in directives to corresponding sources.
+ FeatureSet featureSet = units[_library].featureSet;
+ _typeProvider = _context.typeProvider;
+ if (featureSet.isEnabled(Feature.non_nullable)) {
+ if (_typeProvider is! NonNullableTypeProvider) {
+ _typeProvider = NonNullableTypeProvider.from(_typeProvider);
+ }
+ } else {
+ if (_typeProvider is NonNullableTypeProvider) {
+ _typeProvider = TypeProviderImpl.from(_typeProvider);
+ }
+ }
units.forEach((file, unit) {
+ _validateFeatureSet(unit, featureSet);
_resolveUriBasedDirectives(file, unit);
});
@@ -724,6 +736,15 @@
}
}
+ /// Validate that the feature set associated with the compilation [unit] is
+ /// the same as the [expectedSet] of features supported by the library.
+ void _validateFeatureSet(CompilationUnit unit, FeatureSet expectedSet) {
+ FeatureSet actualSet = unit.featureSet;
+ if (actualSet != expectedSet) {
+ // TODO(brianwilkerson) Generate a diagnostic.
+ }
+ }
+
/**
* Check the given [directive] to see if the referenced source exists and
* report an error if it does not.
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 3791919..ca7835f 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2340,7 +2340,12 @@
featureSet: _featureSet)) {
return;
}
- _errorReporter.reportErrorForNode(errorCode, expression, arguments);
+ if (expressionType.element == type.element) {
+ _errorReporter.reportErrorForNode(
+ StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE, expression);
+ } else {
+ _errorReporter.reportErrorForNode(errorCode, expression, arguments);
+ }
}
bool _checkForAssignableExpression(
@@ -4570,8 +4575,6 @@
/**
* Verify that the given [assertion] has either a 'bool' or '() -> bool'
* condition.
- *
- * See [StaticTypeWarningCode.NON_BOOL_EXPRESSION].
*/
void _checkForNonBoolExpression(Assertion assertion) {
Expression expression = assertion.condition;
@@ -4579,8 +4582,13 @@
if (type is InterfaceType) {
if (!_typeSystem.isAssignableTo(type, _boolType,
featureSet: _featureSet)) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression);
+ if (type.element == _boolType.element) {
+ _errorReporter.reportErrorForNode(
+ StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE, expression);
+ } else {
+ _errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression);
+ }
}
} else if (type is FunctionType) {
_errorReporter.reportErrorForNode(
@@ -4590,16 +4598,19 @@
/**
* Checks to ensure that the given [expression] is assignable to bool.
- *
- * See [StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION].
*/
void _checkForNonBoolNegationExpression(Expression expression) {
DartType conditionType = getStaticType(expression);
if (conditionType != null &&
!_typeSystem.isAssignableTo(conditionType, _boolType,
featureSet: _featureSet)) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression);
+ if (conditionType.element == _boolType.element) {
+ _errorReporter.reportErrorForNode(
+ StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE, expression);
+ } else {
+ _errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression);
+ }
}
}
@@ -4677,8 +4688,6 @@
* Check for illegal derefences of nullables, ie, "unchecked" usages of
* nullable values. Note that *any* usage of a null value is an "unchecked"
* usage, because proper checks will promote the type to a non-nullable value.
- *
- * See [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]
*/
bool _checkForNullableDereference(Expression expression) {
if (expression == null ||
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 91657b9..3e549d1 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -475,7 +475,7 @@
@override
void visitFunctionExpression(FunctionExpression node) {
if (node.parent is! FunctionDeclaration) {
- _checkForMissingReturn(null, node.body, node.element, node);
+ _checkForMissingReturn(null, node.body, node.declaredElement, node);
}
super.visitFunctionExpression(node);
}
@@ -3396,6 +3396,13 @@
LibraryElement coreLibrary, LibraryElement asyncLibrary)
: super(coreLibrary, asyncLibrary);
+ /// Return a type provider initialized from the same library elements as the
+ /// [baseProvider].
+ factory NonNullableTypeProvider.from(TypeProvider baseProvider) {
+ return NonNullableTypeProvider(baseProvider.boolType.element.library,
+ baseProvider.streamType.element.library);
+ }
+
@override
InterfaceType _getType(Namespace namespace, String typeName) {
InterfaceType type = super._getType(namespace, typeName);
@@ -7413,6 +7420,13 @@
_initializeFrom(coreLibrary, asyncLibrary);
}
+ /// Return a type provider initialized from the same library elements as the
+ /// [baseProvider].
+ factory TypeProviderImpl.from(TypeProvider baseProvider) {
+ return TypeProviderImpl(baseProvider.boolType.element.library,
+ baseProvider.streamType.element.library);
+ }
+
@override
InterfaceType get boolType => _boolType;