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;