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

Side by Side Diff: pkg/compiler/lib/src/js/printer.dart

Issue 915533002: Steps towards making dart2js JS AST templates an indepentent library. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « pkg/compiler/lib/src/js/nodes.dart ('k') | pkg/compiler/lib/src/js/template.dart » ('j') | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of js; 5 part of js;
6 6
7 class Printer extends Indentation implements NodeVisitor { 7
8 class JavaScriptPrintingOptions {
8 final bool shouldCompressOutput; 9 final bool shouldCompressOutput;
9 leg.DiagnosticListener diagnosticListener; 10 final bool minifyLocalVariables;
10 CodeBuffer outBuffer; 11 JavaScriptPrintingOptions(
12 {this.shouldCompressOutput: false,
13 this.minifyLocalVariables: false});
14 }
15
16 /**
17 * An environment in which JavaScript printing is done.
18 *
19 * The context contains
floitsch 2015/02/10 14:43:52 nit: we tend to use "///" now (and this file seems
sra1 2015/02/11 00:13:07 Done. I prefer /**/ for longer comments, but /// l
20 */
21 abstract class JavaScriptPrintingContext {
22 /// Signals an error. This should happen only for serious internal errors.
23 void error(String message) { throw message; }
24
25 /// Adds [string] to the output.
26 void emit(String string);
27
28 void enterNode(Node node) {}
29 void exitNode(Node node) {}
30 }
31
32
33 class Printer implements NodeVisitor {
34 final JavaScriptPrintingOptions options;
35 final JavaScriptPrintingContext context;
36 final bool shouldCompressOutput;
37 final DanglingElseVisitor danglingElseVisitor;
38 final LocalNamer localNamer;
39
11 bool inForInit = false; 40 bool inForInit = false;
12 bool atStatementBegin = false; 41 bool atStatementBegin = false;
13 final DanglingElseVisitor danglingElseVisitor;
14 final LocalNamer localNamer;
15 bool pendingSemicolon = false; 42 bool pendingSemicolon = false;
16 bool pendingSpace = false; 43 bool pendingSpace = false;
17 DumpInfoTask monitor = null; 44
45 // The current indentation level.
46 int _indentLevel = 0;
47 // A cache of all indentation strings used so far.
48 List<String> _indentList = <String>[""];
18 49
19 static final identifierCharacterRegExp = new RegExp(r'^[a-zA-Z_0-9$]'); 50 static final identifierCharacterRegExp = new RegExp(r'^[a-zA-Z_0-9$]');
20 static final expressionContinuationRegExp = new RegExp(r'^[-+([]'); 51 static final expressionContinuationRegExp = new RegExp(r'^[-+([]');
21 52
22 Printer(leg.DiagnosticListener diagnosticListener, DumpInfoTask monitor, 53 Printer(JavaScriptPrintingOptions options,
23 { bool enableMinification: false, allowVariableMinification: true }) 54 JavaScriptPrintingContext context)
24 : shouldCompressOutput = enableMinification, 55 : options = options,
25 monitor = monitor, 56 context = context,
26 diagnosticListener = diagnosticListener, 57 shouldCompressOutput = options.shouldCompressOutput,
27 outBuffer = new CodeBuffer(), 58 danglingElseVisitor = new DanglingElseVisitor(context),
28 danglingElseVisitor = new DanglingElseVisitor(diagnosticListener), 59 localNamer = determineRenamer(options.shouldCompressOutput,
29 localNamer = determineRenamer(enableMinification, 60 options.minifyLocalVariables);
30 allowVariableMinification);
31 61
32 static LocalNamer determineRenamer(bool shouldCompressOutput, 62 static LocalNamer determineRenamer(bool shouldCompressOutput,
33 bool allowVariableMinification) { 63 bool allowVariableMinification) {
34 return (shouldCompressOutput && allowVariableMinification) 64 return (shouldCompressOutput && allowVariableMinification)
35 ? new MinifyRenamer() : new IdentityNamer(); 65 ? new MinifyRenamer() : new IdentityNamer();
36 } 66 }
37 67
68
69 // The current indentation string.
70 String get indentation {
71 // Lazily add new indentation strings as required.
72 while (_indentList.length <= _indentLevel) {
73 _indentList.add(_indentList.last + " ");
74 }
75 return _indentList[_indentLevel];
76 }
77
78 void indentMore() {
79 _indentLevel++;
80 }
81
82 void indentLess() {
83 _indentLevel--;
84 }
85
86
38 /// Always emit a newline, even under `enableMinification`. 87 /// Always emit a newline, even under `enableMinification`.
39 void forceLine() { 88 void forceLine() {
40 out("\n"); 89 out("\n");
41 } 90 }
42 /// Emits a newline for readability. 91 /// Emits a newline for readability.
43 void lineOut() { 92 void lineOut() {
44 if (!shouldCompressOutput) forceLine(); 93 if (!shouldCompressOutput) forceLine();
45 } 94 }
46 void spaceOut() { 95 void spaceOut() {
47 if (!shouldCompressOutput) out(" "); 96 if (!shouldCompressOutput) out(" ");
48 } 97 }
49 98
50 String lastAddedString = null; 99 String lastAddedString = null;
51 int get lastCharCode { 100 int get lastCharCode {
52 if (lastAddedString == null) return 0; 101 if (lastAddedString == null) return 0;
53 assert(lastAddedString.length != ""); 102 assert(lastAddedString.length != "");
54 return lastAddedString.codeUnitAt(lastAddedString.length - 1); 103 return lastAddedString.codeUnitAt(lastAddedString.length - 1);
55 } 104 }
56 105
57 void out(String str) { 106 void out(String str) {
58 if (str != "") { 107 if (str != "") {
59 if (pendingSemicolon) { 108 if (pendingSemicolon) {
60 if (!shouldCompressOutput) { 109 if (!shouldCompressOutput) {
61 outBuffer.add(";"); 110 context.emit(";");
62 } else if (str != "}") { 111 } else if (str != "}") {
63 // We want to output newline instead of semicolon because it makes 112 // We want to output newline instead of semicolon because it makes
64 // the raw stack traces much easier to read and it also makes line- 113 // the raw stack traces much easier to read and it also makes line-
65 // based tools like diff work much better. JavaScript will 114 // based tools like diff work much better. JavaScript will
66 // automatically insert the semicolon at the newline if it means a 115 // automatically insert the semicolon at the newline if it means a
67 // parsing error is avoided, so we can only do this trick if the 116 // parsing error is avoided, so we can only do this trick if the
68 // next line is not something that can be glued onto a valid 117 // next line is not something that can be glued onto a valid
69 // expression to make a new valid expression. 118 // expression to make a new valid expression.
70 119
71 // If we're using the new emitter where most pretty printed code 120 // If we're using the new emitter where most pretty printed code
72 // is escaped in strings, it is a lot easier to deal with semicolons 121 // is escaped in strings, it is a lot easier to deal with semicolons
73 // than newlines because the former doesn't need escaping. 122 // than newlines because the former doesn't need escaping.
123 // TODO(sra): This formatting choice via JavaScriptPrintingOptions.
74 if (USE_NEW_EMITTER || expressionContinuationRegExp.hasMatch(str)) { 124 if (USE_NEW_EMITTER || expressionContinuationRegExp.hasMatch(str)) {
75 outBuffer.add(";"); 125 context.emit(";");
76 } else { 126 } else {
77 outBuffer.add("\n"); 127 context.emit("\n");
78 } 128 }
79 } 129 }
80 } 130 }
81 if (pendingSpace && 131 if (pendingSpace &&
82 (!shouldCompressOutput || identifierCharacterRegExp.hasMatch(str))) { 132 (!shouldCompressOutput || identifierCharacterRegExp.hasMatch(str))) {
83 outBuffer.add(" "); 133 context.emit(" ");
84 } 134 }
85 pendingSpace = false; 135 pendingSpace = false;
86 pendingSemicolon = false; 136 pendingSemicolon = false;
87 outBuffer.add(str); 137 context.emit(str);
88 lastAddedString = str; 138 lastAddedString = str;
89 } 139 }
90 } 140 }
91 141
92 void outLn(String str) { 142 void outLn(String str) {
93 out(str); 143 out(str);
94 lineOut(); 144 lineOut();
95 } 145 }
96 146
97 void outSemicolonLn() { 147 void outSemicolonLn() {
98 if (shouldCompressOutput) { 148 if (shouldCompressOutput) {
99 pendingSemicolon = true; 149 pendingSemicolon = true;
100 } else { 150 } else {
101 out(";"); 151 out(";");
102 forceLine(); 152 forceLine();
103 } 153 }
104 } 154 }
105 155
106 void outIndent(String str) { indent(); out(str); } 156 void outIndent(String str) { indent(); out(str); }
107 void outIndentLn(String str) { indent(); outLn(str); } 157 void outIndentLn(String str) { indent(); outLn(str); }
108 void indent() { 158 void indent() {
109 if (!shouldCompressOutput) { 159 if (!shouldCompressOutput) {
110 out(indentation); 160 out(indentation);
111 } 161 }
112 } 162 }
113 163
114 void beginSourceRange(Node node) {
115 if (node.sourceInformation != null) {
116 node.sourceInformation.beginMapping(outBuffer);
117 }
118 }
119
120 void endSourceRange(Node node) {
121 if (node.sourceInformation != null) {
122 node.sourceInformation.endMapping(outBuffer);
123 }
124 }
125
126 visit(Node node) { 164 visit(Node node) {
127 beginSourceRange(node); 165 context.enterNode(node);
128 if (monitor != null) monitor.enteringAst(node, outBuffer.length);
129
130 node.accept(this); 166 node.accept(this);
131 167 context.exitNode(node);
132 if (monitor != null) monitor.exitingAst(node, outBuffer.length);
133 endSourceRange(node);
134 } 168 }
135 169
136 visitCommaSeparated(List<Node> nodes, int hasRequiredType, 170 visitCommaSeparated(List<Node> nodes, int hasRequiredType,
137 {bool newInForInit, bool newAtStatementBegin}) { 171 {bool newInForInit, bool newAtStatementBegin}) {
138 for (int i = 0; i < nodes.length; i++) { 172 for (int i = 0; i < nodes.length; i++) {
139 if (i != 0) { 173 if (i != 0) {
140 atStatementBegin = false; 174 atStatementBegin = false;
141 out(","); 175 out(",");
142 spaceOut(); 176 spaceOut();
143 } 177 }
144 visitNestedExpression(nodes[i], hasRequiredType, 178 visitNestedExpression(nodes[i], hasRequiredType,
145 newInForInit: newInForInit, 179 newInForInit: newInForInit,
146 newAtStatementBegin: newAtStatementBegin); 180 newAtStatementBegin: newAtStatementBegin);
147 } 181 }
148 } 182 }
149 183
150 visitAll(List<Node> nodes) { 184 visitAll(List<Node> nodes) {
151 nodes.forEach(visit); 185 nodes.forEach(visit);
152 } 186 }
153 187
154 visitProgram(Program program) { 188 visitProgram(Program program) {
155 visitAll(program.body); 189 visitAll(program.body);
156 } 190 }
157 191
192 // TODO(sra): Remove unused Blob node.
158 visitBlob(Blob node) { 193 visitBlob(Blob node) {
159 outBuffer.addBuffer(node.buffer); 194 context.error('js.Blob node deprecated');
160 } 195 }
161 196
162 bool blockBody(Node body, {bool needsSeparation, bool needsNewline}) { 197 bool blockBody(Node body, {bool needsSeparation, bool needsNewline}) {
163 if (body is Block) { 198 if (body is Block) {
164 spaceOut(); 199 spaceOut();
165 blockOut(body, false, needsNewline); 200 blockOut(body, false, needsNewline);
166 return true; 201 return true;
167 } 202 }
168 if (shouldCompressOutput && needsSeparation) { 203 if (shouldCompressOutput && needsSeparation) {
169 // If [shouldCompressOutput] is false, then the 'lineOut' will insert 204 // If [shouldCompressOutput] is false, then the 'lineOut' will insert
170 // the separation. 205 // the separation.
171 out(" "); 206 out(" ");
172 } else { 207 } else {
173 lineOut(); 208 lineOut();
174 } 209 }
175 indentBlock(() => visit(body)); 210 indentMore();
211 visit(body);
212 indentLess();
176 return false; 213 return false;
177 } 214 }
178 215
179 void blockOutWithoutBraces(Node node) { 216 void blockOutWithoutBraces(Node node) {
180 if (node is Block) { 217 if (node is Block) {
181 beginSourceRange(node); 218 context.enterNode(node);
182 Block block = node; 219 Block block = node;
183 block.statements.forEach(blockOutWithoutBraces); 220 block.statements.forEach(blockOutWithoutBraces);
184 endSourceRange(node); 221 context.exitNode(node);
185 } else { 222 } else {
186 visit(node); 223 visit(node);
187 } 224 }
188 } 225 }
189 226
190 void blockOut(Block node, bool shouldIndent, bool needsNewline) { 227 void blockOut(Block node, bool shouldIndent, bool needsNewline) {
191 if (shouldIndent) indent(); 228 if (shouldIndent) indent();
192 beginSourceRange(node); 229 context.enterNode(node);
193 out("{"); 230 out("{");
194 lineOut(); 231 lineOut();
195 indentBlock(() => node.statements.forEach(blockOutWithoutBraces)); 232 indentMore();
233 node.statements.forEach(blockOutWithoutBraces);
234 indentLess();
196 indent(); 235 indent();
197 out("}"); 236 out("}");
198 endSourceRange(node); 237 context.exitNode(node);
199 if (needsNewline) lineOut(); 238 if (needsNewline) lineOut();
200 } 239 }
201 240
202 visitBlock(Block block) { 241 visitBlock(Block block) {
203 blockOut(block, true, true); 242 blockOut(block, true, true);
204 } 243 }
205 244
206 visitExpressionStatement(ExpressionStatement expressionStatement) { 245 visitExpressionStatement(ExpressionStatement expressionStatement) {
207 indent(); 246 indent();
208 visitNestedExpression(expressionStatement.expression, EXPRESSION, 247 visitNestedExpression(expressionStatement.expression, EXPRESSION,
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 439
401 visitSwitch(Switch node) { 440 visitSwitch(Switch node) {
402 outIndent("switch"); 441 outIndent("switch");
403 spaceOut(); 442 spaceOut();
404 out("("); 443 out("(");
405 visitNestedExpression(node.key, EXPRESSION, 444 visitNestedExpression(node.key, EXPRESSION,
406 newInForInit: false, newAtStatementBegin: false); 445 newInForInit: false, newAtStatementBegin: false);
407 out(")"); 446 out(")");
408 spaceOut(); 447 spaceOut();
409 outLn("{"); 448 outLn("{");
410 indentBlock(() => visitAll(node.cases)); 449 indentMore();
450 visitAll(node.cases);
451 indentLess();
411 outIndentLn("}"); 452 outIndentLn("}");
412 } 453 }
413 454
414 visitCase(Case node) { 455 visitCase(Case node) {
415 outIndent("case"); 456 outIndent("case");
416 pendingSpace = true; 457 pendingSpace = true;
417 visitNestedExpression(node.expression, EXPRESSION, 458 visitNestedExpression(node.expression, EXPRESSION,
418 newInForInit: false, newAtStatementBegin: false); 459 newInForInit: false, newAtStatementBegin: false);
419 outLn(":"); 460 outLn(":");
420 if (!node.body.statements.isEmpty) { 461 if (!node.body.statements.isEmpty) {
421 indentBlock(() => blockOutWithoutBraces(node.body)); 462 indentMore();
463 blockOutWithoutBraces(node.body);
464 indentLess();
422 } 465 }
423 } 466 }
424 467
425 visitDefault(Default node) { 468 visitDefault(Default node) {
426 outIndentLn("default:"); 469 outIndentLn("default:");
427 if (!node.body.statements.isEmpty) { 470 if (!node.body.statements.isEmpty) {
428 indentBlock(() => blockOutWithoutBraces(node.body)); 471 indentMore();
472 blockOutWithoutBraces(node.body);
473 indentLess();
429 } 474 }
430 } 475 }
431 476
432 visitLabeledStatement(LabeledStatement node) { 477 visitLabeledStatement(LabeledStatement node) {
433 outIndent("${node.label}:"); 478 outIndent("${node.label}:");
434 blockBody(node.body, needsSeparation: false, needsNewline: true); 479 blockBody(node.body, needsSeparation: false, needsNewline: true);
435 } 480 }
436 481
437 void functionOut(Fun fun, Node name, VarCollector vars) { 482 void functionOut(Fun fun, Node name, VarCollector vars) {
438 out("function"); 483 out("function");
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 rightPrecedenceRequirement = MULTIPLICATIVE; 680 rightPrecedenceRequirement = MULTIPLICATIVE;
636 break; 681 break;
637 case "*": 682 case "*":
638 case "/": 683 case "/":
639 case "%": 684 case "%":
640 leftPrecedenceRequirement = MULTIPLICATIVE; 685 leftPrecedenceRequirement = MULTIPLICATIVE;
641 // We cannot remove parenthesis for "*" because of precision issues. 686 // We cannot remove parenthesis for "*" because of precision issues.
642 rightPrecedenceRequirement = UNARY; 687 rightPrecedenceRequirement = UNARY;
643 break; 688 break;
644 default: 689 default:
645 diagnosticListener 690 context.error("Forgot operator: $op");
646 .internalError(NO_LOCATION_SPANNABLE, "Forgot operator: $op");
647 } 691 }
648 692
649 visitNestedExpression(left, leftPrecedenceRequirement, 693 visitNestedExpression(left, leftPrecedenceRequirement,
650 newInForInit: inForInit, 694 newInForInit: inForInit,
651 newAtStatementBegin: atStatementBegin); 695 newAtStatementBegin: atStatementBegin);
652 696
653 if (op == "in" || op == "instanceof") { 697 if (op == "in" || op == "instanceof") {
654 // There are cases where the space is not required but without further 698 // There are cases where the space is not required but without further
655 // analysis we cannot know. 699 // analysis we cannot know.
656 out(" "); 700 out(" ");
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 out(node.pattern); 917 out(node.pattern);
874 } 918 }
875 919
876 visitLiteralExpression(LiteralExpression node) { 920 visitLiteralExpression(LiteralExpression node) {
877 String template = node.template; 921 String template = node.template;
878 List<Expression> inputs = node.inputs; 922 List<Expression> inputs = node.inputs;
879 923
880 List<String> parts = template.split('#'); 924 List<String> parts = template.split('#');
881 int inputsLength = inputs == null ? 0 : inputs.length; 925 int inputsLength = inputs == null ? 0 : inputs.length;
882 if (parts.length != inputsLength + 1) { 926 if (parts.length != inputsLength + 1) {
883 diagnosticListener.internalError(NO_LOCATION_SPANNABLE, 927 context.error('Wrong number of arguments for JS: $template');
884 'Wrong number of arguments for JS: $template');
885 } 928 }
886 // Code that uses JS must take care of operator precedences, and 929 // Code that uses JS must take care of operator precedences, and
887 // put parenthesis if needed. 930 // put parenthesis if needed.
888 out(parts[0]); 931 out(parts[0]);
889 for (int i = 0; i < inputsLength; i++) { 932 for (int i = 0; i < inputsLength; i++) {
890 visit(inputs[i]); 933 visit(inputs[i]);
891 out(parts[i + 1]); 934 out(parts[i + 1]);
892 } 935 }
893 } 936 }
894 937
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 if (decl.allowRename) vars.add(decl.name); 1044 if (decl.allowRename) vars.add(decl.name);
1002 } 1045 }
1003 } 1046 }
1004 1047
1005 1048
1006 /** 1049 /**
1007 * Returns true, if the given node must be wrapped into braces when used 1050 * Returns true, if the given node must be wrapped into braces when used
1008 * as then-statement in an [If] that has an else branch. 1051 * as then-statement in an [If] that has an else branch.
1009 */ 1052 */
1010 class DanglingElseVisitor extends BaseVisitor<bool> { 1053 class DanglingElseVisitor extends BaseVisitor<bool> {
1011 leg.DiagnosticListener diagnosticListener; 1054 JavaScriptPrintingContext context;
1012 1055
1013 DanglingElseVisitor(this.diagnosticListener); 1056 DanglingElseVisitor(this.context);
1014 1057
1015 bool visitProgram(Program node) => false; 1058 bool visitProgram(Program node) => false;
1016 1059
1017 bool visitNode(Statement node) { 1060 bool visitNode(Statement node) {
1018 diagnosticListener 1061 context.error("Forgot node: $node");
1019 .internalError(NO_LOCATION_SPANNABLE, "Forgot node: $node");
1020 return null; 1062 return null;
1021 } 1063 }
1022 1064
1023 bool visitBlock(Block node) => false; 1065 bool visitBlock(Block node) => false;
1024 bool visitExpressionStatement(ExpressionStatement node) => false; 1066 bool visitExpressionStatement(ExpressionStatement node) => false;
1025 bool visitEmptyStatement(EmptyStatement node) => false; 1067 bool visitEmptyStatement(EmptyStatement node) => false;
1026 bool visitIf(If node) { 1068 bool visitIf(If node) {
1027 if (!node.hasElse) return true; 1069 if (!node.hasElse) return true;
1028 return node.otherwise.accept(this); 1070 return node.otherwise.accept(this);
1029 } 1071 }
(...skipping 18 matching lines...) Expand all
1048 bool visitDefault(Default node) => false; 1090 bool visitDefault(Default node) => false;
1049 bool visitFunctionDeclaration(FunctionDeclaration node) => false; 1091 bool visitFunctionDeclaration(FunctionDeclaration node) => false;
1050 bool visitLabeledStatement(LabeledStatement node) 1092 bool visitLabeledStatement(LabeledStatement node)
1051 => node.body.accept(this); 1093 => node.body.accept(this);
1052 bool visitLiteralStatement(LiteralStatement node) => true; 1094 bool visitLiteralStatement(LiteralStatement node) => true;
1053 1095
1054 bool visitExpression(Expression node) => false; 1096 bool visitExpression(Expression node) => false;
1055 } 1097 }
1056 1098
1057 1099
1058 CodeBuffer prettyPrint(Node node, leg.Compiler compiler,
1059 {DumpInfoTask monitor,
1060 bool allowVariableMinification: true}) {
1061 Printer printer =
1062 new Printer(compiler, monitor,
1063 enableMinification: compiler.enableMinification,
1064 allowVariableMinification: allowVariableMinification);
1065 printer.visit(node);
1066 return printer.outBuffer;
1067 }
1068
1069
1070 abstract class LocalNamer { 1100 abstract class LocalNamer {
1071 String getName(String oldName); 1101 String getName(String oldName);
1072 String declareVariable(String oldName); 1102 String declareVariable(String oldName);
1073 String declareParameter(String oldName); 1103 String declareParameter(String oldName);
1074 void enterScope(VarCollector vars); 1104 void enterScope(VarCollector vars);
1075 void leaveScope(); 1105 void leaveScope();
1076 } 1106 }
1077 1107
1078 1108
1079 class IdentityNamer implements LocalNamer { 1109 class IdentityNamer implements LocalNamer {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS)); 1228 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS));
1199 } 1229 }
1200 codes.add(charCodes.$0 + digit); 1230 codes.add(charCodes.$0 + digit);
1201 newName = new String.fromCharCodes(codes); 1231 newName = new String.fromCharCodes(codes);
1202 } 1232 }
1203 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName)); 1233 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName));
1204 maps.last[oldName] = newName; 1234 maps.last[oldName] = newName;
1205 return newName; 1235 return newName;
1206 } 1236 }
1207 } 1237 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js/nodes.dart ('k') | pkg/compiler/lib/src/js/template.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698