@@ -67,15 +67,34 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
67
67
this ._typeProvider,
68
68
{this .instrumentation});
69
69
70
+ NullabilityNodeTarget get safeTarget {
71
+ var target = _target;
72
+ if (target != null ) return target;
73
+ assert (false , 'Unknown nullability node target' );
74
+ return NullabilityNodeTarget .text ('unknown' );
75
+ }
76
+
77
+ @override
78
+ DecoratedType visitAsExpression (AsExpression node) {
79
+ node.expression? .accept (this );
80
+ _pushNullabilityNodeTarget (
81
+ NullabilityNodeTarget .text ('cast type' ), () => node.type? .accept (this ));
82
+ return null ;
83
+ }
84
+
70
85
@override
71
86
DecoratedType visitCatchClause (CatchClause node) {
72
- DecoratedType exceptionType = node.exceptionType? .accept (this );
87
+ var exceptionElement = node.exceptionParameter? .staticElement;
88
+ var target = exceptionElement == null
89
+ ? NullabilityNodeTarget .text ('exception type' )
90
+ : NullabilityNodeTarget .element (exceptionElement);
91
+ DecoratedType exceptionType = _pushNullabilityNodeTarget (
92
+ target, () => node.exceptionType? .accept (this ));
73
93
if (node.exceptionParameter != null ) {
74
94
// If there is no `on Type` part of the catch clause, the type is dynamic.
75
95
if (exceptionType == null ) {
76
- var target = NullabilityNodeTarget .text ('exception' ).withCodeRef (node);
77
- exceptionType = DecoratedType .forImplicitType (
78
- _typeProvider, _typeProvider.dynamicType, _graph, target);
96
+ exceptionType = DecoratedType .forImplicitType (_typeProvider,
97
+ _typeProvider.dynamicType, _graph, target.withCodeRef (node));
79
98
instrumentation? .implicitType (
80
99
source, node.exceptionParameter, exceptionType);
81
100
}
@@ -170,14 +189,23 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
170
189
return null ;
171
190
}
172
191
192
+ @override
193
+ DecoratedType visitConstructorName (ConstructorName node) {
194
+ _pushNullabilityNodeTarget (NullabilityNodeTarget .text ('constructed type' ),
195
+ () => node.type? .accept (this ));
196
+ node.name? .accept (this );
197
+ return null ;
198
+ }
199
+
173
200
@override
174
201
DecoratedType visitDeclaredIdentifier (DeclaredIdentifier node) {
175
202
node.metadata.accept (this );
176
- DecoratedType type = node.type? .accept (this );
203
+ var declaredElement = node.declaredElement;
204
+ var target = NullabilityNodeTarget .element (declaredElement);
205
+ DecoratedType type =
206
+ _pushNullabilityNodeTarget (target, () => node.type? .accept (this ));
177
207
if (node.identifier != null ) {
178
208
if (type == null ) {
179
- var declaredElement = node.declaredElement;
180
- var target = NullabilityNodeTarget .element (declaredElement);
181
209
type = DecoratedType .forImplicitType (
182
210
_typeProvider, declaredElement.type, _graph, target);
183
211
instrumentation? .implicitType (source, node, type);
@@ -258,7 +286,9 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
258
286
DecoratedType visitExtensionDeclaration (ExtensionDeclaration node) {
259
287
node.metadata.accept (this );
260
288
node.typeParameters? .accept (this );
261
- var type = node.extendedType.accept (this );
289
+ var type = _pushNullabilityNodeTarget (
290
+ NullabilityNodeTarget .text ('extended type' ),
291
+ () => node.extendedType.accept (this ));
262
292
_variables.recordDecoratedElementType (node.declaredElement, type);
263
293
node.members.accept (this );
264
294
return null ;
@@ -276,12 +306,10 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
276
306
for (var parameter in node.parameters) {
277
307
var element = parameter.declaredElement;
278
308
NullabilityNodeTarget newTarget;
279
- if (_target == null ) {
280
- newTarget = null ;
281
- } else if (element.isNamed) {
282
- newTarget = _target.namedParameter (element.name);
309
+ if (element.isNamed) {
310
+ newTarget = safeTarget.namedParameter (element.name);
283
311
} else {
284
- newTarget = _target .positionalParameter (index++ );
312
+ newTarget = safeTarget .positionalParameter (index++ );
285
313
}
286
314
_pushNullabilityNodeTarget (newTarget, () => parameter.accept (this ));
287
315
}
@@ -310,6 +338,16 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
310
338
return null ;
311
339
}
312
340
341
+ @override
342
+ DecoratedType visitFunctionExpressionInvocation (
343
+ FunctionExpressionInvocation node) {
344
+ node.function? .accept (this );
345
+ _pushNullabilityNodeTarget (NullabilityNodeTarget .text ('type argument' ),
346
+ () => node.typeArguments? .accept (this ));
347
+ node.argumentList? .accept (this );
348
+ return null ;
349
+ }
350
+
313
351
@override
314
352
DecoratedType visitFunctionTypeAlias (FunctionTypeAlias node) {
315
353
node.metadata.accept (this );
@@ -335,7 +373,7 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
335
373
DecoratedType decoratedFunctionType;
336
374
try {
337
375
node.typeParameters? .accept (this );
338
- node.parameters? .accept (this );
376
+ _pushNullabilityNodeTarget (target, () => node.parameters? .accept (this ) );
339
377
// Note: we don't pass _typeFormalBounds into DecoratedType because we're
340
378
// not defining a generic function type, we're defining a generic typedef
341
379
// of an ordinary (non-generic) function type.
@@ -365,20 +403,31 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
365
403
DecoratedType decoratedFunctionType;
366
404
node.typeParameters? .accept (this );
367
405
var target = NullabilityNodeTarget .element (node.declaredElement);
368
- var returnType = node.functionType.returnType;
369
- if (returnType != null ) {
370
- _pushNullabilityNodeTarget (target.returnType (), () {
371
- decoratedFunctionType = node.functionType.accept (this );
372
- });
373
- } else {
406
+ _pushNullabilityNodeTarget (target, () {
374
407
decoratedFunctionType = node.functionType.accept (this );
375
- }
408
+ });
376
409
_variables.recordDecoratedElementType (
377
410
(node.declaredElement as GenericTypeAliasElement ).function,
378
411
decoratedFunctionType);
379
412
return null ;
380
413
}
381
414
415
+ @override
416
+ DecoratedType visitIsExpression (IsExpression node) {
417
+ node.expression? .accept (this );
418
+ _pushNullabilityNodeTarget (NullabilityNodeTarget .text ('tested type' ),
419
+ () => node.type? .accept (this ));
420
+ return null ;
421
+ }
422
+
423
+ @override
424
+ DecoratedType visitListLiteral (ListLiteral node) {
425
+ _pushNullabilityNodeTarget (NullabilityNodeTarget .text ('list element type' ),
426
+ () => node.typeArguments? .accept (this ));
427
+ node.elements.accept (this );
428
+ return null ;
429
+ }
430
+
382
431
@override
383
432
DecoratedType visitMethodDeclaration (MethodDeclaration node) {
384
433
_handleExecutableDeclaration (
@@ -394,6 +443,16 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
394
443
return null ;
395
444
}
396
445
446
+ @override
447
+ DecoratedType visitMethodInvocation (MethodInvocation node) {
448
+ node.target? .accept (this );
449
+ node.methodName? .accept (this );
450
+ _pushNullabilityNodeTarget (NullabilityNodeTarget .text ('type argument' ),
451
+ () => node.typeArguments? .accept (this ));
452
+ node.argumentList? .accept (this );
453
+ return null ;
454
+ }
455
+
397
456
@override
398
457
visitMixinDeclaration (MixinDeclaration node) {
399
458
node.metadata.accept (this );
@@ -405,6 +464,26 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
405
464
return null ;
406
465
}
407
466
467
+ @override
468
+ DecoratedType visitSetOrMapLiteral (SetOrMapLiteral node) {
469
+ var typeArguments = node.typeArguments;
470
+ if (typeArguments != null ) {
471
+ var arguments = typeArguments.arguments;
472
+ if (arguments.length == 2 ) {
473
+ _pushNullabilityNodeTarget (NullabilityNodeTarget .text ('map key type' ),
474
+ () => arguments[0 ].accept (this ));
475
+ _pushNullabilityNodeTarget (NullabilityNodeTarget .text ('map value type' ),
476
+ () => arguments[1 ].accept (this ));
477
+ } else {
478
+ _pushNullabilityNodeTarget (
479
+ NullabilityNodeTarget .text ('set element type' ),
480
+ () => typeArguments.accept (this ));
481
+ }
482
+ }
483
+ node.elements.accept (this );
484
+ return null ;
485
+ }
486
+
408
487
@override
409
488
DecoratedType visitSimpleFormalParameter (SimpleFormalParameter node) {
410
489
return _handleFormalParameter (node, node.type, null , null );
@@ -414,8 +493,7 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
414
493
DecoratedType visitTypeAnnotation (TypeAnnotation node) {
415
494
assert (node != null ); // TODO(paulberry)
416
495
var type = node.type;
417
- var target = (_target ?? NullabilityNodeTarget .text ('explicit type' ))
418
- .withCodeRef (node);
496
+ var target = safeTarget.withCodeRef (node);
419
497
if (type.isVoid || type.isDynamic) {
420
498
var nullabilityNode = NullabilityNode .forTypeAnnotation (target);
421
499
var decoratedType = DecoratedType (type, nullabilityNode);
@@ -436,8 +514,11 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
436
514
.toList ();
437
515
instrumentation? .implicitTypeArguments (source, node, typeArguments);
438
516
} else {
439
- typeArguments =
440
- node.typeArguments.arguments.map ((t) => t.accept (this )).toList ();
517
+ int index = 0 ;
518
+ typeArguments = node.typeArguments.arguments
519
+ .map ((t) => _pushNullabilityNodeTarget (
520
+ target.typeArgument (index++ ), () => t.accept (this )))
521
+ .toList ();
441
522
}
442
523
} else {
443
524
assert (false ); // TODO(paulberry): is this possible?
@@ -453,7 +534,7 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
453
534
// If [_target] is non-null, then it represents the return type for
454
535
// a FunctionTypeAlias. Otherwise, create a return type target for
455
536
// `target`.
456
- _pushNullabilityNodeTarget (_target ?? target.returnType (), () {
537
+ _pushNullabilityNodeTarget (target.returnType (), () {
457
538
decoratedReturnType = returnType.accept (this );
458
539
});
459
540
}
@@ -508,11 +589,12 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
508
589
var element = node.declaredElement;
509
590
var bound = node.bound;
510
591
DecoratedType decoratedBound;
592
+ var target = NullabilityNodeTarget .typeParameterBound (element);
511
593
if (bound != null ) {
512
- decoratedBound = bound.accept (this );
594
+ decoratedBound =
595
+ _pushNullabilityNodeTarget (target, () => bound.accept (this ));
513
596
} else {
514
- var nullabilityNode = NullabilityNode .forInferredType (
515
- NullabilityNodeTarget .typeParameterBound (element));
597
+ var nullabilityNode = NullabilityNode .forInferredType (target);
516
598
decoratedBound = DecoratedType (_typeProvider.objectType, nullabilityNode);
517
599
_graph.connect (_graph.always, nullabilityNode,
518
600
AlwaysNullableTypeOrigin .forElement (element, false ));
@@ -525,7 +607,9 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
525
607
DecoratedType visitVariableDeclarationList (VariableDeclarationList node) {
526
608
node.metadata.accept (this );
527
609
var typeAnnotation = node.type;
528
- var type = typeAnnotation? .accept (this );
610
+ var type = _pushNullabilityNodeTarget (
611
+ NullabilityNodeTarget .element (node.variables.first.declaredElement),
612
+ () => typeAnnotation? .accept (this ));
529
613
var hint = getPrefixHint (node.firstTokenAfterCommentAndMetadata);
530
614
if (hint != null && hint.kind == HintCommentKind .late_) {
531
615
_variables.recordLateHint (source, node, hint);
@@ -624,7 +708,7 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
624
708
var declaredElement = node.declaredElement;
625
709
node.metadata? .accept (this );
626
710
DecoratedType decoratedType;
627
- var target = NullabilityNodeTarget . element (declaredElement) ;
711
+ var target = safeTarget ;
628
712
if (parameters == null ) {
629
713
if (type != null ) {
630
714
decoratedType = type.accept (this );
@@ -720,31 +804,34 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
720
804
supertypes.addAll (onClause.superclassConstraints);
721
805
}
722
806
var decoratedSupertypes = < ClassElement , DecoratedType > {};
723
- for (var supertype in supertypes) {
724
- DecoratedType decoratedSupertype;
725
- if (supertype == null ) {
726
- var target = NullabilityNodeTarget .text ('implicit object supertype' )
727
- .withCodeRef (astNode);
728
- var nullabilityNode = NullabilityNode .forInferredType (target);
729
- _graph.makeNonNullableUnion (
730
- nullabilityNode, NonNullableObjectSuperclass (source, astNode));
731
- decoratedSupertype =
732
- DecoratedType (_typeProvider.objectType, nullabilityNode);
733
- } else {
734
- decoratedSupertype = supertype.accept (this );
807
+ _pushNullabilityNodeTarget (
808
+ NullabilityNodeTarget .element (declaredElement).supertype, () {
809
+ for (var supertype in supertypes) {
810
+ DecoratedType decoratedSupertype;
811
+ if (supertype == null ) {
812
+ var nullabilityNode =
813
+ NullabilityNode .forInferredType (_target.withCodeRef (astNode));
814
+ _graph.makeNonNullableUnion (
815
+ nullabilityNode, NonNullableObjectSuperclass (source, astNode));
816
+ decoratedSupertype =
817
+ DecoratedType (_typeProvider.objectType, nullabilityNode);
818
+ } else {
819
+ decoratedSupertype = supertype.accept (this );
820
+ }
821
+ var class_ = (decoratedSupertype.type as InterfaceType ).element;
822
+ decoratedSupertypes[class_] = decoratedSupertype;
735
823
}
736
- var class_ = (decoratedSupertype.type as InterfaceType ).element;
737
- decoratedSupertypes[class_] = decoratedSupertype;
738
- }
824
+ });
739
825
_variables.recordDecoratedDirectSupertypes (
740
826
declaredElement, decoratedSupertypes);
741
827
}
742
828
743
- void _pushNullabilityNodeTarget (NullabilityNodeTarget target, Function () fn) {
829
+ T _pushNullabilityNodeTarget <T >(
830
+ NullabilityNodeTarget target, T Function () fn) {
744
831
NullabilityNodeTarget previousTarget = _target;
745
832
try {
746
833
_target = target;
747
- fn ();
834
+ return fn ();
748
835
} finally {
749
836
_target = previousTarget;
750
837
}
0 commit comments