Migration: add support for local variable declarations.
Change-Id: Ifead9354c583a070a7240d158823eafe1be3d875
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104840
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/nullability/graph_builder.dart b/pkg/analysis_server/lib/src/nullability/graph_builder.dart
index c2f4bfa..1cf5c85 100644
--- a/pkg/analysis_server/lib/src/nullability/graph_builder.dart
+++ b/pkg/analysis_server/lib/src/nullability/graph_builder.dart
@@ -439,6 +439,17 @@
return DecoratedType(typeName.type, NullabilityNode.never);
}
+ @override
+ DecoratedType visitVariableDeclaration(VariableDeclaration node) {
+ var destinationType = getOrComputeElementType(node.declaredElement);
+ var initializer = node.initializer;
+ if (initializer == null) {
+ throw UnimplementedError('TODO(paulberry)');
+ } else {
+ _handleAssignment(destinationType, initializer);
+ }
+ }
+
/// Creates the necessary constraint(s) for an assignment from [sourceType] to
/// [destinationType]. [expression] is the expression whose type is
/// [sourceType]; it is the expression we will have to null-check in the case
diff --git a/pkg/analysis_server/lib/src/nullability/node_builder.dart b/pkg/analysis_server/lib/src/nullability/node_builder.dart
index e1c6939..8827aee 100644
--- a/pkg/analysis_server/lib/src/nullability/node_builder.dart
+++ b/pkg/analysis_server/lib/src/nullability/node_builder.dart
@@ -85,14 +85,14 @@
@override
DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
_handleExecutableDeclaration(node.declaredElement, node.returnType,
- node.functionExpression.parameters, node);
+ node.functionExpression.parameters, node.functionExpression.body, node);
return null;
}
@override
DecoratedType visitMethodDeclaration(MethodDeclaration node) {
- _handleExecutableDeclaration(
- node.declaredElement, node.returnType, node.parameters, node);
+ _handleExecutableDeclaration(node.declaredElement, node.returnType,
+ node.parameters, node.body, node);
return null;
}
@@ -169,11 +169,21 @@
return null;
}
+ @override
+ DecoratedType visitVariableDeclarationList(VariableDeclarationList node) {
+ var type = decorateType(node.type, node);
+ for (var variable in node.variables) {
+ _variables.recordDecoratedElementType(variable.declaredElement, type);
+ }
+ return null;
+ }
+
/// Common handling of function and method declarations.
void _handleExecutableDeclaration(
ExecutableElement declaredElement,
TypeAnnotation returnType,
FormalParameterList parameters,
+ FunctionBody body,
AstNode enclosingNode) {
var decoratedReturnType = decorateType(returnType, enclosingNode);
var previousFunctionType = _currentFunctionType;
@@ -187,6 +197,7 @@
_currentFunctionType = functionType;
try {
parameters?.accept(this);
+ body?.accept(this);
} finally {
_currentFunctionType = previousFunctionType;
}
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 115dc45..5851f82 100644
--- a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
+++ b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
@@ -821,6 +821,17 @@
''');
assertNoUpstreamNullability(decoratedTypeAnnotation('Type').node);
}
+
+ test_variableDeclaration() async {
+ await analyze('''
+void f(int i) {
+ int j = i;
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int i').node,
+ decoratedTypeAnnotation('int j').node,
+ hard: true);
+ }
}
class MigrationVisitorTestBase extends AbstractSingleUnitTest {
@@ -1041,6 +1052,16 @@
expect(bound.node.isNullable, isTrue);
expect(bound.type, same(typeProvider.objectType));
}
+
+ test_variableDeclaration_type_simple() async {
+ await analyze('''
+main() {
+ int i;
+}
+''');
+ var decoratedType = decoratedTypeAnnotation('int');
+ expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+ }
}
/// Mock representation of constraint variables.
diff --git a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
index ba01ca0..47140d6 100644
--- a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
+++ b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
@@ -286,6 +286,26 @@
await _checkSingleFileChanges(content, expected);
}
+ test_data_flow_local_declaration() async {
+ var content = '''
+void f(int i) {
+ int j = i;
+}
+main() {
+ f(null);
+}
+''';
+ var expected = '''
+void f(int? i) {
+ int? j = i;
+}
+main() {
+ f(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_data_flow_outward() async {
var content = '''
int f(int i) => null;