Skip to content

Commit 66e349d

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Migration: Clean up substitution logic in getOrComputeElementType
This should address ~267 exceptions whose stacktrace contains the line: EdgeBuilder.getOrComputeElementType (package:nnbd_migration/src/edge_builder.dart:197:16) Change-Id: If377190e0bdabe85f541af50cb5f896fde5481ee Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/114741 Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent e9a44ba commit 66e349d

File tree

3 files changed

+50
-18
lines changed

3 files changed

+50
-18
lines changed

pkg/nnbd_migration/lib/src/edge_builder.dart

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -186,25 +186,14 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
186186
DecoratedType getOrComputeElementType(Element element,
187187
{DecoratedType targetType}) {
188188
Map<TypeParameterElement, DecoratedType> substitution;
189-
Element baseElement;
190-
if (element is Member) {
191-
assert(targetType != null);
192-
baseElement = element.baseElement;
193-
var targetTypeType = targetType.type;
194-
if (targetTypeType is InterfaceType &&
195-
baseElement is ClassMemberElement) {
196-
var enclosingClass = baseElement.enclosingElement as ClassElement;
197-
assert(targetTypeType.element == enclosingClass); // TODO(paulberry)
198-
substitution = <TypeParameterElement, DecoratedType>{};
199-
assert(enclosingClass.typeParameters.length ==
200-
targetTypeType.typeArguments.length); // TODO(paulberry)
201-
for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
202-
substitution[enclosingClass.typeParameters[i]] =
203-
targetType.typeArguments[i];
204-
}
189+
Element baseElement = element is Member ? element.baseElement : element;
190+
if (targetType != null) {
191+
var classElement = baseElement.enclosingElement as ClassElement;
192+
if (classElement.typeParameters.isNotEmpty) {
193+
substitution = _decoratedClassHierarchy
194+
.asInstanceOf(targetType, classElement)
195+
.asSubstitution;
205196
}
206-
} else {
207-
baseElement = element;
208197
}
209198
DecoratedType decoratedBaseType;
210199
if (baseElement is PropertyAccessorElement &&
@@ -230,6 +219,8 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
230219
elementType = element.type;
231220
} else if (element is ConstructorElement) {
232221
elementType = element.type;
222+
} else if (element is PropertyAccessorMember) {
223+
elementType = element.type;
233224
} else {
234225
throw element.runtimeType; // TODO(paulberry)
235226
}

pkg/nnbd_migration/lib/src/nullability_node.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,12 @@ class NullabilityGraph {
346346
class NullabilityGraphForTesting extends NullabilityGraph {
347347
final List<NullabilityEdge> _allEdges = [];
348348

349+
/// Prints out a representation of the graph nodes. Useful in debugging
350+
/// broken tests.
351+
void debugDump() {
352+
_debugDump();
353+
}
354+
349355
/// Iterates through all edges in the graph.
350356
@visibleForTesting
351357
Iterable<NullabilityEdge> getAllEdges() {

pkg/nnbd_migration/test/edge_builder_test.dart

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,6 +2468,23 @@ void test(C c) {
24682468
assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
24692469
}
24702470

2471+
test_methodInvocation_target_generic_in_base_class() async {
2472+
await analyze('''
2473+
abstract class B<T> {
2474+
void m(T/*1*/ t);
2475+
}
2476+
abstract class C extends B<int/*2*/> {}
2477+
void f(C c, int/*3*/ i) {
2478+
c.m(i);
2479+
}
2480+
''');
2481+
// nullable(3) -> substitute(nullable(2), nullable(1))
2482+
var nullable1 = decoratedTypeAnnotation('T/*1*/').node;
2483+
var nullable2 = decoratedTypeAnnotation('int/*2*/').node;
2484+
var nullable3 = decoratedTypeAnnotation('int/*3*/').node;
2485+
assertEdge(nullable3, substitutionNode(nullable2, nullable1), hard: true);
2486+
}
2487+
24712488
test_methodInvocation_typeParameter_inferred() async {
24722489
await analyze('''
24732490
T f<T>(T t) => t;
@@ -3324,6 +3341,24 @@ bool f(C c) => c.b;
33243341
hard: false);
33253342
}
33263343

3344+
test_prefixedIdentifier_getter_type_in_generic() async {
3345+
await analyze('''
3346+
class C<T> {
3347+
List<T> _x;
3348+
List<T> get x => _x;
3349+
}
3350+
List<int> f(C<int> c) => c.x;
3351+
''');
3352+
assertEdge(decoratedTypeAnnotation('List<T> get').node,
3353+
decoratedTypeAnnotation('List<int> f').node,
3354+
hard: false);
3355+
assertEdge(
3356+
substitutionNode(decoratedTypeAnnotation('int> c').node,
3357+
decoratedTypeAnnotation('T> get').node),
3358+
decoratedTypeAnnotation('int> f').node,
3359+
hard: false);
3360+
}
3361+
33273362
test_prefixedIdentifier_target_check() async {
33283363
await analyze('''
33293364
class C {

0 commit comments

Comments
 (0)