Migration: support index expressions.
Change-Id: Ie43b5045df75b325a74243a8ae8801387c73c64a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104883
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@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 ee4c725..7414beb 100644
--- a/pkg/analysis_server/lib/src/nullability/graph_builder.dart
+++ b/pkg/analysis_server/lib/src/nullability/graph_builder.dart
@@ -292,6 +292,22 @@
}
@override
+ DecoratedType visitIndexExpression(IndexExpression node) {
+ DecoratedType targetType;
+ if (node.target != null) {
+ targetType = _handleAssignment(_notNullType, node.target);
+ }
+ var callee = node.staticElement;
+ if (callee == null) {
+ throw new UnimplementedError('TODO(paulberry)');
+ }
+ var calleeType = getOrComputeElementType(callee, targetType: targetType);
+ // TODO(paulberry): substitute if necessary
+ _handleAssignment(calleeType.positionalParameters[0], node.index);
+ return calleeType.returnType;
+ }
+
+ @override
DecoratedType visitIntegerLiteral(IntegerLiteral node) {
return DecoratedType(node.staticType, NullabilityNode.never);
}
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 e5e2877..79c3227 100644
--- a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
+++ b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
@@ -563,6 +563,40 @@
contextNode: nullable_return);
}
+ test_indexExpression_index() async {
+ await analyze('''
+class C {
+ int operator[](int i) => 1;
+}
+int f(C c, int j) => c[j];
+''');
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int i').node,
+ hard: true);
+ }
+
+ test_indexExpression_return_type() async {
+ await analyze('''
+class C {
+ int operator[](int i) => 1;
+}
+int f(C c) => c[0];
+''');
+ assertEdge(decoratedTypeAnnotation('int operator').node,
+ decoratedTypeAnnotation('int f').node,
+ hard: false);
+ }
+
+ test_indexExpression_target_check() async {
+ await analyze('''
+class C {
+ int operator[](int i) => 1;
+}
+int f(C c) => c[0];
+''');
+ assertNullCheck(checkExpression('c['), decoratedTypeAnnotation('C c').node);
+ }
+
test_intLiteral() async {
await analyze('''
int f() {
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 eb0d189..fca6f2c 100644
--- a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
+++ b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
@@ -264,6 +264,38 @@
await _checkSingleFileChanges(content, expected);
}
+ test_data_flow_indexed_get_index_value() async {
+ var content = '''
+class C {
+ int operator[](int i) => 1;
+}
+int f(C c) => c[null];
+''';
+ var expected = '''
+class C {
+ int operator[](int? i) => 1;
+}
+int f(C c) => c[null];
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_data_flow_indexed_get_value() async {
+ var content = '''
+class C {
+ int operator[](int i) => null;
+}
+int f(C c) => c[0];
+''';
+ var expected = '''
+class C {
+ int? operator[](int i) => null;
+}
+int? f(C c) => c[0];
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_data_flow_inward() async {
var content = '''
int f(int i) => 0;