Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: pkg/front_end/lib/src/codegen/tools.dart

Issue 3002293003: Convert GeneratedContent to async and use AnalysisDriver for tasks graph. (Closed)
Patch Set: Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/analyzer_plugin/tool/spec/to_html.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:async';
5 import 'dart:io'; 6 import 'dart:io';
6 7
7 import 'package:path/path.dart'; 8 import 'package:path/path.dart';
8 9
9 /** 10 /**
10 * Type of functions used to compute the contents of a set of generated files. 11 * Type of functions used to compute the contents of a set of generated files.
11 * [pkgPath] is the path to the current package. 12 * [pkgPath] is the path to the current package.
12 */ 13 */
13 typedef Map<String, FileContentsComputer> DirectoryContentsComputer( 14 typedef Map<String, FileContentsComputer> DirectoryContentsComputer(
14 String pkgPath); 15 String pkgPath);
15 16
16 /** 17 /**
17 * Type of functions used to compute the contents of a generated file. 18 * Type of functions used to compute the contents of a generated file.
18 * [pkgPath] is the path to the current package. 19 * [pkgPath] is the path to the current package.
19 */ 20 */
20 typedef String FileContentsComputer(String pkgPath); 21 typedef Future<String> FileContentsComputer(String pkgPath);
21 22
22 /** 23 /**
23 * Abstract base class representing behaviors common to generated files and 24 * Abstract base class representing behaviors common to generated files and
24 * generated directories. 25 * generated directories.
25 */ 26 */
26 abstract class GeneratedContent { 27 abstract class GeneratedContent {
27 /** 28 /**
28 * Check whether the [output] has the correct contents, and return true if it 29 * Check whether the [output] has the correct contents, and return true if it
29 * does. [pkgPath] is the path to the current package. 30 * does. [pkgPath] is the path to the current package.
30 */ 31 */
31 bool check(String pkgPath); 32 Future<bool> check(String pkgPath);
32 33
33 /** 34 /**
34 * Replace the [output] with the correct contents. [pkgPath] is the path to 35 * Replace the [output] with the correct contents. [pkgPath] is the path to
35 * the current package. 36 * the current package.
36 */ 37 */
37 void generate(String pkgPath); 38 Future<Null> generate(String pkgPath);
38 39
39 /** 40 /**
40 * Get a [FileSystemEntity] representing the output file or directory. 41 * Get a [FileSystemEntity] representing the output file or directory.
41 * [pkgPath] is the path to the current package. 42 * [pkgPath] is the path to the current package.
42 */ 43 */
43 FileSystemEntity output(String pkgPath); 44 FileSystemEntity output(String pkgPath);
44 45
45 /** 46 /**
46 * Check that all of the [targets] are up to date. If they are not, print 47 * Check that all of the [targets] are up to date. If they are not, print
47 * out a message instructing the user to regenerate them, and exit with a 48 * out a message instructing the user to regenerate them, and exit with a
48 * nonzero error code. 49 * nonzero error code.
49 * 50 *
50 * [pkgPath] is the path to the current package. [generatorRelPath] is the 51 * [pkgPath] is the path to the current package. [generatorRelPath] is the
51 * path to a .dart script the user may use to regenerate the targets. 52 * path to a .dart script the user may use to regenerate the targets.
52 * 53 *
53 * To avoid mistakes when run on Windows, [generatorRelPath] always uses 54 * To avoid mistakes when run on Windows, [generatorRelPath] always uses
54 * POSIX directory separators. 55 * POSIX directory separators.
55 */ 56 */
56 static void checkAll(String pkgPath, String generatorRelPath, 57 static Future<Null> checkAll(String pkgPath, String generatorRelPath,
57 Iterable<GeneratedContent> targets) { 58 Iterable<GeneratedContent> targets) async {
58 bool generateNeeded = false; 59 bool generateNeeded = false;
59 for (GeneratedContent target in targets) { 60 for (GeneratedContent target in targets) {
60 if (!target.check(pkgPath)) { 61 bool ok = await target.check(pkgPath);
62 if (!ok) {
61 print( 63 print(
62 '${target.output(pkgPath).absolute} does not have expected contents. '); 64 '${target.output(pkgPath).absolute} does not have expected contents. ');
63 generateNeeded = true; 65 generateNeeded = true;
64 } 66 }
65 } 67 }
66 if (generateNeeded) { 68 if (generateNeeded) {
67 print('Please regenerate using:'); 69 print('Please regenerate using:');
68 String executable = Platform.executable; 70 String executable = Platform.executable;
69 String packageRoot = ''; 71 String packageRoot = '';
70 if (Platform.packageRoot != null) { 72 if (Platform.packageRoot != null) {
71 packageRoot = ' --package-root=${Platform.packageRoot}'; 73 packageRoot = ' --package-root=${Platform.packageRoot}';
72 } 74 }
73 String generateScript = 75 String generateScript =
74 join(pkgPath, joinAll(posix.split(generatorRelPath))); 76 join(pkgPath, joinAll(posix.split(generatorRelPath)));
75 print(' $executable$packageRoot $generateScript'); 77 print(' $executable$packageRoot $generateScript');
76 exit(1); 78 exit(1);
77 } else { 79 } else {
78 print('All generated files up to date.'); 80 print('All generated files up to date.');
79 } 81 }
80 } 82 }
81 83
82 /** 84 /**
83 * Regenerate all of the [targets]. [pkgPath] is the path to the current 85 * Regenerate all of the [targets]. [pkgPath] is the path to the current
84 * package. 86 * package.
85 */ 87 */
86 static void generateAll(String pkgPath, Iterable<GeneratedContent> targets) { 88 static Future<Null> generateAll(
89 String pkgPath, Iterable<GeneratedContent> targets) async {
87 print("Generating..."); 90 print("Generating...");
88 for (GeneratedContent target in targets) { 91 for (GeneratedContent target in targets) {
89 target.generate(pkgPath); 92 await target.generate(pkgPath);
90 } 93 }
91 } 94 }
92 } 95 }
93 96
94 /** 97 /**
95 * Class representing a single output directory (either generated code or 98 * Class representing a single output directory (either generated code or
96 * generated HTML). No other content should exist in the directory. 99 * generated HTML). No other content should exist in the directory.
97 */ 100 */
98 class GeneratedDirectory extends GeneratedContent { 101 class GeneratedDirectory extends GeneratedContent {
99 /** 102 /**
100 * The path to the directory that will have the generated content. 103 * The path to the directory that will have the generated content.
101 */ 104 */
102 final String outputDirPath; 105 final String outputDirPath;
103 106
104 /** 107 /**
105 * Callback function that computes the directory contents. 108 * Callback function that computes the directory contents.
106 */ 109 */
107 final DirectoryContentsComputer directoryContentsComputer; 110 final DirectoryContentsComputer directoryContentsComputer;
108 111
109 GeneratedDirectory(this.outputDirPath, this.directoryContentsComputer); 112 GeneratedDirectory(this.outputDirPath, this.directoryContentsComputer);
110 113
111 @override 114 @override
112 bool check(String pkgPath) { 115 Future<bool> check(String pkgPath) async {
113 Directory outputDirectory = output(pkgPath); 116 Directory outputDirectory = output(pkgPath);
114 Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath); 117 Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
115 try { 118 try {
116 for (String file in map.keys) { 119 for (String file in map.keys) {
117 FileContentsComputer fileContentsComputer = map[file]; 120 FileContentsComputer fileContentsComputer = map[file];
118 String expectedContents = fileContentsComputer(pkgPath); 121 String expectedContents = await fileContentsComputer(pkgPath);
119 File outputFile = new File(posix.join(outputDirectory.path, file)); 122 File outputFile = new File(posix.join(outputDirectory.path, file));
120 String actualContents = outputFile.readAsStringSync(); 123 String actualContents = outputFile.readAsStringSync();
121 // Normalize Windows line endings to Unix line endings so that the 124 // Normalize Windows line endings to Unix line endings so that the
122 // comparison doesn't fail on Windows. 125 // comparison doesn't fail on Windows.
123 actualContents = actualContents.replaceAll('\r\n', '\n'); 126 actualContents = actualContents.replaceAll('\r\n', '\n');
124 if (expectedContents != actualContents) { 127 if (expectedContents != actualContents) {
125 return false; 128 return false;
126 } 129 }
127 } 130 }
128 int nonHiddenFileCount = 0; 131 int nonHiddenFileCount = 0;
(...skipping 13 matching lines...) Expand all
142 } catch (e) { 145 } catch (e) {
143 // There was a problem reading the file (most likely because it didn't 146 // There was a problem reading the file (most likely because it didn't
144 // exist). Treat that the same as if the file doesn't have the expected 147 // exist). Treat that the same as if the file doesn't have the expected
145 // contents. 148 // contents.
146 return false; 149 return false;
147 } 150 }
148 return true; 151 return true;
149 } 152 }
150 153
151 @override 154 @override
152 void generate(String pkgPath) { 155 Future<Null> generate(String pkgPath) async {
153 Directory outputDirectory = output(pkgPath); 156 Directory outputDirectory = output(pkgPath);
154 try { 157 try {
155 // delete the contents of the directory (and the directory itself) 158 // delete the contents of the directory (and the directory itself)
156 outputDirectory.deleteSync(recursive: true); 159 outputDirectory.deleteSync(recursive: true);
157 } catch (e) { 160 } catch (e) {
158 // Error caught while trying to delete the directory, this can happen if 161 // Error caught while trying to delete the directory, this can happen if
159 // it didn't yet exist. 162 // it didn't yet exist.
160 } 163 }
161 // re-create the empty directory 164 // re-create the empty directory
162 outputDirectory.createSync(recursive: true); 165 outputDirectory.createSync(recursive: true);
163 166
164 // generate all of the files in the directory 167 // generate all of the files in the directory
165 Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath); 168 Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
166 map.forEach((String file, FileContentsComputer fileContentsComputer) { 169 for (String file in map.keys) {
170 FileContentsComputer fileContentsComputer = map[file];
167 File outputFile = new File(posix.join(outputDirectory.path, file)); 171 File outputFile = new File(posix.join(outputDirectory.path, file));
168 print(' ${outputFile.path}'); 172 print(' ${outputFile.path}');
169 outputFile.writeAsStringSync(fileContentsComputer(pkgPath)); 173 String contents = await fileContentsComputer(pkgPath);
170 }); 174 outputFile.writeAsStringSync(contents);
175 }
171 } 176 }
172 177
173 @override 178 @override
174 Directory output(String pkgPath) => 179 Directory output(String pkgPath) =>
175 new Directory(join(pkgPath, joinAll(posix.split(outputDirPath)))); 180 new Directory(join(pkgPath, joinAll(posix.split(outputDirPath))));
176 } 181 }
177 182
178 /** 183 /**
179 * Class representing a single output file (either generated code or generated 184 * Class representing a single output file (either generated code or generated
180 * HTML). 185 * HTML).
181 */ 186 */
182 class GeneratedFile extends GeneratedContent { 187 class GeneratedFile extends GeneratedContent {
183 /** 188 /**
184 * The output file to which generated output should be written, relative to 189 * The output file to which generated output should be written, relative to
185 * the "tool/spec" directory. This filename uses the posix path separator 190 * the "tool/spec" directory. This filename uses the posix path separator
186 * ('/') regardless of the OS. 191 * ('/') regardless of the OS.
187 */ 192 */
188 final String outputPath; 193 final String outputPath;
189 194
190 /** 195 /**
191 * Callback function which computes the file. 196 * Callback function which computes the file.
192 */ 197 */
193 final FileContentsComputer computeContents; 198 final FileContentsComputer computeContents;
194 199
195 GeneratedFile(this.outputPath, this.computeContents); 200 GeneratedFile(this.outputPath, this.computeContents);
196 201
197 bool get isDartFile => outputPath.endsWith('.dart'); 202 bool get isDartFile => outputPath.endsWith('.dart');
198 203
199 @override 204 @override
200 bool check(String pkgPath) { 205 Future<bool> check(String pkgPath) async {
201 File outputFile = output(pkgPath); 206 File outputFile = output(pkgPath);
202 String expectedContents = computeContents(pkgPath); 207 String expectedContents = await computeContents(pkgPath);
203 if (isDartFile) { 208 if (isDartFile) {
204 expectedContents = DartFormat.formatText(expectedContents); 209 expectedContents = DartFormat.formatText(expectedContents);
205 } 210 }
206 try { 211 try {
207 String actualContents = outputFile.readAsStringSync(); 212 String actualContents = outputFile.readAsStringSync();
208 // Normalize Windows line endings to Unix line endings so that the 213 // Normalize Windows line endings to Unix line endings so that the
209 // comparison doesn't fail on Windows. 214 // comparison doesn't fail on Windows.
210 actualContents = actualContents.replaceAll('\r\n', '\n'); 215 actualContents = actualContents.replaceAll('\r\n', '\n');
211 return expectedContents == actualContents; 216 return expectedContents == actualContents;
212 } catch (e) { 217 } catch (e) {
213 // There was a problem reading the file (most likely because it didn't 218 // There was a problem reading the file (most likely because it didn't
214 // exist). Treat that the same as if the file doesn't have the expected 219 // exist). Treat that the same as if the file doesn't have the expected
215 // contents. 220 // contents.
216 return false; 221 return false;
217 } 222 }
218 } 223 }
219 224
220 @override 225 @override
221 void generate(String pkgPath) { 226 Future<Null> generate(String pkgPath) async {
222 File outputFile = output(pkgPath); 227 File outputFile = output(pkgPath);
223 print(' ${outputFile.path}'); 228 print(' ${outputFile.path}');
224 outputFile.writeAsStringSync(computeContents(pkgPath)); 229 String contents = await computeContents(pkgPath);
230 outputFile.writeAsStringSync(contents);
225 if (isDartFile) { 231 if (isDartFile) {
226 DartFormat.formatFile(outputFile); 232 DartFormat.formatFile(outputFile);
227 } 233 }
228 } 234 }
229 235
230 @override 236 @override
231 File output(String pkgPath) => 237 File output(String pkgPath) =>
232 new File(join(pkgPath, joinAll(posix.split(outputPath)))); 238 new File(join(pkgPath, joinAll(posix.split(outputPath))));
233 } 239 }
234 240
(...skipping 18 matching lines...) Expand all
253 } 259 }
254 260
255 static String formatText(String text) { 261 static String formatText(String text) {
256 File file = new File(join(Directory.systemTemp.path, 'gen.dart')); 262 File file = new File(join(Directory.systemTemp.path, 'gen.dart'));
257 file.writeAsStringSync(text); 263 file.writeAsStringSync(text);
258 ProcessResult result = Process.runSync(_dartfmtPath, ['-w', file.path]); 264 ProcessResult result = Process.runSync(_dartfmtPath, ['-w', file.path]);
259 if (result.exitCode != 0) throw result.stderr; 265 if (result.exitCode != 0) throw result.stderr;
260 return file.readAsStringSync(); 266 return file.readAsStringSync();
261 } 267 }
262 } 268 }
OLDNEW
« no previous file with comments | « pkg/analyzer_plugin/tool/spec/to_html.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698