OLD | NEW |
---|---|
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_ast; | 5 part of js_ast; |
6 | 6 |
7 | 7 |
8 class JavaScriptPrintingOptions { | 8 class JavaScriptPrintingOptions { |
9 final bool shouldCompressOutput; | 9 final bool shouldCompressOutput; |
10 final bool minifyLocalVariables; | 10 final bool minifyLocalVariables; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 } | 197 } |
198 | 198 |
199 visitAll(List<Node> nodes) { | 199 visitAll(List<Node> nodes) { |
200 nodes.forEach(visit); | 200 nodes.forEach(visit); |
201 } | 201 } |
202 | 202 |
203 visitProgram(Program program) { | 203 visitProgram(Program program) { |
204 visitAll(program.body); | 204 visitAll(program.body); |
205 } | 205 } |
206 | 206 |
207 bool blockBody(Node body, {bool needsSeparation, bool needsNewline}) { | 207 bool blockBody(Statement body, {bool needsSeparation, bool needsNewline}) { |
208 if (body is Block && body.statements.length == 1) { | |
209 Block block = body; | |
210 body = block.statements.single; | |
211 } | |
208 if (body is Block) { | 212 if (body is Block) { |
209 spaceOut(); | 213 spaceOut(); |
210 blockOut(body, false, needsNewline); | 214 blockOut(body, shouldIndent: false, needsNewline: needsNewline); |
211 return true; | 215 return true; |
212 } | 216 } |
213 if (shouldCompressOutput && needsSeparation) { | 217 if (shouldCompressOutput && needsSeparation) { |
214 // If [shouldCompressOutput] is false, then the 'lineOut' will insert | 218 // If [shouldCompressOutput] is false, then the 'lineOut' will insert |
215 // the separation. | 219 // the separation. |
216 out(" "); | 220 out(" "); |
217 } else { | 221 } else { |
218 lineOut(); | 222 lineOut(); |
219 } | 223 } |
220 indentMore(); | 224 indentMore(); |
221 visit(body); | 225 visit(body); |
222 indentLess(); | 226 indentLess(); |
223 return false; | 227 return false; |
224 } | 228 } |
225 | 229 |
226 void blockOutWithoutBraces(Node node) { | 230 void blockOutWithoutBraces(Node node) { |
227 if (node is Block) { | 231 if (node is Block) { |
228 context.enterNode(node); | 232 context.enterNode(node); |
229 Block block = node; | 233 Block block = node; |
230 block.statements.forEach(blockOutWithoutBraces); | 234 block.statements.forEach(blockOutWithoutBraces); |
231 context.exitNode(node); | 235 context.exitNode(node); |
232 } else { | 236 } else { |
233 visit(node); | 237 visit(node); |
234 } | 238 } |
235 } | 239 } |
236 | 240 |
237 void blockOut(Block node, bool shouldIndent, bool needsNewline) { | 241 void blockOut(Block node, {bool shouldIndent, bool needsNewline}) { |
238 if (shouldIndent) indent(); | 242 if (shouldIndent) indent(); |
239 context.enterNode(node); | 243 context.enterNode(node); |
240 out("{"); | 244 out("{"); |
241 lineOut(); | 245 lineOut(); |
242 indentMore(); | 246 indentMore(); |
243 node.statements.forEach(blockOutWithoutBraces); | 247 node.statements.forEach(blockOutWithoutBraces); |
244 indentLess(); | 248 indentLess(); |
245 indent(); | 249 indent(); |
246 out("}"); | 250 out("}"); |
247 context.exitNode(node); | 251 context.exitNode(node); |
248 if (needsNewline) lineOut(); | 252 if (needsNewline) lineOut(); |
249 } | 253 } |
250 | 254 |
251 visitBlock(Block block) { | 255 visitBlock(Block block) { |
252 blockOut(block, true, true); | 256 blockOut(block, shouldIndent: true, needsNewline: true); |
253 } | 257 } |
254 | 258 |
255 visitExpressionStatement(ExpressionStatement expressionStatement) { | 259 visitExpressionStatement(ExpressionStatement expressionStatement) { |
256 indent(); | 260 indent(); |
257 visitNestedExpression(expressionStatement.expression, EXPRESSION, | 261 visitNestedExpression(expressionStatement.expression, EXPRESSION, |
258 newInForInit: false, newAtStatementBegin: true); | 262 newInForInit: false, newAtStatementBegin: true); |
259 outSemicolonLn(); | 263 outSemicolonLn(); |
260 } | 264 } |
261 | 265 |
262 visitEmptyStatement(EmptyStatement nop) { | 266 visitEmptyStatement(EmptyStatement nop) { |
263 outIndentLn(";"); | 267 outIndentLn(";"); |
264 } | 268 } |
265 | 269 |
266 void ifOut(If node, bool shouldIndent) { | 270 void ifOut(If node, bool shouldIndent) { |
267 Node then = node.then; | 271 Statement then = node.then; |
268 Node elsePart = node.otherwise; | 272 Statement elsePart = node.otherwise; |
269 bool hasElse = node.hasElse; | 273 bool hasElse = node.hasElse; |
270 | 274 |
271 // Handle dangling elses and a work-around for Android 4.0 stock browser. | 275 // Handle dangling elses and a work-around for Android 4.0 stock browser. |
272 // Android 4.0 requires braces for a single do-while in the `then` branch. | 276 // Android 4.0 requires braces for a single do-while in the `then` branch. |
273 // See issue 10923. | 277 // See issue 10923. |
274 if (hasElse) { | 278 bool needsBracesInThen = hasElse |
floitsch
2015/02/23 13:46:08
bool needsBracesInThen =
hasElse && (then.acce
sigurdm
2015/02/23 14:13:22
Acknowledged.
This change has been undone.
| |
275 bool needsBraces = node.then.accept(danglingElseVisitor) || then is Do; | 279 ? node.then.accept(danglingElseVisitor) || then is Do |
276 if (needsBraces) { | 280 : false; |
277 then = new Block(<Statement>[then]); | 281 |
278 } | |
279 } | |
280 if (shouldIndent) indent(); | 282 if (shouldIndent) indent(); |
281 out("if"); | 283 out("if"); |
282 spaceOut(); | 284 spaceOut(); |
283 out("("); | 285 out("("); |
284 visitNestedExpression(node.condition, EXPRESSION, | 286 visitNestedExpression(node.condition, EXPRESSION, |
285 newInForInit: false, newAtStatementBegin: false); | 287 newInForInit: false, newAtStatementBegin: false); |
286 out(")"); | 288 out(")"); |
287 bool thenWasBlock = | 289 bool thenWasBlock; |
288 blockBody(then, needsSeparation: false, needsNewline: !hasElse); | 290 if (needsBracesInThen) { |
291 spaceOut(); | |
292 blockOut(new Block([then]), shouldIndent: false, needsNewline: !hasElse); | |
293 thenWasBlock = true; | |
294 } else { | |
floitsch
2015/02/23 13:46:08
This probably broke the dangling-else:
if (x) {
sigurdm
2015/02/23 14:13:22
Yes, I just realized that. I will remove the block
| |
295 thenWasBlock = | |
296 blockBody(then, needsSeparation: false, needsNewline: !hasElse); | |
297 } | |
289 if (hasElse) { | 298 if (hasElse) { |
290 if (thenWasBlock) { | 299 if (thenWasBlock) { |
291 spaceOut(); | 300 spaceOut(); |
292 } else { | 301 } else { |
293 indent(); | 302 indent(); |
294 } | 303 } |
295 out("else"); | 304 out("else"); |
296 if (elsePart is If) { | 305 if (elsePart is If) { |
297 pendingSpace = true; | 306 pendingSpace = true; |
298 ifOut(elsePart, false); | 307 ifOut(elsePart, false); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 visitThrow(Throw node) { | 425 visitThrow(Throw node) { |
417 outIndent("throw"); | 426 outIndent("throw"); |
418 pendingSpace = true; | 427 pendingSpace = true; |
419 visitNestedExpression(node.expression, EXPRESSION, | 428 visitNestedExpression(node.expression, EXPRESSION, |
420 newInForInit: false, newAtStatementBegin: false); | 429 newInForInit: false, newAtStatementBegin: false); |
421 outSemicolonLn(); | 430 outSemicolonLn(); |
422 } | 431 } |
423 | 432 |
424 visitTry(Try node) { | 433 visitTry(Try node) { |
425 outIndent("try"); | 434 outIndent("try"); |
426 blockBody(node.body, needsSeparation: true, needsNewline: false); | 435 spaceOut(); |
436 blockOut(node.body, shouldIndent: false, needsNewline: false); | |
427 if (node.catchPart != null) { | 437 if (node.catchPart != null) { |
428 visit(node.catchPart); | 438 visit(node.catchPart); |
429 } | 439 } |
430 if (node.finallyPart != null) { | 440 if (node.finallyPart != null) { |
431 spaceOut(); | 441 spaceOut(); |
432 out("finally"); | 442 out("finally"); |
433 blockBody(node.finallyPart, needsSeparation: true, needsNewline: true); | 443 spaceOut(); |
444 blockOut(node.finallyPart, shouldIndent: false, needsNewline: true); | |
434 } else { | 445 } else { |
435 lineOut(); | 446 lineOut(); |
436 } | 447 } |
437 } | 448 } |
438 | 449 |
439 visitCatch(Catch node) { | 450 visitCatch(Catch node) { |
440 spaceOut(); | 451 spaceOut(); |
441 out("catch"); | 452 out("catch"); |
442 spaceOut(); | 453 spaceOut(); |
443 out("("); | 454 out("("); |
444 visitNestedExpression(node.declaration, EXPRESSION, | 455 visitNestedExpression(node.declaration, EXPRESSION, |
445 newInForInit: false, newAtStatementBegin: false); | 456 newInForInit: false, newAtStatementBegin: false); |
446 out(")"); | 457 out(")"); |
447 blockBody(node.body, needsSeparation: false, needsNewline: true); | 458 spaceOut(); |
459 blockOut(node.body, shouldIndent: false, needsNewline: false); | |
448 } | 460 } |
449 | 461 |
450 visitSwitch(Switch node) { | 462 visitSwitch(Switch node) { |
451 outIndent("switch"); | 463 outIndent("switch"); |
452 spaceOut(); | 464 spaceOut(); |
453 out("("); | 465 out("("); |
454 visitNestedExpression(node.key, EXPRESSION, | 466 visitNestedExpression(node.key, EXPRESSION, |
455 newInForInit: false, newAtStatementBegin: false); | 467 newInForInit: false, newAtStatementBegin: false); |
456 out(")"); | 468 out(")"); |
457 spaceOut(); | 469 spaceOut(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
510 case const AsyncModifier.async(): | 522 case const AsyncModifier.async(): |
511 out(' async'); | 523 out(' async'); |
512 break; | 524 break; |
513 case const AsyncModifier.syncStar(): | 525 case const AsyncModifier.syncStar(): |
514 out(' sync*'); | 526 out(' sync*'); |
515 break; | 527 break; |
516 case const AsyncModifier.asyncStar(): | 528 case const AsyncModifier.asyncStar(): |
517 out(' async*'); | 529 out(' async*'); |
518 break; | 530 break; |
519 } | 531 } |
520 blockBody(fun.body, needsSeparation: false, needsNewline: false); | 532 spaceOut(); |
533 blockOut(fun.body, shouldIndent: false, needsNewline: false); | |
521 localNamer.leaveScope(); | 534 localNamer.leaveScope(); |
522 } | 535 } |
523 | 536 |
524 visitFunctionDeclaration(FunctionDeclaration declaration) { | 537 visitFunctionDeclaration(FunctionDeclaration declaration) { |
525 VarCollector vars = new VarCollector(); | 538 VarCollector vars = new VarCollector(); |
526 vars.visitFunctionDeclaration(declaration); | 539 vars.visitFunctionDeclaration(declaration); |
527 indent(); | 540 indent(); |
528 functionOut(declaration.function, declaration.name, vars); | 541 functionOut(declaration.function, declaration.name, vars); |
529 lineOut(); | 542 lineOut(); |
530 } | 543 } |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1242 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS)); | 1255 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS)); |
1243 } | 1256 } |
1244 codes.add(charCodes.$0 + digit); | 1257 codes.add(charCodes.$0 + digit); |
1245 newName = new String.fromCharCodes(codes); | 1258 newName = new String.fromCharCodes(codes); |
1246 } | 1259 } |
1247 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName)); | 1260 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName)); |
1248 maps.last[oldName] = newName; | 1261 maps.last[oldName] = newName; |
1249 return newName; | 1262 return newName; |
1250 } | 1263 } |
1251 } | 1264 } |
OLD | NEW |