Skip to content

Commit 09dec7f

Browse files
authored
re-write flutter analyze to use the analysis server (flutter#16979)
re-write flutter analyze (the single-shot and --flutter-repo) to use the analysis server
1 parent ca94bfd commit 09dec7f

17 files changed

+443
-814
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ analyzer. There are two main ways to run it. In either case you will
7979
want to run `flutter update-packages` first, or you will get bogus
8080
error messages about core classes like Offset from `dart:ui`.
8181

82-
For a one-off, use `flutter analyze --flutter-repo`. This uses the `analysis_options_repo.yaml` file
82+
For a one-off, use `flutter analyze --flutter-repo`. This uses the `analysis_options.yaml` file
8383
at the root of the repository for its configuration.
8484

8585
For continuous analysis, use `flutter analyze --flutter-repo --watch`. This uses normal

analysis_options.yaml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,18 @@
99
#
1010
# There are four similar analysis options files in the flutter repos:
1111
# - analysis_options.yaml (this file)
12-
# - analysis_options_repo.yaml
1312
# - packages/flutter/lib/analysis_options_user.yaml
1413
# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml
14+
# - https://github.com/flutter/engine/blob/master/analysis_options.yaml
1515
#
1616
# This file contains the analysis options used by Flutter tools, such as IntelliJ,
1717
# Android Studio, and the `flutter analyze` command.
18-
# It is very similar to the analysis_options_repo.yaml file in this same directory;
19-
# the only difference (currently) is the public_member_api_docs option,
20-
# which triggers too many messages to be used in editors.
2118
#
2219
# The flutter/plugins repo contains a copy of this file, which should be kept
2320
# in sync with this file.
2421

2522
analyzer:
2623
language:
27-
enableStrictCallChecks: true
2824
enableSuperMixins: true
2925
strong-mode:
3026
implicit-dynamic: false
@@ -131,7 +127,6 @@ linter:
131127
- prefer_is_not_empty
132128
- prefer_single_quotes
133129
- prefer_typing_uninitialized_variables
134-
# - public_member_api_docs # this is the only difference from analysis_options_repo.yaml
135130
- recursive_getters
136131
- slash_for_doc_comments
137132
- sort_constructors_first

dev/bots/analyze-sample-code.dart

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ Future<Null> main() async {
189189
}
190190
}
191191
buffer.add('');
192+
buffer.add('// ignore_for_file: unused_element');
193+
buffer.add('');
192194
final List<Line> lines = new List<Line>.filled(buffer.length, null, growable: true);
193195
for (Section section in sections) {
194196
buffer.addAll(section.strings);
@@ -207,7 +209,7 @@ dependencies:
207209
print('Found $sampleCodeSections sample code sections.');
208210
final Process process = await Process.start(
209211
_flutter,
210-
<String>['analyze', '--no-preamble', mainDart.path],
212+
<String>['analyze', '--no-preamble', '--no-congratulate', mainDart.parent.path],
211213
workingDirectory: temp.path,
212214
);
213215
stderr.addStream(process.stderr);
@@ -216,10 +218,6 @@ dependencies:
216218
errors.removeAt(0);
217219
if (errors.first.startsWith('Running "flutter packages get" in '))
218220
errors.removeAt(0);
219-
if (errors.first.startsWith('Analyzing '))
220-
errors.removeAt(0);
221-
if (errors.last.endsWith(' issues found.') || errors.last.endsWith(' issue found.'))
222-
errors.removeLast();
223221
int errorCount = 0;
224222
for (String error in errors) {
225223
final String kBullet = Platform.isWindows ? ' - ' : ' • ';

dev/devicelab/bin/tasks/dartdocs.dart

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,24 @@ Future<Null> main() async {
2121
int publicMembers = 0;
2222
int otherErrors = 0;
2323
int otherLines = 0;
24-
await for (String entry in analysis.stderr.transform(utf8.decoder).transform(const LineSplitter())) {
25-
print('analyzer stderr: $entry');
26-
if (entry.startsWith('[lint] Document all public members')) {
24+
await for (String entry in analysis.stdout.transform(utf8.decoder).transform(const LineSplitter())) {
25+
entry = entry.trim();
26+
print('analyzer stdout: $entry');
27+
if (entry == 'Building flutter tool...') {
28+
// ignore this line
29+
} else if (entry.startsWith('info • Document all public members •')) {
2730
publicMembers += 1;
28-
} else if (entry.startsWith('[')) {
31+
} else if (entry.startsWith('info •') || entry.startsWith('warning •') || entry.startsWith('error •')) {
2932
otherErrors += 1;
30-
} else if (entry.startsWith('(Ran in ')) {
33+
} else if (entry.contains(' (ran in ')) {
3134
// ignore this line
32-
} else {
35+
} else if (entry.isNotEmpty) {
3336
otherLines += 1;
3437
}
3538
}
36-
await for (String entry in analysis.stdout.transform(utf8.decoder).transform(const LineSplitter())) {
37-
print('analyzer stdout: $entry');
38-
if (entry == 'Building flutter tool...') {
39+
await for (String entry in analysis.stderr.transform(utf8.decoder).transform(const LineSplitter())) {
40+
print('analyzer stderr: $entry');
41+
if (entry.startsWith('[lint] ')) {
3942
// ignore this line
4043
} else {
4144
otherLines += 1;

packages/analysis_options.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Take our settings from the repo's main analysis_options.yaml file, but include
2+
# an additional rule to validate that public members are documented.
3+
4+
include: ../analysis_options.yaml
5+
6+
linter:
7+
rules:
8+
- public_member_api_docs

packages/flutter/lib/analysis_options_user.yaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@
77
# See the configuration guide for more
88
# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer
99
#
10-
# There are three similar analysis options files in the flutter repo:
10+
# There are four similar analysis options files in the flutter repos:
1111
# - analysis_options.yaml
12-
# - analysis_options_repo.yaml
1312
# - packages/flutter/lib/analysis_options_user.yaml (this file)
13+
# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml
14+
# - https://github.com/flutter/engine/blob/master/analysis_options.yaml
1415
#
15-
# This file contains the analysis options used by "flutter analyze"
16-
# and the dartanalyzer when analyzing code outside the flutter repository.
17-
# It isn't named 'analysis_options.yaml' because otherwise editors like Atom
18-
# would use it when analyzing the flutter tool itself.
16+
# This file contains the analysis options used by "flutter analyze" and the
17+
# dartanalyzer when analyzing code outside the flutter repository. It isn't named
18+
# 'analysis_options.yaml' because otherwise editors would use it when analyzing
19+
# the flutter tool itself.
1920
#
20-
# When editing, make sure you keep /analysis_options.yaml consistent.
21+
# When editing, make sure you keep this and /analysis_options.yaml consistent.
2122

2223
analyzer:
2324
language:
24-
enableStrictCallChecks: true
2525
enableSuperMixins: true
2626
strong-mode: true
2727
errors:
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Use the analysis options settings from the top level of the repo (not
2+
# the ones from above, which include the `public_member_api_docs` rule).
3+
4+
include: ../../analysis_options.yaml
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Use the analysis options settings from the top level of the repo (not
2+
# the ones from above, which include the `public_member_api_docs` rule).
3+
4+
include: ../../analysis_options.yaml

packages/flutter_tools/lib/src/commands/analyze.dart

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,51 @@ import '../runner/flutter_command.dart';
99
import 'analyze_continuously.dart';
1010
import 'analyze_once.dart';
1111

12-
bool isDartFile(FileSystemEntity entry) => entry is File && entry.path.endsWith('.dart');
13-
14-
typedef bool FileFilter(FileSystemEntity entity);
15-
1612
class AnalyzeCommand extends FlutterCommand {
17-
AnalyzeCommand({ bool verboseHelp: false, this.workingDirectory }) {
18-
argParser.addFlag('flutter-repo', help: 'Include all the examples and tests from the Flutter repository.', defaultsTo: false);
19-
argParser.addFlag('current-package', help: 'Include the lib/main.dart file from the current directory, if any.', defaultsTo: true);
20-
argParser.addFlag('dartdocs', help: 'List every public member that is lacking documentation (only works with --flutter-repo and without --watch).', defaultsTo: false, hide: !verboseHelp);
21-
argParser.addFlag('watch', help: 'Run analysis continuously, watching the filesystem for changes.', negatable: false);
22-
argParser.addFlag('preview-dart-2', defaultsTo: true, help: 'Preview Dart 2.0 functionality.');
23-
argParser.addOption('write', valueHelp: 'file', help: 'Also output the results to a file. This is useful with --watch if you want a file to always contain the latest results.');
24-
argParser.addOption('dart-sdk', valueHelp: 'path-to-sdk', help: 'The path to the Dart SDK.', hide: !verboseHelp);
13+
AnalyzeCommand({bool verboseHelp: false, this.workingDirectory}) {
14+
argParser.addFlag('flutter-repo',
15+
negatable: false,
16+
help: 'Include all the examples and tests from the Flutter repository.',
17+
defaultsTo: false,
18+
hide: !verboseHelp);
19+
argParser.addFlag('current-package',
20+
help: 'Analyze the current project, if applicable.', defaultsTo: true);
21+
argParser.addFlag('dartdocs',
22+
negatable: false,
23+
help: 'List every public member that is lacking documentation '
24+
'(only works with --flutter-repo).',
25+
hide: !verboseHelp);
26+
argParser.addFlag('watch',
27+
help: 'Run analysis continuously, watching the filesystem for changes.',
28+
negatable: false);
29+
argParser.addFlag('preview-dart-2',
30+
defaultsTo: true, help: 'Preview Dart 2.0 functionality.');
31+
argParser.addOption('write',
32+
valueHelp: 'file',
33+
help: 'Also output the results to a file. This is useful with --watch '
34+
'if you want a file to always contain the latest results.');
35+
argParser.addOption('dart-sdk',
36+
valueHelp: 'path-to-sdk',
37+
help: 'The path to the Dart SDK.',
38+
hide: !verboseHelp);
2539

2640
// Hidden option to enable a benchmarking mode.
27-
argParser.addFlag('benchmark', negatable: false, hide: !verboseHelp, help: 'Also output the analysis time.');
41+
argParser.addFlag('benchmark',
42+
negatable: false,
43+
hide: !verboseHelp,
44+
help: 'Also output the analysis time.');
2845

2946
usesPubOption();
3047

3148
// Not used by analyze --watch
32-
argParser.addFlag('congratulate', help: 'When analyzing the flutter repository, show output even when there are no errors, warnings, hints, or lints.', defaultsTo: true);
33-
argParser.addFlag('preamble', help: 'When analyzing the flutter repository, display the number of files that will be analyzed.', defaultsTo: true);
49+
argParser.addFlag('congratulate',
50+
help: 'When analyzing the flutter repository, show output even when '
51+
'there are no errors, warnings, hints, or lints.',
52+
defaultsTo: true);
53+
argParser.addFlag('preamble',
54+
defaultsTo: true,
55+
help: 'When analyzing the flutter repository, display the number of '
56+
'files that will be analyzed.');
3457
}
3558

3659
/// The working directory for testing analysis using dartanalyzer.
@@ -40,17 +63,19 @@ class AnalyzeCommand extends FlutterCommand {
4063
String get name => 'analyze';
4164

4265
@override
43-
String get description => 'Analyze the project\'s Dart code.';
66+
String get description => "Analyze the project's Dart code.";
4467

4568
@override
4669
bool get shouldRunPub {
4770
// If they're not analyzing the current project.
48-
if (!argResults['current-package'])
71+
if (!argResults['current-package']) {
4972
return false;
73+
}
5074

5175
// Or we're not in a project directory.
52-
if (!fs.file('pubspec.yaml').existsSync())
76+
if (!fs.file('pubspec.yaml').existsSync()) {
5377
return false;
78+
}
5479

5580
return super.shouldRunPub;
5681
}
@@ -59,11 +84,15 @@ class AnalyzeCommand extends FlutterCommand {
5984
Future<Null> runCommand() {
6085
if (argResults['watch']) {
6186
return new AnalyzeContinuously(
62-
argResults, runner.getRepoPackages(), previewDart2: argResults['preview-dart-2']
87+
argResults,
88+
runner.getRepoRoots(),
89+
runner.getRepoPackages(),
90+
previewDart2: argResults['preview-dart-2'],
6391
).analyze();
6492
} else {
6593
return new AnalyzeOnce(
6694
argResults,
95+
runner.getRepoRoots(),
6796
runner.getRepoPackages(),
6897
workingDirectory: workingDirectory,
6998
previewDart2: argResults['preview-dart-2'],

0 commit comments

Comments
 (0)