| 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 */ | 50 */ |
| 51 typedef String FileContentsComputer(); | 51 typedef String FileContentsComputer(); |
| 52 | 52 |
| 53 /** | 53 /** |
| 54 * Mixin class for generating code. | 54 * Mixin class for generating code. |
| 55 */ | 55 */ |
| 56 class CodeGenerator { | 56 class CodeGenerator { |
| 57 _CodeGeneratorState _state; | 57 _CodeGeneratorState _state; |
| 58 | 58 |
| 59 /** | 59 /** |
| 60 * Settings that specialize code generation behavior for a given |
| 61 * programming language. |
| 62 */ |
| 63 CodeGeneratorSettings codeGeneratorSettings; |
| 64 |
| 65 /** |
| 60 * Measure the width of the current indentation level. | 66 * Measure the width of the current indentation level. |
| 61 */ | 67 */ |
| 62 int get indentWidth => _state.nextIndent.length; | 68 int get indentWidth => _state.nextIndent.length; |
| 63 | 69 |
| 64 /** | 70 /** |
| 65 * Execute [callback], collecting any code that is output using [write] | 71 * Execute [callback], collecting any code that is output using [write] |
| 66 * or [writeln], and return the result as a string. | 72 * or [writeln], and return the result as a string. |
| 67 */ | 73 */ |
| 68 String collectCode(void callback()) { | 74 String collectCode(void callback()) { |
| 69 _CodeGeneratorState oldState = _state; | 75 _CodeGeneratorState oldState = _state; |
| 70 try { | 76 try { |
| 71 _state = new _CodeGeneratorState(); | 77 _state = new _CodeGeneratorState(); |
| 72 callback(); | 78 callback(); |
| 73 return _state.buffer.toString().replaceAll(trailingWhitespaceRegExp, ''); | 79 return _state.buffer.toString().replaceAll(trailingWhitespaceRegExp, ''); |
| 74 } finally { | 80 } finally { |
| 75 _state = oldState; | 81 _state = oldState; |
| 76 } | 82 } |
| 77 } | 83 } |
| 78 | 84 |
| 79 /** | 85 /** |
| 80 * Generate a doc comment based on the HTML in [docs]. | 86 * Generate a doc comment based on the HTML in [docs]. |
| 81 * | 87 * |
| 82 * If [javadocStyle] is true, then the output is compatable with Javadoc, | 88 * If [javadocStyle] is true, then the output is compatable with Javadoc, |
| 83 * which understands certain HTML constructs. | 89 * which understands certain HTML constructs. |
| 84 */ | 90 */ |
| 85 void docComment(List<dom.Node> docs, {int width: 79, bool javadocStyle: | 91 void docComment(List<dom.Node> docs) { |
| 86 false}) { | |
| 87 if (containsOnlyWhitespace(docs)) { | 92 if (containsOnlyWhitespace(docs)) { |
| 88 return; | 93 return; |
| 89 } | 94 } |
| 90 writeln('/**'); | 95 writeln(codeGeneratorSettings.docCommentStartMarker); |
| 91 indentBy(' * ', () { | 96 var width = codeGeneratorSettings.commentLineLength; |
| 97 var javadocStyle = codeGeneratorSettings.languageName == 'java'; |
| 98 indentBy(codeGeneratorSettings.docCommentLineLeader, () { |
| 92 write(nodesToText(docs, width - _state.indent.length, javadocStyle)); | 99 write(nodesToText(docs, width - _state.indent.length, javadocStyle)); |
| 93 }); | 100 }); |
| 94 writeln(' */'); | 101 writeln(codeGeneratorSettings.docCommentEndMarker); |
| 102 } |
| 103 |
| 104 void lineComment(List<dom.Node> docs) { |
| 105 if (containsOnlyWhitespace(docs)) { |
| 106 return; |
| 107 } |
| 108 write(codeGeneratorSettings.lineCommentLineLeader); |
| 109 var width = codeGeneratorSettings.commentLineLength; |
| 110 indentBy(codeGeneratorSettings.lineCommentLineLeader, () { |
| 111 write(nodesToText(docs, width - _state.indent.length, false)); |
| 112 }); |
| 95 } | 113 } |
| 96 | 114 |
| 97 /** | 115 /** |
| 98 * Execute [callback], indenting any code it outputs by two spaces. | 116 * Execute [callback], indenting any code it outputs by two spaces. |
| 99 */ | 117 */ |
| 100 void indent(void callback()) => indentSpecial(' ', ' ', callback); | 118 void indent(void callback()) => indentSpecial(' ', ' ', callback); |
| 101 | 119 |
| 102 /** | 120 /** |
| 103 * Execute [callback], using [additionalIndent] to indent any code it outputs. | 121 * Execute [callback], using [additionalIndent] to indent any code it outputs. |
| 104 */ | 122 */ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 119 _state.indent += additionalIndent; | 137 _state.indent += additionalIndent; |
| 120 callback(); | 138 callback(); |
| 121 } finally { | 139 } finally { |
| 122 _state.nextIndent = oldNextIndent; | 140 _state.nextIndent = oldNextIndent; |
| 123 _state.indent = oldIndent; | 141 _state.indent = oldIndent; |
| 124 } | 142 } |
| 125 } | 143 } |
| 126 | 144 |
| 127 void outputHeader({bool javaStyle: false}) { | 145 void outputHeader({bool javaStyle: false}) { |
| 128 String header; | 146 String header; |
| 129 if (javaStyle) { | 147 if (codeGeneratorSettings.languageName == 'java') { |
| 130 header = ''' | 148 header = ''' |
| 131 /* | 149 /* |
| 132 * Copyright (c) 2014, the Dart project authors. | 150 * Copyright (c) 2014, the Dart project authors. |
| 133 * | 151 * |
| 134 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except | 152 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except |
| 135 * in compliance with the License. You may obtain a copy of the License at | 153 * in compliance with the License. You may obtain a copy of the License at |
| 136 * | 154 * |
| 137 * http://www.eclipse.org/legal/epl-v10.html | 155 * http://www.eclipse.org/legal/epl-v10.html |
| 138 * | 156 * |
| 139 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License | 157 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License |
| 140 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express | 158 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express |
| 141 * or implied. See the License for the specific language governing permissions a
nd limitations under | 159 * or implied. See the License for the specific language governing permissions a
nd limitations under |
| 142 * the License. | 160 * the License. |
| 143 * | 161 * |
| 144 * This file has been automatically generated. Please do not edit it manually. | 162 * This file has been automatically generated. Please do not edit it manually. |
| 145 * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generat
e_files". | 163 * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generat
e_files". |
| 146 */'''; | 164 */'''; |
| 165 } else if (codeGeneratorSettings.languageName == 'python') { |
| 166 header = ''' |
| 167 # Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 168 # for details. All rights reserved. Use of this source code is governed by a |
| 169 # BSD-style license that can be found in the LICENSE file. |
| 170 # |
| 171 # This file has been automatically generated. Please do not edit it manually. |
| 172 # To regenerate the file, use the script |
| 173 # "pkg/analysis_server/tool/spec/generate_files". |
| 174 '''; |
| 147 } else { | 175 } else { |
| 148 header = ''' | 176 header = ''' |
| 149 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 177 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 150 // for details. All rights reserved. Use of this source code is governed by a | 178 // for details. All rights reserved. Use of this source code is governed by a |
| 151 // BSD-style license that can be found in the LICENSE file. | 179 // BSD-style license that can be found in the LICENSE file. |
| 152 // | 180 // |
| 153 // This file has been automatically generated. Please do not edit it manually. | 181 // This file has been automatically generated. Please do not edit it manually. |
| 154 // To regenerate the file, use the script | 182 // To regenerate the file, use the script |
| 155 // "pkg/analysis_server/tool/spec/generate_files". | 183 // "pkg/analysis_server/tool/spec/generate_files". |
| 156 '''; | 184 '''; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 | 419 |
| 392 /** | 420 /** |
| 393 * Output text, ending the current line. | 421 * Output text, ending the current line. |
| 394 */ | 422 */ |
| 395 void writeln([Object obj = '']) { | 423 void writeln([Object obj = '']) { |
| 396 _state.write('$obj\n'); | 424 _state.write('$obj\n'); |
| 397 } | 425 } |
| 398 } | 426 } |
| 399 | 427 |
| 400 /** | 428 /** |
| 429 * Controls several settings of [CodeGenerator]. |
| 430 * |
| 431 * The default settings are valid for generating Java and Dart code. |
| 432 */ |
| 433 class CodeGeneratorSettings { |
| 434 /** |
| 435 * Name of the language being generated. Lowercase. |
| 436 */ |
| 437 String languageName; |
| 438 |
| 439 /** |
| 440 * Marker used in line comments. |
| 441 */ |
| 442 String lineCommentLineLeader; |
| 443 |
| 444 /** |
| 445 * Start marker for doc comments. |
| 446 */ |
| 447 String docCommentStartMarker; |
| 448 |
| 449 /** |
| 450 * Line leader for body lines in doc comments. |
| 451 */ |
| 452 String docCommentLineLeader; |
| 453 |
| 454 /** |
| 455 * End marker for doc comments. |
| 456 */ |
| 457 String docCommentEndMarker; |
| 458 |
| 459 /** |
| 460 * Line length for doc comment lines. |
| 461 */ |
| 462 int commentLineLength; |
| 463 |
| 464 CodeGeneratorSettings({this.languageName: 'java', this.lineCommentLineLeader:
'// ', |
| 465 this.docCommentStartMarker: '/**', this.docCommentLineLeader: ' * ', |
| 466 this.docCommentEndMarker: ' */', this.commentLineLength: 79}); |
| 467 } |
| 468 |
| 469 /** |
| 401 * State used by [CodeGenerator]. | 470 * State used by [CodeGenerator]. |
| 402 */ | 471 */ |
| 403 class _CodeGeneratorState { | 472 class _CodeGeneratorState { |
| 404 StringBuffer buffer = new StringBuffer(); | 473 StringBuffer buffer = new StringBuffer(); |
| 405 String nextIndent = ''; | 474 String nextIndent = ''; |
| 406 String indent = ''; | 475 String indent = ''; |
| 407 bool indentNeeded = true; | 476 bool indentNeeded = true; |
| 408 | 477 |
| 409 void write(String text) { | 478 void write(String text) { |
| 410 List<String> lines = text.split('\n'); | 479 List<String> lines = text.split('\n'); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 if (lines.last.isEmpty) { | 522 if (lines.last.isEmpty) { |
| 454 lines.removeLast(); | 523 lines.removeLast(); |
| 455 buffer.add(new dom.Text(lines.join('\n$indent') + '\n')); | 524 buffer.add(new dom.Text(lines.join('\n$indent') + '\n')); |
| 456 indentNeeded = true; | 525 indentNeeded = true; |
| 457 } else { | 526 } else { |
| 458 buffer.add(new dom.Text(lines.join('\n$indent'))); | 527 buffer.add(new dom.Text(lines.join('\n$indent'))); |
| 459 indentNeeded = false; | 528 indentNeeded = false; |
| 460 } | 529 } |
| 461 } | 530 } |
| 462 } | 531 } |
| OLD | NEW |