Skip to content

Commit 9ee42fd

Browse files
authored
[ Widget Preview ] Cleanup PreviewDetector code (flutter#163050)
Adds some convenience extensions for working with analyzer APIs and removes a dependency on an implementation library from a private analyzer package.
1 parent 59fd4f9 commit 9ee42fd

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

packages/flutter_tools/lib/src/widget_preview/preview_detector.dart

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44

55
import 'dart:async';
66

7-
// ignore: implementation_imports
8-
import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart';
97
import 'package:analyzer/dart/analysis/analysis_context.dart';
108
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
119
import 'package:analyzer/dart/analysis/results.dart';
1210
import 'package:analyzer/dart/ast/ast.dart';
11+
import 'package:analyzer/dart/ast/token.dart';
1312
import 'package:analyzer/file_system/physical_file_system.dart';
1413
import 'package:watcher/watcher.dart';
1514

@@ -28,6 +27,27 @@ typedef PreviewPath = ({String path, Uri uri});
2827
/// Represents a set of previews for a given file.
2928
typedef PreviewMapping = Map<PreviewPath, List<String>>;
3029

30+
extension on Token {
31+
/// Convenience getter to identify tokens for private fields and functions.
32+
bool get isPrivate => toString().startsWith('_');
33+
}
34+
35+
extension on Annotation {
36+
/// Convenience getter to identify `@Preview` annotations
37+
bool get isPreview => name.name == 'Preview';
38+
}
39+
40+
/// Convenience getters for examining [String] paths.
41+
extension on String {
42+
bool get isDartFile => endsWith('.dart');
43+
bool get isGeneratedPreviewFile => endsWith(PreviewCodeGenerator.generatedPreviewFilePath);
44+
}
45+
46+
extension on ParsedUnitResult {
47+
/// Convenience method to package [path] and [uri] into a [PreviewPath]
48+
PreviewPath toPreviewPath() => (path: path, uri: uri);
49+
}
50+
3151
class PreviewDetector {
3252
PreviewDetector({required this.fs, required this.logger, required this.onChangeDetected});
3353

@@ -49,8 +69,7 @@ class PreviewDetector {
4969
final String eventPath = event.path;
5070
// Only trigger a reload when changes to Dart sources are detected. We
5171
// ignore the generated preview file to avoid getting stuck in a loop.
52-
if (!eventPath.endsWith('.dart') ||
53-
eventPath.endsWith(PreviewCodeGenerator.generatedPreviewFilePath)) {
72+
if (!eventPath.isDartFile || eventPath.isGeneratedPreviewFile) {
5473
return;
5574
}
5675
logger.printStatus('Detected change in $eventPath.');
@@ -110,36 +129,35 @@ class PreviewDetector {
110129

111130
for (final String filePath in context.contextRoot.analyzedFiles()) {
112131
logger.printTrace('Checking file: $filePath');
113-
if (!filePath.endsWith('.dart')) {
132+
if (!filePath.isDartFile) {
114133
continue;
115134
}
116135

117136
final SomeParsedLibraryResult lib = context.currentSession.getParsedLibrary(filePath);
118137
if (lib is ParsedLibraryResult) {
119-
for (final ParsedUnitResult unit in lib.units) {
120-
final List<String> previewEntries =
121-
previews[(path: unit.path, uri: unit.uri)] ?? <String>[];
122-
for (final SyntacticEntity entity in unit.unit.childEntities) {
123-
if (entity is FunctionDeclaration && !entity.name.toString().startsWith('_')) {
138+
for (final ParsedUnitResult libUnit in lib.units) {
139+
final List<String> previewEntries = previews[libUnit.toPreviewPath()] ?? <String>[];
140+
for (final CompilationUnitMember entity in libUnit.unit.declarations) {
141+
if (entity is FunctionDeclaration && !entity.name.isPrivate) {
124142
bool foundPreview = false;
125143
for (final Annotation annotation in entity.metadata) {
126-
if (annotation.name.name == 'Preview') {
144+
if (annotation.isPreview) {
127145
// What happens if the annotation is applied multiple times?
128146
foundPreview = true;
129147
break;
130148
}
131149
}
132150
if (foundPreview) {
133151
logger.printStatus('Found preview at:');
134-
logger.printStatus('File path: ${unit.uri}');
152+
logger.printStatus('File path: ${libUnit.uri}');
135153
logger.printStatus('Preview function: ${entity.name}');
136154
logger.printStatus('');
137155
previewEntries.add(entity.name.toString());
138156
}
139157
}
140158
}
141159
if (previewEntries.isNotEmpty) {
142-
previews[(path: unit.path, uri: unit.uri)] = previewEntries;
160+
previews[libUnit.toPreviewPath()] = previewEntries;
143161
}
144162
}
145163
} else {

0 commit comments

Comments
 (0)