| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 /** | 5 /** |
| 6 * Assigns JavaScript identifiers to Dart variables, class-names and members. | 6 * Assigns JavaScript identifiers to Dart variables, class-names and members. |
| 7 */ | 7 */ |
| 8 class Namer { | 8 class Namer { |
| 9 final Compiler compiler; | 9 final Compiler compiler; |
| 10 | 10 |
| 11 static final CLOSURE_INVOCATION_NAME = const SourceString('\$call'); | 11 static final CLOSURE_INVOCATION_NAME = const SourceString('\$call'); |
| 12 static final OPERATOR_EQUALS = const SourceString('operator\$eq'); | 12 static final OPERATOR_EQUALS = const SourceString('operator\$eq'); |
| 13 | 13 |
| 14 static Set<String> _jsReserved = null; | 14 static Set<String> _jsReserved = null; |
| 15 Set<String> get jsReserved() { | 15 Set<String> get jsReserved() { |
| 16 if (_jsReserved === null) { | 16 if (_jsReserved === null) { |
| 17 _jsReserved = new Set<String>(); | 17 _jsReserved = new Set<String>(); |
| 18 _jsReserved.addAll(JsNames.javaScriptKeywords); | 18 _jsReserved.addAll(JsNames.javaScriptKeywords); |
| 19 _jsReserved.addAll(JsNames.reservedPropertySymbols); | 19 _jsReserved.addAll(JsNames.reservedPropertySymbols); |
| 20 } | 20 } |
| 21 return _jsReserved; | 21 return _jsReserved; |
| 22 } | 22 } |
| 23 | 23 |
| 24 Map<Element, String> globals; | 24 Map<Element, String> globals; |
| 25 Map<String, int> usedGlobals; | 25 Map<String, int> usedGlobals; |
| 26 Map<String, LibraryElement> shortPrivateNameOwners; |
| 26 | 27 |
| 27 Namer(this.compiler) | 28 Namer(this.compiler) |
| 28 : globals = new Map<Element, String>(), | 29 : globals = new Map<Element, String>(), |
| 29 usedGlobals = new Map<String, int>(); | 30 usedGlobals = new Map<String, int>(), |
| 31 shortPrivateNameOwners = new Map<String, LibraryElement>(); |
| 30 | 32 |
| 31 final String CURRENT_ISOLATE = "\$"; | 33 final String CURRENT_ISOLATE = "\$"; |
| 32 final String ISOLATE = "Isolate"; | 34 final String ISOLATE = "Isolate"; |
| 33 final String ISOLATE_PROPERTIES = "\$isolateProperties"; | 35 final String ISOLATE_PROPERTIES = "\$isolateProperties"; |
| 34 | 36 |
| 35 | 37 |
| 36 String closureInvocationName(Selector selector) { | 38 String closureInvocationName(Selector selector) { |
| 37 // TODO(floitsch): mangle, while not conflicting with instance names. | 39 // TODO(floitsch): mangle, while not conflicting with instance names. |
| 38 return instanceMethodInvocationName(null, CLOSURE_INVOCATION_NAME, | 40 return instanceMethodInvocationName(null, CLOSURE_INVOCATION_NAME, |
| 39 selector); | 41 selector); |
| 40 } | 42 } |
| 41 | 43 |
| 42 String privateName(LibraryElement lib, SourceString name) { | 44 String privateName(LibraryElement lib, SourceString name) { |
| 43 if (name.isPrivate()) { | 45 if (name.isPrivate()) { |
| 44 return '_${getName(lib)}${name.slowToString()}'; | 46 String nameString = name.slowToString(); |
| 47 |
| 48 // The first library asking for a short private name wins. |
| 49 LibraryElement owner = |
| 50 shortPrivateNameOwners.putIfAbsent(nameString, () => lib); |
| 51 // If a private name could clash with a mangled private name we don't |
| 52 // use the short name. For example a private name "_lib3_foo" would |
| 53 // clash with "_foo" from "lib3". |
| 54 if (owner === lib && !nameString.startsWith('_$LIBRARY_PREFIX')) { |
| 55 return nameString; |
| 56 } |
| 57 String libName = getName(lib); |
| 58 // If a library name does not start with the [LIBRARY_PREFIX] then our |
| 59 // assumptions about clashing with mangled private members do not hold. |
| 60 assert(libName.startsWith(LIBRARY_PREFIX)); |
| 61 return '_$libName$nameString'; |
| 45 } else { | 62 } else { |
| 46 return '${name.slowToString()}'; | 63 return name.slowToString(); |
| 47 } | 64 } |
| 48 } | 65 } |
| 49 | 66 |
| 50 String instanceMethodName(LibraryElement lib, SourceString name, int arity) { | 67 String instanceMethodName(LibraryElement lib, SourceString name, int arity) { |
| 51 return '${privateName(lib, name)}\$$arity'; | 68 return '${privateName(lib, name)}\$$arity'; |
| 52 } | 69 } |
| 53 | 70 |
| 54 String instanceMethodInvocationName(LibraryElement lib, SourceString name, | 71 String instanceMethodInvocationName(LibraryElement lib, SourceString name, |
| 55 Selector selector) { | 72 Selector selector) { |
| 56 // TODO(floitsch): mangle, while preserving uniqueness. | 73 // TODO(floitsch): mangle, while preserving uniqueness. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 String name; | 108 String name; |
| 92 do { | 109 do { |
| 93 usedCount++; | 110 usedCount++; |
| 94 name = '$proposedName$usedCount'; | 111 name = '$proposedName$usedCount'; |
| 95 } while (usedGlobals[name] !== null); | 112 } while (usedGlobals[name] !== null); |
| 96 usedGlobals[proposedName] = usedCount; | 113 usedGlobals[proposedName] = usedCount; |
| 97 return name; | 114 return name; |
| 98 } | 115 } |
| 99 } | 116 } |
| 100 | 117 |
| 118 static final String LIBRARY_PREFIX = "lib"; |
| 119 |
| 101 /** | 120 /** |
| 102 * Returns a preferred JS-id for the given top-level or static element. | 121 * Returns a preferred JS-id for the given top-level or static element. |
| 103 * The returned id is guaranteed to be a valid JS-id. | 122 * The returned id is guaranteed to be a valid JS-id. |
| 104 */ | 123 */ |
| 105 String _computeGuess(Element element) { | 124 String _computeGuess(Element element) { |
| 106 assert(!element.isInstanceMember()); | 125 assert(!element.isInstanceMember()); |
| 107 LibraryElement lib = element.getLibrary(); | 126 LibraryElement lib = element.getLibrary(); |
| 108 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { | 127 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { |
| 109 FunctionElement functionElement = element; | 128 FunctionElement functionElement = element; |
| 110 return instanceMethodName(lib, element.name, | 129 return instanceMethodName(lib, element.name, |
| 111 functionElement.parameterCount(compiler)); | 130 functionElement.parameterCount(compiler)); |
| 112 } else { | 131 } else { |
| 113 // TODO(floitsch): deal with named constructors. | 132 // TODO(floitsch): deal with named constructors. |
| 114 String name; | 133 String name; |
| 115 if (Elements.isStaticOrTopLevel(element)) { | 134 if (Elements.isStaticOrTopLevel(element)) { |
| 116 name = element.name.slowToString(); | 135 name = element.name.slowToString(); |
| 117 } else if (element.kind == ElementKind.GETTER) { | 136 } else if (element.kind == ElementKind.GETTER) { |
| 118 name = getterName(lib, element.name); | 137 name = getterName(lib, element.name); |
| 119 } else if (element.kind == ElementKind.SETTER) { | 138 } else if (element.kind == ElementKind.SETTER) { |
| 120 name = setterName(lib, element.name); | 139 name = setterName(lib, element.name); |
| 121 } else if (element.kind == ElementKind.FUNCTION) { | 140 } else if (element.kind == ElementKind.FUNCTION) { |
| 122 FunctionElement functionElement = element; | 141 FunctionElement functionElement = element; |
| 123 name = element.name.slowToString(); | 142 name = element.name.slowToString(); |
| 124 name = '$name\$${functionElement.parameterCount(compiler)}'; | 143 name = '$name\$${functionElement.parameterCount(compiler)}'; |
| 125 } else if (element.kind === ElementKind.LIBRARY) { | 144 } else if (element.kind === ElementKind.LIBRARY) { |
| 126 name = 'lib'; | 145 name = LIBRARY_PREFIX; |
| 127 } else { | 146 } else { |
| 128 name = element.name.slowToString(); | 147 name = element.name.slowToString(); |
| 129 } | 148 } |
| 130 // Prefix the name with '$' if it is reserved. | 149 // Prefix the name with '$' if it is reserved. |
| 131 return safeName(name); | 150 return safeName(name); |
| 132 } | 151 } |
| 133 } | 152 } |
| 134 | 153 |
| 135 String getBailoutName(Element element) { | 154 String getBailoutName(Element element) { |
| 136 return '${getName(element)}\$bailout'; | 155 return '${getName(element)}\$bailout'; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 } | 234 } |
| 216 | 235 |
| 217 String safeName(String name) { | 236 String safeName(String name) { |
| 218 if (jsReserved.contains(name) || name.startsWith('\$')) { | 237 if (jsReserved.contains(name) || name.startsWith('\$')) { |
| 219 name = "\$$name"; | 238 name = "\$$name"; |
| 220 assert(!jsReserved.contains(name)); | 239 assert(!jsReserved.contains(name)); |
| 221 } | 240 } |
| 222 return name; | 241 return name; |
| 223 } | 242 } |
| 224 } | 243 } |
| OLD | NEW |