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