@@ -28,6 +28,29 @@ class InfoBuilderTest extends AbstractAnalysisTest {
2828 /// not yet completed.
2929 List <UnitInfo > infos;
3030
31+ /// Assert various properties of the given [detail] .
32+ void assertDetail ({@required RegionDetail detail, int offset, int length}) {
33+ if (offset != null ) {
34+ expect (detail.target.offset, offset);
35+ }
36+ if (length != null ) {
37+ expect (detail.target.length, length);
38+ }
39+ }
40+
41+ /// Assert that some target in [targets] has various properties.
42+ void assertInTargets (
43+ {@required Iterable <NavigationTarget > targets, int offset, int length}) {
44+ String failureReasons = [
45+ if (offset != null ) 'offset: $offset ' ,
46+ if (length != null ) 'length: $length ' ,
47+ ].join (' and ' );
48+ expect (targets.any ((t) {
49+ return (offset == null || offset == t.offset) &&
50+ (length == null || length == t.length);
51+ }), isTrue, reason: 'Expected one of $targets to contain $failureReasons ' );
52+ }
53+
3154 /// Assert various properties of the given [region] . If an [offset] is
3255 /// provided but no [length] is provided, a default length of `1` will be
3356 /// used.
@@ -72,6 +95,52 @@ class InfoBuilderTest extends AbstractAnalysisTest {
7295 infos = await builder.explainMigration ();
7396 }
7497
98+ test_asExpression () async {
99+ addTestFile ('''
100+ void f([num a]) {
101+ int b = a as int;
102+ }
103+ ''' );
104+ await buildInfo ();
105+ UnitInfo unit = infos[0 ];
106+ expect (unit.content, '''
107+ void f([num? a]) {
108+ int? b = a as int?;
109+ }
110+ ''' );
111+ List <RegionInfo > regions = unit.regions;
112+ expect (regions, hasLength (3 ));
113+ assertRegion (region: regions[0 ], offset: 11 );
114+ assertRegion (
115+ region: regions[1 ],
116+ offset: 24 ,
117+ details: ["This variable is initialized to a nullable value" ]);
118+ assertRegion (
119+ region: regions[2 ],
120+ offset: 38 ,
121+ details: ["The value of the expression is nullable" ]);
122+ }
123+
124+ test_expressionFunctionReturnTarget () async {
125+ addTestFile ('''
126+ String g() => 1 == 2 ? "Hello" : null;
127+ ''' );
128+ await buildInfo ();
129+ UnitInfo unit = infos[0 ];
130+ expect (unit.content, '''
131+ String? g() => 1 == 2 ? "Hello" : null;
132+ ''' );
133+ assertInTargets (targets: unit.targets, offset: 7 , length: 1 ); // "g"
134+ assertInTargets (targets: unit.targets, offset: 11 , length: 2 ); // "=>"
135+ List <RegionInfo > regions = unit.regions;
136+ expect (regions, hasLength (1 ));
137+ assertRegion (
138+ region: regions[0 ],
139+ offset: 6 ,
140+ details: ["This function returns a nullable value" ]);
141+ assertDetail (detail: regions[0 ].details[0 ], offset: 11 , length: 2 );
142+ }
143+
75144 test_field_fieldFormalInitializer_optional () async {
76145 addTestFile ('''
77146class A {
@@ -357,6 +426,30 @@ void f([String? s]) {}
357426 details: ["This parameter has an implicit default value of 'null'" ]);
358427 }
359428
429+ test_returnDetailTarget () async {
430+ addTestFile ('''
431+ String g() {
432+ return 1 == 2 ? "Hello" : null;
433+ }
434+ ''' );
435+ await buildInfo ();
436+ UnitInfo unit = infos[0 ];
437+ expect (unit.content, '''
438+ String? g() {
439+ return 1 == 2 ? "Hello" : null;
440+ }
441+ ''' );
442+ assertInTargets (targets: unit.targets, offset: 7 , length: 1 ); // "g"
443+ assertInTargets (targets: unit.targets, offset: 15 , length: 6 ); // "return"
444+ List <RegionInfo > regions = unit.regions;
445+ expect (regions, hasLength (1 ));
446+ assertRegion (
447+ region: regions[0 ],
448+ offset: 6 ,
449+ details: ["This function returns a nullable value" ]);
450+ assertDetail (detail: regions[0 ].details[0 ], offset: 15 , length: 6 );
451+ }
452+
360453 test_returnType_function_expression () async {
361454 addTestFile ('''
362455int _f = null;
0 commit comments