OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 /** | 5 /** |
6 * Tools for code generation. | 6 * Tools for code generation. |
7 */ | 7 */ |
8 library codegen.tools; | 8 library codegen.tools; |
9 | 9 |
10 import 'dart:io'; | 10 import 'dart:io'; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 | 70 |
71 /** | 71 /** |
72 * Execute [callback], collecting any code that is output using [write] | 72 * Execute [callback], collecting any code that is output using [write] |
73 * or [writeln], and return the result as a string. | 73 * or [writeln], and return the result as a string. |
74 */ | 74 */ |
75 String collectCode(void callback(), {bool removeTrailingNewLine: false}) { | 75 String collectCode(void callback(), {bool removeTrailingNewLine: false}) { |
76 _CodeGeneratorState oldState = _state; | 76 _CodeGeneratorState oldState = _state; |
77 try { | 77 try { |
78 _state = new _CodeGeneratorState(); | 78 _state = new _CodeGeneratorState(); |
79 callback(); | 79 callback(); |
80 var text = _state.buffer.toString().replaceAll(trailingSpacesInLineRegExp,
''); | 80 var text = |
| 81 _state.buffer.toString().replaceAll(trailingSpacesInLineRegExp, ''); |
81 if (!removeTrailingNewLine) { | 82 if (!removeTrailingNewLine) { |
82 return text; | 83 return text; |
83 } else { | 84 } else { |
84 return text.replaceAll(trailingWhitespaceRegExp, ''); | 85 return text.replaceAll(trailingWhitespaceRegExp, ''); |
85 } | 86 } |
86 } finally { | 87 } finally { |
87 _state = oldState; | 88 _state = oldState; |
88 } | 89 } |
89 } | 90 } |
90 | 91 |
91 /** | 92 /** |
92 * Generate a doc comment based on the HTML in [docs]. | 93 * Generate a doc comment based on the HTML in [docs]. |
93 * | 94 * |
94 * When generating java code, the output is compatible with Javadoc, which | 95 * When generating java code, the output is compatible with Javadoc, which |
95 * understands certain HTML constructs. | 96 * understands certain HTML constructs. |
96 */ | 97 */ |
97 void docComment(List<dom.Node> docs, {bool removeTrailingNewLine: false}) { | 98 void docComment(List<dom.Node> docs, {bool removeTrailingNewLine: false}) { |
98 if (containsOnlyWhitespace(docs)) return; | 99 if (containsOnlyWhitespace(docs)) return; |
99 writeln(codeGeneratorSettings.docCommentStartMarker); | 100 writeln(codeGeneratorSettings.docCommentStartMarker); |
100 int width = codeGeneratorSettings.commentLineLength; | 101 int width = codeGeneratorSettings.commentLineLength; |
101 bool javadocStyle = codeGeneratorSettings.languageName == 'java'; | 102 bool javadocStyle = codeGeneratorSettings.languageName == 'java'; |
102 indentBy(codeGeneratorSettings.docCommentLineLeader, () { | 103 indentBy(codeGeneratorSettings.docCommentLineLeader, () { |
103 write(nodesToText(docs, width - _state.indent.length, javadocStyle, | 104 write(nodesToText(docs, width - _state.indent.length, javadocStyle, |
104 removeTrailingNewLine: removeTrailingNewLine)); | 105 removeTrailingNewLine: removeTrailingNewLine)); |
105 }); | 106 }); |
106 writeln(codeGeneratorSettings.docCommentEndMarker); | 107 writeln(codeGeneratorSettings.docCommentEndMarker); |
107 } | 108 } |
108 | 109 |
109 /** | 110 /** |
110 * Execute [callback], indenting any code it outputs. | 111 * Execute [callback], indenting any code it outputs. |
111 */ | 112 */ |
112 void indent(void callback()) { | 113 void indent(void callback()) { |
113 indentSpecial(codeGeneratorSettings.indent, codeGeneratorSettings.indent, | 114 indentSpecial( |
114 callback); | 115 codeGeneratorSettings.indent, codeGeneratorSettings.indent, callback); |
115 } | 116 } |
116 | 117 |
117 /** | 118 /** |
118 * Execute [callback], using [additionalIndent] to indent any code it outputs. | 119 * Execute [callback], using [additionalIndent] to indent any code it outputs. |
119 */ | 120 */ |
120 void indentBy(String additionalIndent, void callback()) => | 121 void indentBy(String additionalIndent, void callback()) => |
121 indentSpecial(additionalIndent, additionalIndent, callback); | 122 indentSpecial(additionalIndent, additionalIndent, callback); |
122 | 123 |
123 /** | 124 /** |
124 * Execute [callback], using [additionalIndent] to indent any code it outputs. | 125 * Execute [callback], using [additionalIndent] to indent any code it outputs. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 /** | 244 /** |
244 * Line length for doc comment lines. | 245 * Line length for doc comment lines. |
245 */ | 246 */ |
246 int commentLineLength; | 247 int commentLineLength; |
247 | 248 |
248 /** | 249 /** |
249 * String used for indenting code. | 250 * String used for indenting code. |
250 */ | 251 */ |
251 String indent; | 252 String indent; |
252 | 253 |
253 CodeGeneratorSettings({this.languageName: 'java', | 254 CodeGeneratorSettings( |
254 this.lineCommentLineLeader: '// ', this.docCommentStartMarker: '/**', | 255 {this.languageName: 'java', |
255 this.docCommentLineLeader: ' * ', this.docCommentEndMarker: ' */', | 256 this.lineCommentLineLeader: '// ', |
256 this.commentLineLength: 99, this.indent: ' '}); | 257 this.docCommentStartMarker: '/**', |
| 258 this.docCommentLineLeader: ' * ', |
| 259 this.docCommentEndMarker: ' */', |
| 260 this.commentLineLength: 99, |
| 261 this.indent: ' '}); |
257 } | 262 } |
258 | 263 |
259 abstract class GeneratedContent { | 264 abstract class GeneratedContent { |
260 FileSystemEntity get outputFile; | 265 FileSystemEntity get outputFile; |
261 bool check(); | 266 bool check(); |
262 void generate(); | 267 void generate(); |
263 } | 268 } |
264 | 269 |
265 /** | 270 /** |
266 * Class representing a single output directory (either generated code or | 271 * Class representing a single output directory (either generated code or |
267 * generated HTML). No other content should exist in the directory. | 272 * generated HTML). No other content should exist in the directory. |
268 */ | 273 */ |
269 class GeneratedDirectory extends GeneratedContent { | 274 class GeneratedDirectory extends GeneratedContent { |
270 | |
271 /** | 275 /** |
272 * The path to the directory that will have the generated content. | 276 * The path to the directory that will have the generated content. |
273 */ | 277 */ |
274 final String outputDirPath; | 278 final String outputDirPath; |
275 | 279 |
276 /** | 280 /** |
277 * Callback function that computes the directory contents. | 281 * Callback function that computes the directory contents. |
278 */ | 282 */ |
279 final DirectoryContentsComputer directoryContentsComputer; | 283 final DirectoryContentsComputer directoryContentsComputer; |
280 | 284 |
(...skipping 20 matching lines...) Expand all Loading... |
301 new File(joinAll(posix.split(posix.join(outputDirPath, file)))); | 305 new File(joinAll(posix.split(posix.join(outputDirPath, file)))); |
302 String actualContents = outputFile.readAsStringSync(); | 306 String actualContents = outputFile.readAsStringSync(); |
303 // Normalize Windows line endings to Unix line endings so that the | 307 // Normalize Windows line endings to Unix line endings so that the |
304 // comparison doesn't fail on Windows. | 308 // comparison doesn't fail on Windows. |
305 actualContents = actualContents.replaceAll('\r\n', '\n'); | 309 actualContents = actualContents.replaceAll('\r\n', '\n'); |
306 if (expectedContents != actualContents) { | 310 if (expectedContents != actualContents) { |
307 return false; | 311 return false; |
308 } | 312 } |
309 } | 313 } |
310 int nonHiddenFileCount = 0; | 314 int nonHiddenFileCount = 0; |
311 outputFile.listSync(recursive: false, followLinks: false).forEach( | 315 outputFile |
312 (FileSystemEntity fileSystemEntity) { | 316 .listSync(recursive: false, followLinks: false) |
| 317 .forEach((FileSystemEntity fileSystemEntity) { |
313 if (fileSystemEntity is File && | 318 if (fileSystemEntity is File && |
314 !basename(fileSystemEntity.path).startsWith('.')) { | 319 !basename(fileSystemEntity.path).startsWith('.')) { |
315 nonHiddenFileCount++; | 320 nonHiddenFileCount++; |
316 } | 321 } |
317 }); | 322 }); |
318 if (nonHiddenFileCount != map.length) { | 323 if (nonHiddenFileCount != map.length) { |
319 // The number of files generated doesn't match the number we expected to | 324 // The number of files generated doesn't match the number we expected to |
320 // generate. | 325 // generate. |
321 return false; | 326 return false; |
322 } | 327 } |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 if (lines.last.isEmpty) { | 548 if (lines.last.isEmpty) { |
544 lines.removeLast(); | 549 lines.removeLast(); |
545 buffer.add(new dom.Text(lines.join('\n$indent') + '\n')); | 550 buffer.add(new dom.Text(lines.join('\n$indent') + '\n')); |
546 indentNeeded = true; | 551 indentNeeded = true; |
547 } else { | 552 } else { |
548 buffer.add(new dom.Text(lines.join('\n$indent'))); | 553 buffer.add(new dom.Text(lines.join('\n$indent'))); |
549 indentNeeded = false; | 554 indentNeeded = false; |
550 } | 555 } |
551 } | 556 } |
552 } | 557 } |
OLD | NEW |