Fix nullability of inferred dynamic types
Change-Id: Ib27c5ade4a57bbfa73c528adbafaaa19be53c97c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102301
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
index ea6265c..c7d0d5f 100644
--- a/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
+++ b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
@@ -8,6 +8,7 @@
import 'package:analysis_server/src/nullability/nullability_graph.dart';
import 'package:analysis_server/src/nullability/nullability_node.dart';
import 'package:analysis_server/src/nullability/transitional_api.dart';
+import 'package:analysis_server/src/nullability/unit_propagation.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -56,7 +57,7 @@
? new DecoratedType(
DynamicTypeImpl.instance,
NullabilityNode.forInferredDynamicType(
- _graph, enclosingNode.offset),
+ _graph, _variables.constraints, enclosingNode.offset),
_graph)
: type.accept(this);
}
@@ -192,6 +193,10 @@
/// ([ConstraintVariableGatherer], which finds all the variables that need to be
/// constrained).
abstract class VariableRecorder {
+ /// Gets the [Constraints] object currently in use. Note: this will go away
+ /// when we stop using constraint variables for migration.
+ Constraints get constraints;
+
/// Associates decorated type information with the given [element].
void recordDecoratedElementType(Element element, DecoratedType type);
diff --git a/pkg/analysis_server/lib/src/nullability/nullability_node.dart b/pkg/analysis_server/lib/src/nullability/nullability_node.dart
index cc5ee45..b5c809d 100644
--- a/pkg/analysis_server/lib/src/nullability/nullability_node.dart
+++ b/pkg/analysis_server/lib/src/nullability/nullability_node.dart
@@ -46,9 +46,10 @@
/// TODO(paulberry): this should go away; we should decorate the actual
/// inferred type rather than assuming `dynamic`.
factory NullabilityNode.forInferredDynamicType(
- NullabilityGraph graph, int offset) {
+ NullabilityGraph graph, Constraints constraints, int offset) {
var node = _NullabilityNodeSimple(
TypeIsNullable(null), 'inferredDynamic($offset)');
+ constraints.record([], node._nullable);
graph.connect(NullabilityNode.always, node);
return node;
}
diff --git a/pkg/analysis_server/lib/src/nullability/transitional_api.dart b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
index ffbad45..90c0fc7 100644
--- a/pkg/analysis_server/lib/src/nullability/transitional_api.dart
+++ b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
@@ -148,7 +148,7 @@
final Variables _variables;
- final _constraints = Solver();
+ final Solver _constraints;
final NullabilityGraph _graph;
@@ -162,10 +162,11 @@
{bool permissive: false,
NullabilityMigrationAssumptions assumptions:
const NullabilityMigrationAssumptions()})
- : this._(permissive, assumptions, NullabilityGraph());
+ : this._(permissive, assumptions, NullabilityGraph(), Solver());
- NullabilityMigration._(this._permissive, this.assumptions, this._graph)
- : _variables = Variables(_graph);
+ NullabilityMigration._(
+ this._permissive, this.assumptions, this._graph, this._constraints)
+ : _variables = Variables(_graph, _constraints);
Map<Source, List<PotentialModification>> finish() {
_constraints.applyHeuristics();
@@ -275,7 +276,10 @@
final NullabilityGraph _graph;
- Variables(this._graph);
+ @override
+ final Constraints constraints;
+
+ Variables(this._graph, this.constraints);
@override
DecoratedType decoratedElementType(Element element, {bool create: false}) =>
diff --git a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
index 88cccb6..d4e2e9f 100644
--- a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
+++ b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
@@ -29,9 +29,6 @@
@reflectiveTest
class ConstraintGathererTest extends ConstraintsTestBase {
- @override
- final _Constraints constraints = _Constraints();
-
void assertConditional(
NullabilityNode node, NullabilityNode left, NullabilityNode right) {
var conditionalNode = node as NullabilityNodeForLUB;
@@ -793,8 +790,6 @@
}
abstract class ConstraintsTestBase extends MigrationVisitorTestBase {
- Constraints get constraints;
-
/// Analyzes the given source code, producing constraint variables and
/// constraints for it.
@override
@@ -935,9 +930,12 @@
final NullabilityGraph graph;
- MigrationVisitorTestBase() : this._(NullabilityGraph());
+ final _Constraints constraints;
- MigrationVisitorTestBase._(this.graph) : _variables = _Variables(graph);
+ MigrationVisitorTestBase() : this._(NullabilityGraph(), _Constraints());
+
+ MigrationVisitorTestBase._(this.graph, this.constraints)
+ : _variables = _Variables(graph, constraints);
TypeProvider get typeProvider => testAnalysisResult.typeProvider;
@@ -1027,7 +1025,8 @@
final _possiblyOptional = <DefaultFormalParameter, NullabilityNode>{};
- _Variables(NullabilityGraph graph) : super(graph);
+ _Variables(NullabilityGraph graph, Constraints constraints)
+ : super(graph, constraints);
/// Gets the [ExpressionChecks] associated with the given [expression].
ExpressionChecks checkExpression(Expression expression) =>