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

Commit 1993669

Browse files
bwilkersoncommit-bot@chromium.org
authored andcommitted
Clean up examples in analyzer docs that were using deprecated APIs and add a test to catch future breakages
Change-Id: I74bdb4c7474d130ae87e7cdc5991d7fadc79e453 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103465 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent 14b1d2f commit 1993669

File tree

5 files changed

+176
-16
lines changed

5 files changed

+176
-16
lines changed

pkg/analyzer/doc/tutorial/analysis.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,14 @@ to analyze.
2424
main() {
2525
List<String> includedPaths = <String>[/* ... */];
2626
AnalysisContextCollection collection =
27-
new AnalysisContextCollection(includedPaths);
27+
new AnalysisContextCollection(includedPaths: includedPaths);
2828
analyzeSomeFiles(collection, includedPaths);
2929
}
30+
31+
analyzeSomeFiles(
32+
AnalysisContextCollection collection, List<String> includedPaths) {
33+
// See below.
34+
}
3035
```
3136

3237
The collection will create one or more analysis contexts that can be used to
@@ -52,6 +57,10 @@ analyzeSomeFiles(
5257
analyzeSingleFile(context, path);
5358
}
5459
}
60+
61+
analyzeSingleFile(AnalysisContext context, String path) {
62+
// See below.
63+
}
5564
```
5665

5766
## Analyzing Multiple Files
@@ -68,6 +77,10 @@ analyzeAllFiles(AnalysisContextCollection collection) {
6877
}
6978
}
7079
}
80+
81+
analyzeSingleFile(AnalysisContext context, String path) {
82+
// See below.
83+
}
7184
```
7285

7386
The files returned this way will include _all_ of the files in all of the

pkg/analyzer/doc/tutorial/ast.md

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,12 @@ If you have followed the steps in [Performing Analysis][analysis], and you want
5050
to get the compilation unit for a file at a known `path`, then you can ask the
5151
analysis session for an AST.
5252

53-
If you need an unresolved AST, then you can use either a synchronous or
54-
asynchronous method to access the AST:
53+
If you need an unresolved AST, then you can use the following method to access
54+
the AST:
5555

5656
```dart
57-
main() async {
58-
ParseResult result = await session.getParsedAst(path);
59-
CompilationUnit unit = result.unit;
60-
}
61-
```
62-
63-
or
64-
65-
```dart
66-
main() {
67-
ParseResult result = session.getParsedAstSync(path);
57+
processFile(AnalysisSession session, String path) {
58+
ParsedUnitResult result = session.getParsedUnit(path);
6859
CompilationUnit unit = result.unit;
6960
}
7061
```
@@ -73,8 +64,8 @@ If you need a resolved AST, then you need to use the following asynchronous
7364
method to access it:
7465

7566
```dart
76-
main() async {
77-
ResolveResult result = await session.getResolvedAst(path);
67+
processFile(AnalysisSession session, String path) async {
68+
ResolvedUnitResult result = await session.getResolvedUnit(path);
7869
CompilationUnit unit = result.unit;
7970
}
8071
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The 'snippets' directory exists to enable the test in 'verify_docs_test.dart'.

pkg/analyzer/test/test_all.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'instrumentation/test_all.dart' as instrumentation;
1313
import 'parse_compilation_unit_test.dart' as parse_compilation_unit;
1414
import 'source/test_all.dart' as source;
1515
import 'src/test_all.dart' as src;
16+
import 'verify_docs_test.dart' as verify_docs;
1617
import 'verify_tests_test.dart' as verify_tests;
1718

1819
main() {
@@ -26,6 +27,7 @@ main() {
2627
parse_compilation_unit.main();
2728
source.main();
2829
src.main();
30+
verify_docs.main();
2931
verify_tests.main();
3032
}, name: 'analyzer');
3133
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:convert';
6+
7+
import 'package:analyzer/dart/analysis/analysis_context.dart';
8+
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
9+
import 'package:analyzer/dart/analysis/results.dart';
10+
import 'package:analyzer/error/error.dart';
11+
import 'package:analyzer/file_system/file_system.dart';
12+
import 'package:analyzer/file_system/overlay_file_system.dart';
13+
import 'package:analyzer/file_system/physical_file_system.dart';
14+
import 'package:analyzer/src/error/codes.dart';
15+
import 'package:front_end/src/testing/package_root.dart' as package_root;
16+
import 'package:test/test.dart';
17+
18+
main() async {
19+
SnippetTester tester = SnippetTester();
20+
await tester.verify();
21+
if (tester.output.isNotEmpty) {
22+
fail(tester.output.toString());
23+
}
24+
}
25+
26+
class SnippetTester {
27+
OverlayResourceProvider provider;
28+
Folder docFolder;
29+
String snippetDirPath;
30+
String snippetPath;
31+
32+
StringBuffer output = StringBuffer();
33+
34+
SnippetTester() {
35+
provider = OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
36+
String packageRoot =
37+
provider.pathContext.normalize(package_root.packageRoot);
38+
String analyzerPath = provider.pathContext.join(packageRoot, 'analyzer');
39+
String docPath = provider.pathContext.join(analyzerPath, 'doc');
40+
docFolder = provider.getFolder(docPath);
41+
snippetDirPath =
42+
provider.pathContext.join(analyzerPath, 'test', 'snippets');
43+
snippetPath = provider.pathContext.join(snippetDirPath, 'snippet.dart');
44+
}
45+
46+
void verify() async {
47+
await verifyFolder(docFolder);
48+
}
49+
50+
void verifyFile(File file) async {
51+
String content = file.readAsStringSync();
52+
List<String> lines = const LineSplitter().convert(content);
53+
List<String> codeLines = [];
54+
bool inCode = false;
55+
for (int i = 0; i < lines.length; i++) {
56+
String line = lines[i];
57+
if (line == '```dart') {
58+
if (inCode) {
59+
// TODO(brianwilkerson) Report this.
60+
}
61+
inCode = true;
62+
} else if (line == '```') {
63+
if (!inCode) {
64+
// TODO(brianwilkerson) Report this.
65+
}
66+
await verifySnippet(file, codeLines.join('\n'));
67+
codeLines.clear();
68+
inCode = false;
69+
} else if (inCode) {
70+
codeLines.add(line);
71+
}
72+
}
73+
}
74+
75+
void verifyFolder(Folder folder) async {
76+
for (Resource child in folder.getChildren()) {
77+
if (child is File) {
78+
if (child.shortName.endsWith('.md')) {
79+
await verifyFile(child);
80+
}
81+
} else if (child is Folder) {
82+
await verifyFolder(child);
83+
}
84+
}
85+
}
86+
87+
void verifySnippet(File file, String snippet) async {
88+
// TODO(brianwilkerson) When the files outside of 'src' contain only public
89+
// API, write code to compute the list of imports so that new public API
90+
// will automatically be allowed.
91+
String imports = '''
92+
import 'dart:math' as math;
93+
94+
import 'package:analyzer/dart/analysis/analysis_context.dart';
95+
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
96+
import 'package:analyzer/dart/analysis/results.dart';
97+
import 'package:analyzer/dart/analysis/session.dart';
98+
import 'package:analyzer/dart/ast/ast.dart';
99+
import 'package:analyzer/dart/ast/visitor.dart';
100+
import 'package:analyzer/dart/element/element.dart';
101+
import 'package:analyzer/dart/element/visitor.dart';
102+
103+
''';
104+
provider.setOverlay(snippetPath,
105+
content: '''
106+
$imports
107+
$snippet
108+
''',
109+
modificationStamp: 1);
110+
try {
111+
AnalysisContextCollection collection = new AnalysisContextCollection(
112+
includedPaths: <String>[snippetDirPath], resourceProvider: provider);
113+
List<AnalysisContext> contexts = collection.contexts;
114+
if (contexts.length != 1) {
115+
fail('The snippets directory contains multiple analysis contexts.');
116+
}
117+
ErrorsResult results =
118+
await contexts[0].currentSession.getErrors(snippetPath);
119+
Iterable<AnalysisError> errors = results.errors.where((error) {
120+
ErrorCode errorCode = error.errorCode;
121+
return errorCode != HintCode.UNUSED_IMPORT &&
122+
errorCode != HintCode.UNUSED_LOCAL_VARIABLE;
123+
});
124+
if (errors.isNotEmpty) {
125+
String filePath =
126+
provider.pathContext.relative(file.path, from: docFolder.path);
127+
if (output.isNotEmpty) {
128+
output.writeln();
129+
}
130+
output.writeln('Errors in snippet in "$filePath":');
131+
output.writeln();
132+
output.writeln(snippet);
133+
output.writeln();
134+
int importsLength = imports.length + 1; // account for the '\n'.
135+
for (var error in errors) {
136+
writeError(error, importsLength);
137+
}
138+
}
139+
} finally {
140+
provider.removeOverlay(snippetPath);
141+
}
142+
}
143+
144+
void writeError(AnalysisError error, int prefixLength) {
145+
output.write(error.errorCode);
146+
output.write(' (');
147+
output.write(error.offset - prefixLength);
148+
output.write(', ');
149+
output.write(error.length);
150+
output.write(') ');
151+
output.writeln(error.message);
152+
}
153+
}

0 commit comments

Comments
 (0)