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 Statement unwrapIfSingleStatement(Statement body) { |
floitsch
2015/02/23 14:26:05
unwrapBlockIfSingleStatement ?
sigurdm
2015/02/23 14:34:21
Done.
| |
208 Statement result = body; | |
209 while (result is Block) { | |
210 Block block = result; | |
211 if (block.statements.length != 1) break; | |
212 result = block.statements.single; | |
213 } | |
214 return result; | |
215 } | |
216 | |
217 bool blockBody(Statement body, {bool needsSeparation, bool needsNewline}) { | |
208 if (body is Block) { | 218 if (body is Block) { |
209 spaceOut(); | 219 spaceOut(); |
210 blockOut(body, false, needsNewline); | 220 blockOut(body, shouldIndent: false, needsNewline: needsNewline); |
211 return true; | 221 return true; |
212 } | 222 } |
213 if (shouldCompressOutput && needsSeparation) { | 223 if (shouldCompressOutput && needsSeparation) { |
214 // If [shouldCompressOutput] is false, then the 'lineOut' will insert | 224 // If [shouldCompressOutput] is false, then the 'lineOut' will insert |
215 // the separation. | 225 // the separation. |
216 out(" "); | 226 out(" "); |
217 } else { | 227 } else { |
218 lineOut(); | 228 lineOut(); |
219 } | 229 } |
220 indentMore(); | 230 indentMore(); |
221 visit(body); | 231 visit(body); |
222 indentLess(); | 232 indentLess(); |
223 return false; | 233 return false; |
224 } | 234 } |
225 | 235 |
226 void blockOutWithoutBraces(Node node) { | 236 void blockOutWithoutBraces(Node node) { |
227 if (node is Block) { | 237 if (node is Block) { |
228 context.enterNode(node); | 238 context.enterNode(node); |
229 Block block = node; | 239 Block block = node; |
230 block.statements.forEach(blockOutWithoutBraces); | 240 block.statements.forEach(blockOutWithoutBraces); |
231 context.exitNode(node); | 241 context.exitNode(node); |
232 } else { | 242 } else { |
233 visit(node); | 243 visit(node); |
234 } | 244 } |
235 } | 245 } |
236 | 246 |
237 void blockOut(Block node, bool shouldIndent, bool needsNewline) { | 247 void blockOut(Block node, {bool shouldIndent, bool needsNewline}) { |
238 if (shouldIndent) indent(); | 248 if (shouldIndent) indent(); |
239 context.enterNode(node); | 249 context.enterNode(node); |
240 out("{"); | 250 out("{"); |
241 lineOut(); | 251 lineOut(); |
242 indentMore(); | 252 indentMore(); |
243 node.statements.forEach(blockOutWithoutBraces); | 253 node.statements.forEach(blockOutWithoutBraces); |
244 indentLess(); | 254 indentLess(); |
245 indent(); | 255 indent(); |
246 out("}"); | 256 out("}"); |
247 context.exitNode(node); | 257 context.exitNode(node); |
248 if (needsNewline) lineOut(); | 258 if (needsNewline) lineOut(); |
249 } | 259 } |
250 | 260 |
251 visitBlock(Block block) { | 261 visitBlock(Block block) { |
252 blockOut(block, true, true); | 262 blockOut(block, shouldIndent: true, needsNewline: true); |
253 } | 263 } |
254 | 264 |
255 visitExpressionStatement(ExpressionStatement expressionStatement) { | 265 visitExpressionStatement(ExpressionStatement expressionStatement) { |
256 indent(); | 266 indent(); |
257 visitNestedExpression(expressionStatement.expression, EXPRESSION, | 267 visitNestedExpression(expressionStatement.expression, EXPRESSION, |
258 newInForInit: false, newAtStatementBegin: true); | 268 newInForInit: false, newAtStatementBegin: true); |
259 outSemicolonLn(); | 269 outSemicolonLn(); |
260 } | 270 } |
261 | 271 |
262 visitEmptyStatement(EmptyStatement nop) { | 272 visitEmptyStatement(EmptyStatement nop) { |
263 outIndentLn(";"); | 273 outIndentLn(";"); |
264 } | 274 } |
265 | 275 |
266 void ifOut(If node, bool shouldIndent) { | 276 void ifOut(If node, bool shouldIndent) { |
267 Node then = node.then; | 277 Statement then = unwrapIfSingleStatement(node.then); |
268 Node elsePart = node.otherwise; | 278 Statement elsePart = node.otherwise; |
269 bool hasElse = node.hasElse; | 279 bool hasElse = node.hasElse; |
270 | 280 |
271 // Handle dangling elses and a work-around for Android 4.0 stock browser. | 281 // 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. | 282 // Android 4.0 requires braces for a single do-while in the `then` branch. |
273 // See issue 10923. | 283 // See issue 10923. |
274 if (hasElse) { | 284 if (hasElse) { |
275 bool needsBraces = node.then.accept(danglingElseVisitor) || then is Do; | 285 bool needsBraces = then.accept(danglingElseVisitor) || then is Do; |
276 if (needsBraces) { | 286 if (needsBraces) { |
277 then = new Block(<Statement>[then]); | 287 then = new Block(<Statement>[then]); |
278 } | 288 } |
279 } | 289 } |
280 if (shouldIndent) indent(); | 290 if (shouldIndent) indent(); |
281 out("if"); | 291 out("if"); |
282 spaceOut(); | 292 spaceOut(); |
283 out("("); | 293 out("("); |
284 visitNestedExpression(node.condition, EXPRESSION, | 294 visitNestedExpression(node.condition, EXPRESSION, |
285 newInForInit: false, newAtStatementBegin: false); | 295 newInForInit: false, newAtStatementBegin: false); |
286 out(")"); | 296 out(")"); |
287 bool thenWasBlock = | 297 bool thenWasBlock = |
288 blockBody(then, needsSeparation: false, needsNewline: !hasElse); | 298 blockBody(then, needsSeparation: false, needsNewline: !hasElse); |
289 if (hasElse) { | 299 if (hasElse) { |
290 if (thenWasBlock) { | 300 if (thenWasBlock) { |
291 spaceOut(); | 301 spaceOut(); |
292 } else { | 302 } else { |
293 indent(); | 303 indent(); |
294 } | 304 } |
295 out("else"); | 305 out("else"); |
296 if (elsePart is If) { | 306 if (elsePart is If) { |
297 pendingSpace = true; | 307 pendingSpace = true; |
298 ifOut(elsePart, false); | 308 ifOut(elsePart, false); |
299 } else { | 309 } else { |
300 blockBody(elsePart, needsSeparation: true, needsNewline: true); | 310 blockBody(unwrapIfSingleStatement(elsePart), |
311 needsSeparation: true, needsNewline: true); | |
301 } | 312 } |
302 } | 313 } |
303 } | 314 } |
304 | 315 |
305 visitIf(If node) { | 316 visitIf(If node) { |
306 ifOut(node, true); | 317 ifOut(node, true); |
307 } | 318 } |
308 | 319 |
309 visitFor(For loop) { | 320 visitFor(For loop) { |
310 outIndent("for"); | 321 outIndent("for"); |
311 spaceOut(); | 322 spaceOut(); |
312 out("("); | 323 out("("); |
313 if (loop.init != null) { | 324 if (loop.init != null) { |
314 visitNestedExpression(loop.init, EXPRESSION, | 325 visitNestedExpression(loop.init, EXPRESSION, |
315 newInForInit: true, newAtStatementBegin: false); | 326 newInForInit: true, newAtStatementBegin: false); |
316 } | 327 } |
317 out(";"); | 328 out(";"); |
318 if (loop.condition != null) { | 329 if (loop.condition != null) { |
319 spaceOut(); | 330 spaceOut(); |
320 visitNestedExpression(loop.condition, EXPRESSION, | 331 visitNestedExpression(loop.condition, EXPRESSION, |
321 newInForInit: false, newAtStatementBegin: false); | 332 newInForInit: false, newAtStatementBegin: false); |
322 } | 333 } |
323 out(";"); | 334 out(";"); |
324 if (loop.update != null) { | 335 if (loop.update != null) { |
325 spaceOut(); | 336 spaceOut(); |
326 visitNestedExpression(loop.update, EXPRESSION, | 337 visitNestedExpression(loop.update, EXPRESSION, |
327 newInForInit: false, newAtStatementBegin: false); | 338 newInForInit: false, newAtStatementBegin: false); |
328 } | 339 } |
329 out(")"); | 340 out(")"); |
330 blockBody(loop.body, needsSeparation: false, needsNewline: true); | 341 blockBody(unwrapIfSingleStatement(loop.body), |
342 needsSeparation: false, needsNewline: true); | |
331 } | 343 } |
332 | 344 |
333 visitForIn(ForIn loop) { | 345 visitForIn(ForIn loop) { |
334 outIndent("for"); | 346 outIndent("for"); |
335 spaceOut(); | 347 spaceOut(); |
336 out("("); | 348 out("("); |
337 visitNestedExpression(loop.leftHandSide, EXPRESSION, | 349 visitNestedExpression(loop.leftHandSide, EXPRESSION, |
338 newInForInit: true, newAtStatementBegin: false); | 350 newInForInit: true, newAtStatementBegin: false); |
339 out(" in"); | 351 out(" in"); |
340 pendingSpace = true; | 352 pendingSpace = true; |
341 visitNestedExpression(loop.object, EXPRESSION, | 353 visitNestedExpression(loop.object, EXPRESSION, |
342 newInForInit: false, newAtStatementBegin: false); | 354 newInForInit: false, newAtStatementBegin: false); |
343 out(")"); | 355 out(")"); |
344 blockBody(loop.body, needsSeparation: false, needsNewline: true); | 356 blockBody(unwrapIfSingleStatement(loop.body), |
357 needsSeparation: false, needsNewline: true); | |
345 } | 358 } |
346 | 359 |
347 visitWhile(While loop) { | 360 visitWhile(While loop) { |
348 outIndent("while"); | 361 outIndent("while"); |
349 spaceOut(); | 362 spaceOut(); |
350 out("("); | 363 out("("); |
351 visitNestedExpression(loop.condition, EXPRESSION, | 364 visitNestedExpression(loop.condition, EXPRESSION, |
352 newInForInit: false, newAtStatementBegin: false); | 365 newInForInit: false, newAtStatementBegin: false); |
353 out(")"); | 366 out(")"); |
354 blockBody(loop.body, needsSeparation: false, needsNewline: true); | 367 blockBody(unwrapIfSingleStatement(loop.body), |
368 needsSeparation: false, needsNewline: true); | |
355 } | 369 } |
356 | 370 |
357 visitDo(Do loop) { | 371 visitDo(Do loop) { |
358 outIndent("do"); | 372 outIndent("do"); |
359 if (blockBody(loop.body, needsSeparation: true, needsNewline: false)) { | 373 if (blockBody(unwrapIfSingleStatement(loop.body), |
374 needsSeparation: true, needsNewline: false)) { | |
360 spaceOut(); | 375 spaceOut(); |
361 } else { | 376 } else { |
362 indent(); | 377 indent(); |
363 } | 378 } |
364 out("while"); | 379 out("while"); |
365 spaceOut(); | 380 spaceOut(); |
366 out("("); | 381 out("("); |
367 visitNestedExpression(loop.condition, EXPRESSION, | 382 visitNestedExpression(loop.condition, EXPRESSION, |
368 newInForInit: false, newAtStatementBegin: false); | 383 newInForInit: false, newAtStatementBegin: false); |
369 out(")"); | 384 out(")"); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
437 } | 452 } |
438 | 453 |
439 visitCatch(Catch node) { | 454 visitCatch(Catch node) { |
440 spaceOut(); | 455 spaceOut(); |
441 out("catch"); | 456 out("catch"); |
442 spaceOut(); | 457 spaceOut(); |
443 out("("); | 458 out("("); |
444 visitNestedExpression(node.declaration, EXPRESSION, | 459 visitNestedExpression(node.declaration, EXPRESSION, |
445 newInForInit: false, newAtStatementBegin: false); | 460 newInForInit: false, newAtStatementBegin: false); |
446 out(")"); | 461 out(")"); |
447 blockBody(node.body, needsSeparation: false, needsNewline: true); | 462 blockBody(node.body, needsSeparation: false, needsNewline: false); |
448 } | 463 } |
449 | 464 |
450 visitSwitch(Switch node) { | 465 visitSwitch(Switch node) { |
451 outIndent("switch"); | 466 outIndent("switch"); |
452 spaceOut(); | 467 spaceOut(); |
453 out("("); | 468 out("("); |
454 visitNestedExpression(node.key, EXPRESSION, | 469 visitNestedExpression(node.key, EXPRESSION, |
455 newInForInit: false, newAtStatementBegin: false); | 470 newInForInit: false, newAtStatementBegin: false); |
456 out(")"); | 471 out(")"); |
457 spaceOut(); | 472 spaceOut(); |
(...skipping 21 matching lines...) Expand all Loading... | |
479 outIndentLn("default:"); | 494 outIndentLn("default:"); |
480 if (!node.body.statements.isEmpty) { | 495 if (!node.body.statements.isEmpty) { |
481 indentMore(); | 496 indentMore(); |
482 blockOutWithoutBraces(node.body); | 497 blockOutWithoutBraces(node.body); |
483 indentLess(); | 498 indentLess(); |
484 } | 499 } |
485 } | 500 } |
486 | 501 |
487 visitLabeledStatement(LabeledStatement node) { | 502 visitLabeledStatement(LabeledStatement node) { |
488 outIndent("${node.label}:"); | 503 outIndent("${node.label}:"); |
489 blockBody(node.body, needsSeparation: false, needsNewline: true); | 504 blockBody(unwrapIfSingleStatement(node.body), |
505 needsSeparation: false, needsNewline: true); | |
490 } | 506 } |
491 | 507 |
492 void functionOut(Fun fun, Node name, VarCollector vars) { | 508 void functionOut(Fun fun, Node name, VarCollector vars) { |
493 out("function"); | 509 out("function"); |
494 if (name != null) { | 510 if (name != null) { |
495 out(" "); | 511 out(" "); |
496 // Name must be a [Decl]. Therefore only test for primary expressions. | 512 // Name must be a [Decl]. Therefore only test for primary expressions. |
497 visitNestedExpression(name, PRIMARY, | 513 visitNestedExpression(name, PRIMARY, |
498 newInForInit: false, newAtStatementBegin: false); | 514 newInForInit: false, newAtStatementBegin: false); |
499 } | 515 } |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1242 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS)); | 1258 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS)); |
1243 } | 1259 } |
1244 codes.add(charCodes.$0 + digit); | 1260 codes.add(charCodes.$0 + digit); |
1245 newName = new String.fromCharCodes(codes); | 1261 newName = new String.fromCharCodes(codes); |
1246 } | 1262 } |
1247 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName)); | 1263 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName)); |
1248 maps.last[oldName] = newName; | 1264 maps.last[oldName] = newName; |
1249 return newName; | 1265 return newName; |
1250 } | 1266 } |
1251 } | 1267 } |
OLD | NEW |