Skip to content

Commit

Permalink
Migration: add edge builder support for generic method invocations.
Browse files Browse the repository at this point in the history
This should address ~25 exceptions whose stack trace includes the line:

EdgeBuilder.visitMethodDeclaration (package:nnbd_migration/src/edge_builder.dart:843:7)

Change-Id: I0076592f43f18c68f499fc9a80347a73033f8919
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/115802
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
  • Loading branch information
stereotype441 authored and commit-bot@chromium.org committed Sep 6, 2019
1 parent 35f45f0 commit bad1816
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
3 changes: 0 additions & 3 deletions pkg/nnbd_migration/lib/src/edge_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -839,9 +839,6 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>

@override
DecoratedType visitMethodDeclaration(MethodDeclaration node) {
if (node.typeParameters != null) {
_unimplemented(node, 'Generic method');
}
_handleExecutableDeclaration(node, node.declaredElement, node.metadata,
node.returnType, node.parameters, null, node.body, null);
return null;
Expand Down
23 changes: 23 additions & 0 deletions pkg/nnbd_migration/test/edge_builder_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1749,6 +1749,29 @@ int/*2*/ g() {
hard: false));
}

test_genericMethodInvocation() async {
await analyze('''
class Base {
T foo<T>(T x) => x;
}
class Derived extends Base {}
int bar(Derived d, int i) => d.foo(i);
''');
var implicitTypeArgumentMatcher = anyNode;
assertEdge(
decoratedTypeAnnotation('int i').node,
substitutionNode(
implicitTypeArgumentMatcher, decoratedTypeAnnotation('T x').node),
hard: true);
var implicitTypeArgumentNullability =
implicitTypeArgumentMatcher.matchingNode;
assertEdge(
substitutionNode(implicitTypeArgumentNullability,
decoratedTypeAnnotation('T foo').node),
decoratedTypeAnnotation('int bar').node,
hard: false);
}

test_if_condition() async {
await analyze('''
void f(bool b) {
Expand Down
23 changes: 14 additions & 9 deletions pkg/nnbd_migration/test/migration_visitor_test_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ import 'package:test/test.dart';

import 'abstract_single_unit.dart';

/// A [NodeMatcher] that matches any node, and records what node it matched to.
class AnyNodeMatcher implements NodeMatcher {
final List<NullabilityNode> _matchingNodes = [];

NullabilityNode get matchingNode => _matchingNodes.single;

@override
bool matches(NullabilityNode node) {
_matchingNodes.add(node);
return true;
}
}

/// Mixin allowing unit tests to create decorated types easily.
mixin DecoratedTypeTester implements DecoratedTypeTesterBase {
int _offset = 0;
Expand Down Expand Up @@ -114,7 +127,7 @@ class EdgeBuilderTestBase extends MigrationVisitorTestBase {
/// Mixin allowing unit tests to check for the presence of graph edges.
mixin EdgeTester {
/// Returns a [NodeMatcher] that matches any node whatsoever.
NodeMatcher get anyNode => const _AnyNodeMatcher();
AnyNodeMatcher get anyNode => AnyNodeMatcher();

NullabilityGraphForTesting get graph;

Expand Down Expand Up @@ -337,14 +350,6 @@ abstract class NodeMatcher {
bool matches(NullabilityNode node);
}

/// A [NodeMatcher] that matches any node.
class _AnyNodeMatcher implements NodeMatcher {
const _AnyNodeMatcher();

@override
bool matches(NullabilityNode node) => true;
}

/// A [NodeMatcher] that matches exactly one node.
class _ExactNodeMatcher implements NodeMatcher {
final NullabilityNode _expectation;
Expand Down

0 comments on commit bad1816

Please sign in to comment.