Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit da3ead0

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Issue 3446. Recurse into attributes to find children widgets.
R=brianwilkerson@google.com, devoncarew@google.com Bug: flutter/flutter-intellij#3446 Change-Id: Ifa83367c68b406b342e0f99195015d98eaedb049 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103900 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
1 parent 9556a95 commit da3ead0

File tree

2 files changed

+91
-11
lines changed

2 files changed

+91
-11
lines changed

pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,20 @@ T _registerWidgetInstance<T extends Widget>(int id, T widget) {
6363
var flutterDartOutline = _convert(dartOutline);
6464

6565
// Create outlines for widgets.
66-
resolvedUnit.unit.accept(new _FlutterOutlineBuilder(this));
66+
var visitor = new _FlutterOutlineBuilder(this);
67+
resolvedUnit.unit.accept(visitor);
68+
69+
// Associate Flutter outlines with Dart outlines.
70+
for (var outline in visitor.outlines) {
71+
for (var parent in _depthFirstOrder) {
72+
if (parent.offset < outline.offset &&
73+
outline.offset + outline.length < parent.offset + parent.length) {
74+
parent.children ??= <protocol.FlutterOutline>[];
75+
parent.children.add(outline);
76+
break;
77+
}
78+
}
79+
}
6780

6881
// Compute instrumented code.
6982
if (widgets.values.any((w) => w.hasDesignTimeConstructor)) {
@@ -224,8 +237,14 @@ T _registerWidgetInstance<T extends Widget>(int id, T widget) {
224237
}
225238
}
226239
} else {
227-
ParameterElement parameter = argument.staticParameterElement;
228-
_addAttribute(attributes, argument, parameter);
240+
var visitor = _FlutterOutlineBuilder(this);
241+
argument.accept(visitor);
242+
if (visitor.outlines.isNotEmpty) {
243+
children.addAll(visitor.outlines);
244+
} else {
245+
ParameterElement parameter = argument.staticParameterElement;
246+
_addAttribute(attributes, argument, parameter);
247+
}
229248
}
230249
}
231250

@@ -385,21 +404,15 @@ T _registerWidgetInstance<T extends Widget>(int id, T widget) {
385404

386405
class _FlutterOutlineBuilder extends GeneralizingAstVisitor<void> {
387406
final FlutterOutlineComputer computer;
407+
final List<protocol.FlutterOutline> outlines = [];
388408

389409
_FlutterOutlineBuilder(this.computer);
390410

391411
@override
392412
void visitExpression(Expression node) {
393413
var outline = computer._createOutline(node, false);
394414
if (outline != null) {
395-
for (var parent in computer._depthFirstOrder) {
396-
if (parent.offset < outline.offset &&
397-
outline.offset + outline.length < parent.offset + parent.length) {
398-
parent.children ??= <protocol.FlutterOutline>[];
399-
parent.children.add(outline);
400-
return;
401-
}
402-
}
415+
outlines.add(outline);
403416
} else {
404417
super.visitExpression(node);
405418
}

pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,73 @@ class MyWidget extends StatelessWidget {
205205
}
206206
}
207207

208+
test_children_closure_blockBody() async {
209+
newFile('/home/test/lib/a.dart', content: r'''
210+
import 'package:flutter/widgets.dart';
211+
212+
class WidgetA extends StatelessWidget {
213+
final Widget Function(bool) factory;
214+
215+
WidgetA(this.factory);
216+
}
217+
''');
218+
FlutterOutline unitOutline = await _computeOutline('''
219+
import 'package:flutter/widgets.dart';
220+
import 'a.dart';
221+
222+
class MyWidget extends StatelessWidget {
223+
@override
224+
Widget build(BuildContext context) {
225+
return new WidgetA((b) {
226+
if (b) {
227+
return const Text('aaa'),
228+
} else {
229+
return const Container(),
230+
}
231+
}); // WidgetA
232+
}
233+
}
234+
''');
235+
expect(_toText(unitOutline), r'''
236+
(D) MyWidget
237+
(D) build
238+
WidgetA
239+
Text
240+
Container
241+
''');
242+
}
243+
244+
test_children_closure_expressionBody() async {
245+
newFile('/home/test/lib/a.dart', content: r'''
246+
import 'package:flutter/widgets.dart';
247+
248+
class WidgetA extends StatelessWidget {
249+
final Widget Function() factory;
250+
251+
WidgetA(this.factory);
252+
}
253+
''');
254+
FlutterOutline unitOutline = await _computeOutline('''
255+
import 'package:flutter/widgets.dart';
256+
import 'a.dart';
257+
258+
class MyWidget extends StatelessWidget {
259+
@override
260+
Widget build(BuildContext context) {
261+
return new WidgetA(
262+
() => const Text('aaa'),
263+
); // WidgetA
264+
}
265+
}
266+
''');
267+
expect(_toText(unitOutline), r'''
268+
(D) MyWidget
269+
(D) build
270+
WidgetA
271+
Text
272+
''');
273+
}
274+
208275
test_children_withCollectionElements() async {
209276
FlutterOutline unitOutline = await _computeOutline('''
210277
import 'package:flutter/widgets.dart';

0 commit comments

Comments
 (0)