Skip to content

Commit

Permalink
Use the right type provider based on the feature set of the library
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
bwilkerson authored and commit-bot@chromium.org committed Jun 5, 2019
1 parent bbf0055 commit 9efd0fa
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 15 deletions.
27 changes: 24 additions & 3 deletions pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -62,7 +63,7 @@ class LibraryAnalyzer {
final AnalysisContext _context;
final ElementResynthesizer _resynthesizer;
final LinkedElementFactory _elementFactory;
final TypeProvider _typeProvider;
TypeProvider _typeProvider;

final TypeSystem _typeSystem;
LibraryElement _libraryElement;
Expand Down Expand Up @@ -97,8 +98,7 @@ class LibraryAnalyzer {
this._inheritance,
this._library,
this._resourceProvider)
: _typeProvider = _context.typeProvider,
_typeSystem = _context.typeSystem;
: _typeSystem = _context.typeSystem;

/**
* Compute analysis results for all units of the library.
Expand All @@ -124,7 +124,19 @@ class LibraryAnalyzer {
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);
});

Expand Down Expand Up @@ -724,6 +736,15 @@ class LibraryAnalyzer {
}
}

/// 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.
Expand Down
31 changes: 20 additions & 11 deletions pkg/analyzer/lib/src/generated/error_verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2340,7 +2340,12 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
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(
Expand Down Expand Up @@ -4570,17 +4575,20 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
/**
* 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;
DartType type = getStaticType(expression);
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(
Expand All @@ -4590,16 +4598,19 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {

/**
* 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);
}
}
}

Expand Down Expand Up @@ -4677,8 +4688,6 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
* 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 ||
Expand Down
16 changes: 15 additions & 1 deletion pkg/analyzer/lib/src/generated/resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
@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);
}
Expand Down Expand Up @@ -3396,6 +3396,13 @@ class NonNullableTypeProvider extends TypeProviderImpl {
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);
Expand Down Expand Up @@ -7413,6 +7420,13 @@ class TypeProviderImpl extends TypeProviderBase {
_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;

Expand Down

0 comments on commit 9efd0fa

Please sign in to comment.