Support for list literals with type arguments

Change-Id: I7a661d83335b7d4c4ef2221af3eb31c865e2f9dc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106386
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Brian Wilkerson 2019-06-17 20:55:11 +00:00 committed by commit-bot@chromium.org
parent 792a3d561a
commit 8461cc6f5b
2 changed files with 72 additions and 1 deletions

View file

@ -17,6 +17,7 @@ import 'package:nnbd_migration/src/decorated_type.dart';
import 'package:nnbd_migration/src/expression_checks.dart';
import 'package:nnbd_migration/src/node_builder.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/variables.dart';
/// Visitor that builds nullability graph edges by examining code to be
/// migrated.
@ -412,7 +413,27 @@ class GraphBuilder extends GeneralizingAstVisitor<DecoratedType> {
@override
DecoratedType visitListLiteral(ListLiteral node) {
throw new UnimplementedError('TODO(brianwilkerson)');
var listType = node.staticType as InterfaceType;
if (node.typeArguments == null) {
// TODO(brianwilkerson) We might want to create a fake node in the graph
// to represent the type argument so that we can still create edges from
// the elements to it.
throw new UnimplementedError('TODO(brianwilkerson)');
} else {
var typeArgumentType = _variables.decoratedTypeAnnotation(
_source, node.typeArguments.arguments[0]);
for (var element in node.elements) {
if (element is Expression) {
_handleAssignment(typeArgumentType, element);
} else {
// Handle spread and control flow elements.
element.accept(this);
throw new UnimplementedError('TODO(brianwilkerson)');
}
}
return DecoratedType(listType, _graph.never,
typeArguments: [typeArgumentType]);
}
}
@override

View file

@ -908,6 +908,56 @@ bool f(a) => a is List<int>;
assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
}
@failingTest
test_listLiteral_noTypeArgument_noNullableElements() async {
// Failing because we're not yet handling collection literals without a
// type argument.
await analyze('''
List<String> f() {
return ['a', 'b'];
}
''');
assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
// TODO(brianwilkerson) Add an assertion that there is an edge from the list
// literal's fake type argument to the return type's type argument.
}
@failingTest
test_listLiteral_noTypeArgument_nullableElement() async {
// Failing because we're not yet handling collection literals without a
// type argument.
await analyze('''
List<String> f() {
return ['a', null, 'c'];
}
''');
assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
}
test_listLiteral_typeArgument_noNullableElements() async {
await analyze('''
List<String> f() {
return <String>['a', 'b'];
}
''');
assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
var typeArgForLiteral = decoratedTypeAnnotation('String>[').node;
var typeArgForReturnType = decoratedTypeAnnotation('String> ').node;
assertNoUpstreamNullability(typeArgForLiteral);
assertEdge(typeArgForLiteral, typeArgForReturnType, hard: false);
}
test_listLiteral_typeArgument_nullableElement() async {
await analyze('''
List<String> f() {
return <String>['a', null, 'c'];
}
''');
assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
assertEdge(always, decoratedTypeAnnotation('String>[').node, hard: false);
}
test_methodDeclaration_resets_unconditional_control_flow() async {
await analyze('''
class C {