Chromium Code Reviews| Index: lib/compiler/implementation/js/printer.dart |
| diff --git a/lib/compiler/implementation/js/printer.dart b/lib/compiler/implementation/js/printer.dart |
| index 95f4a3d88d9cbf7287290e7b65af8132b3ce39c4..4622670c4048d7430603bfba8208b460d6f9fca1 100644 |
| --- a/lib/compiler/implementation/js/printer.dart |
| +++ b/lib/compiler/implementation/js/printer.dart |
| @@ -10,12 +10,15 @@ class Printer implements NodeVisitor { |
| bool inForInit = false; |
| bool atStatementBegin = false; |
| final DanglingElseVisitor danglingElseVisitor; |
| + Renamer _renamer; |
|
floitsch
2012/10/09 13:45:43
no need to make it private.
erikcorry
2012/10/09 20:15:51
Done.
|
| Printer(leg.Compiler compiler) |
| : shouldCompressOutput = compiler.enableMinification, |
| this.compiler = compiler, |
| outBuffer = new leg.CodeBuffer(), |
| - danglingElseVisitor = new DanglingElseVisitor(compiler); |
| + danglingElseVisitor = new DanglingElseVisitor(compiler) { |
| + _renamer = shouldCompressOutput ? new MinifyRenamer() : new DummyRenamer(); |
| + } |
| void spaceOut() { |
| if (!shouldCompressOutput) out(" "); |
| @@ -352,6 +355,7 @@ class Printer implements NodeVisitor { |
| visitNestedExpression(name, PRIMARY, |
| newInForInit: false, newAtStatementBegin: false); |
| } |
| + _renamer.enterScope(); |
| out("("); |
| if (fun.params != null) { |
| visitCommaSeparated(fun.params, PRIMARY, |
| @@ -359,6 +363,7 @@ class Printer implements NodeVisitor { |
| } |
| out(")"); |
| blockBody(fun.body, needsSeparation: false, needsNewline: false); |
| + _renamer.leaveScope(); |
| } |
| visitFunctionDeclaration(FunctionDeclaration declaration) { |
| @@ -596,7 +601,8 @@ class Printer implements NodeVisitor { |
| } |
| visitVariableUse(VariableUse ref) { |
| - out(ref.name); |
| + var newName = _renamer.getName(ref.name); |
|
floitsch
2012/10/09 13:45:43
FYI: I think it can currently happen that the name
erikcorry
2012/10/09 20:15:51
ok
|
| + out(newName); |
|
floitsch
2012/10/09 13:45:43
out(renamer.getName(ref.name)) ?
erikcorry
2012/10/09 20:15:51
Done.
|
| } |
| visitThis(This node) { |
| @@ -604,11 +610,13 @@ class Printer implements NodeVisitor { |
| } |
| visitVariableDeclaration(VariableDeclaration decl) { |
| - out(decl.name); |
| + var newName = _renamer.declareName(decl.name); |
| + out(newName); |
| } |
| visitParameter(Parameter param) { |
| - out(param.name); |
| + var newName = _renamer.declareName(param.name); |
| + out(newName); |
| } |
| bool isDigit(int charCode) { |
| @@ -825,3 +833,51 @@ leg.CodeBuffer prettyPrint(Node node, |
| printer.visit(node); |
| return printer.outBuffer; |
| } |
| + |
| + |
| +abstract class Renamer { |
|
floitsch
2012/10/09 13:45:43
Missing enterScope, leaveScope.
floitsch
2012/10/09 13:45:43
I would call this class 'Namer'. Otherwise it impl
erikcorry
2012/10/09 20:15:51
Done.
erikcorry
2012/10/09 20:15:51
Done and the member variable was also renamed to m
|
| + String getName(String oldName); |
| + String declareName(String oldName); |
| +} |
| + |
| + |
| +class DummyRenamer implements Renamer { |
|
floitsch
2012/10/09 13:45:43
Don't like "Dummy". Maybe "PassThroughNamer", "Ori
ngeoffray
2012/10/09 13:53:42
IdentityNamer?
floitsch
2012/10/09 13:55:35
yeah. That's actually the one I was looking for. t
erikcorry
2012/10/09 20:15:51
Done.
|
| + String getName(String oldName) => oldName; |
| + String declareName(String oldName) => oldName; |
| + void enterScope() {} |
| + void leaveScope() {} |
| +} |
| + |
| + |
| +class MinifyRenamer implements Renamer { |
| + MinifyRenamer() : _maps = [], _name_number_stack = [], _name_number = 0; |
|
ngeoffray
2012/10/09 13:53:42
_name_number -> _nameNumber
_name_number_stack ->
ngeoffray
2012/10/09 13:53:42
You could type these lists:
_maps = <Map<String, S
erikcorry
2012/10/09 20:15:51
Done.
erikcorry
2012/10/09 20:15:51
I'd rather not.
|
| + |
| + void enterScope() { |
| + _maps.add(new Map<String, String>()); |
| + _name_number_stack.add(_name_number); |
|
floitsch
2012/10/09 13:45:43
_nameNumberStack
erikcorry
2012/10/09 20:15:51
Done.
|
| + } |
| + |
| + void leaveScope() { |
| + _maps.removeLast(); |
| + _name_number = _name_number_stack.removeLast(); |
| + } |
| + |
| + String getName(String oldName) { |
| + for (int i = _maps.length - 1; i >= 0; i--) { |
| + var map = _maps[i]; |
|
floitsch
2012/10/09 13:45:43
Personally I would prefer having a type here, but
erikcorry
2012/10/09 20:15:51
I'd rather not.
|
| + if (map.containsKey(oldName)) return map[oldName]; |
|
floitsch
2012/10/09 13:45:43
String replacement = map[oldName];
if (replacement
erikcorry
2012/10/09 20:15:51
Done.
|
| + } |
| + return oldName; |
| + } |
| + |
| + Strint declareName(String oldName) { |
| + if (_maps.length == 0) return oldName; |
| + var newName = "z${_name_number++}"; |
| + _maps.last()[oldName] = newName; |
| + return newName; |
| + } |
| + |
| + List<Map<String, String>> _maps; |
|
floitsch
2012/10/09 13:45:43
We usually have locals on the top of the class.
floitsch
2012/10/09 13:45:43
No need to make the fields private.
floitsch
2012/10/09 13:45:43
make the maps field final.
erikcorry
2012/10/09 20:15:51
Done.
erikcorry
2012/10/09 20:15:51
Done.
erikcorry
2012/10/09 20:15:51
Done.
|
| + List<int> _name_number_stack; |
|
floitsch
2012/10/09 13:45:43
make nameNumberStack final.
erikcorry
2012/10/09 20:15:51
Done.
|
| + int _name_number; |
| +} |