| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dev_compiler.src.codegen.js_names; | 5 library dev_compiler.src.codegen.js_names; |
| 6 | 6 |
| 7 import 'package:dev_compiler/src/js/js_ast.dart'; | 7 import 'package:dev_compiler/src/js/js_ast.dart'; |
| 8 import 'package:dev_compiler/src/js/keywords.dart'; | |
| 9 | 8 |
| 10 /// Marker subclass for temporary variables. | 9 /// Marker subclass for temporary variables. |
| 11 /// We treat these as being in a different scope from other identifiers, and | 10 /// We treat these as being in a different scope from other identifiers, and |
| 12 /// rename them so they don't collide. See [JSNamer]. | 11 /// rename them so they don't collide. See [JSNamer]. |
| 13 // TODO(jmesserly): move into js_ast? add a boolean to Identifier? | 12 // TODO(jmesserly): move into js_ast? add a boolean to Identifier? |
| 14 class JSTemporary extends Identifier { | 13 class JSTemporary extends Identifier { |
| 15 JSTemporary(String name) : super(name); | 14 JSTemporary(String name) : super(name); |
| 16 } | 15 } |
| 17 | 16 |
| 18 /// This class has two purposes: | 17 /// This class has two purposes: |
| (...skipping 15 matching lines...) Expand all Loading... |
| 34 final renames = new Map<String, String>(); | 33 final renames = new Map<String, String>(); |
| 35 | 34 |
| 36 JSNamer(Node node) { | 35 JSNamer(Node node) { |
| 37 node.accept(new _NameCollector(usedNames)); | 36 node.accept(new _NameCollector(usedNames)); |
| 38 } | 37 } |
| 39 | 38 |
| 40 String getName(Identifier node) { | 39 String getName(Identifier node) { |
| 41 var name = node.name; | 40 var name = node.name; |
| 42 if (node is JSTemporary) { | 41 if (node is JSTemporary) { |
| 43 return _rename(name, valid: true); | 42 return _rename(name, valid: true); |
| 44 } else if (isJsKeyword(name)) { | 43 } else if (invalidJSVariableName(name)) { |
| 45 return _rename(name, valid: false); | 44 return _rename(name, valid: false); |
| 46 } | 45 } |
| 47 return name; | 46 return name; |
| 48 } | 47 } |
| 49 | 48 |
| 50 String _rename(String name, {bool valid}) { | 49 String _rename(String name, {bool valid}) { |
| 51 var candidate = renames[name]; | 50 var candidate = renames[name]; |
| 52 if (candidate != null) return candidate; | 51 if (candidate != null) return candidate; |
| 53 | 52 |
| 54 // Try to use the temp's name, otherwise rename. | 53 // Try to use the temp's name, otherwise rename. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 72 } | 71 } |
| 73 | 72 |
| 74 /// Collects all names used in the visited tree. | 73 /// Collects all names used in the visited tree. |
| 75 class _NameCollector extends BaseVisitor { | 74 class _NameCollector extends BaseVisitor { |
| 76 final Set<String> names; | 75 final Set<String> names; |
| 77 _NameCollector(this.names); | 76 _NameCollector(this.names); |
| 78 visitIdentifier(Identifier node) { | 77 visitIdentifier(Identifier node) { |
| 79 if (node is! JSTemporary) names.add(node.name); | 78 if (node is! JSTemporary) names.add(node.name); |
| 80 } | 79 } |
| 81 } | 80 } |
| 81 |
| 82 /// Returns true for invalid JS variable names, such as keywords. |
| 83 /// Also handles invalid variable names in strict mode, like "arguments". |
| 84 bool invalidJSVariableName(String keyword, {bool strictMode: true}) { |
| 85 switch (keyword) { |
| 86 case "break": |
| 87 case "case": |
| 88 case "catch": |
| 89 case "class": |
| 90 case "const": |
| 91 case "continue": |
| 92 case "debugger": |
| 93 case "default": |
| 94 case "delete": |
| 95 case "do": |
| 96 case "else": |
| 97 case "export": |
| 98 case "extends": |
| 99 case "finally": |
| 100 case "for": |
| 101 case "function": |
| 102 case "if": |
| 103 case "import": |
| 104 case "in": |
| 105 case "instanceof": |
| 106 case "let": |
| 107 case "new": |
| 108 case "return": |
| 109 case "static": |
| 110 case "super": |
| 111 case "switch": |
| 112 case "this": |
| 113 case "throw": |
| 114 case "try": |
| 115 case "typeof": |
| 116 case "var": |
| 117 case "void": |
| 118 case "while": |
| 119 case "with": |
| 120 case "yield": |
| 121 return true; |
| 122 case "arguments": |
| 123 case "eval": |
| 124 return strictMode; |
| 125 } |
| 126 return false; |
| 127 } |
| 128 |
| 129 /// Returns true for invalid static method names in strict mode. |
| 130 /// In particular, "caller" "callee" and "arguments" cannot be used. |
| 131 bool invalidJSStaticMethodName(String name) { |
| 132 switch (name) { |
| 133 case "arguments": |
| 134 case "caller": |
| 135 case "callee": |
| 136 return true; |
| 137 } |
| 138 return false; |
| 139 } |
| OLD | NEW |