Chromium Code Reviews| 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 part of js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Assigns JavaScript identifiers to Dart variables, class-names and members. | 8 * Assigns JavaScript identifiers to Dart variables, class-names and members. |
| 9 */ | 9 */ |
| 10 class Namer { | 10 class Namer { |
| 11 final Compiler compiler; | |
| 12 | |
| 13 static Set<String> _jsReserved = null; | 11 static Set<String> _jsReserved = null; |
| 14 Set<String> get jsReserved { | 12 Set<String> get jsReserved { |
| 15 if (_jsReserved == null) { | 13 if (_jsReserved == null) { |
| 16 _jsReserved = new Set<String>(); | 14 _jsReserved = new Set<String>(); |
| 17 _jsReserved.addAll(JsNames.javaScriptKeywords); | 15 _jsReserved.addAll(JsNames.javaScriptKeywords); |
| 18 _jsReserved.addAll(JsNames.reservedPropertySymbols); | 16 _jsReserved.addAll(JsNames.reservedPropertySymbols); |
| 19 } | 17 } |
| 20 return _jsReserved; | 18 return _jsReserved; |
| 21 } | 19 } |
| 22 | 20 |
| 21 final String CURRENT_ISOLATE = r'$'; | |
| 22 | |
| 23 /** | 23 /** |
| 24 * Map from top-level or static elements to their unique identifiers provided | 24 * Map from top-level or static elements to their unique identifiers provided |
| 25 * by [getName]. | 25 * by [getName]. |
| 26 * | 26 * |
| 27 * Invariant: Keys must be declaration elements. | 27 * Invariant: Keys must be declaration elements. |
| 28 */ | 28 */ |
| 29 final Compiler compiler; | |
| 29 final Map<Element, String> globals; | 30 final Map<Element, String> globals; |
| 30 final Map<String, int> usedGlobals; | |
| 31 final Map<String, LibraryElement> shortPrivateNameOwners; | 31 final Map<String, LibraryElement> shortPrivateNameOwners; |
| 32 final Set<String> usedGlobalNames; | |
| 33 final Set<String> usedInstanceNames; | |
| 34 final Map<String, String> instanceNameMap; | |
| 35 final Map<String, String> globalNameMap; | |
| 36 final Map<String, int> popularNameCounters; | |
| 32 | 37 |
| 33 final Map<Constant, String> constantNames; | 38 final Map<Constant, String> constantNames; |
| 34 | 39 |
| 35 Namer(this.compiler) | 40 Namer(this.compiler) |
| 36 : globals = new Map<Element, String>(), | 41 : globals = new Map<Element, String>(), |
| 37 usedGlobals = new Map<String, int>(), | |
| 38 shortPrivateNameOwners = new Map<String, LibraryElement>(), | 42 shortPrivateNameOwners = new Map<String, LibraryElement>(), |
| 39 constantNames = new Map<Constant, String>(); | 43 usedGlobalNames = new Set<String>(), |
| 44 usedInstanceNames = new Set<String>(), | |
| 45 instanceNameMap = new Map<String, String>(), | |
| 46 globalNameMap = new Map<String, String>(), | |
| 47 constantNames = new Map<Constant, String>(), | |
| 48 popularNameCounters = new Map<String, int>(); | |
| 40 | 49 |
| 41 final String CURRENT_ISOLATE = r'$'; | 50 String get ISOLATE => 'Isolate'; |
| 42 final String ISOLATE = 'Isolate'; | 51 String get ISOLATE_PROPERTIES => r'$isolateProperties'; |
| 43 final String ISOLATE_PROPERTIES = r"$isolateProperties"; | |
| 44 /** Some closures must contain their name. The name is stored in | 52 /** Some closures must contain their name. The name is stored in |
| 45 * [STATIC_CLOSURE_NAME_NAME]. */ | 53 * [STATIC_CLOSURE_NAME_NAME]. */ |
| 46 final String STATIC_CLOSURE_NAME_NAME = r'$name'; | 54 String get STATIC_CLOSURE_NAME_NAME => r'$name'; |
| 47 static const SourceString CLOSURE_INVOCATION_NAME = | 55 SourceString get CLOSURE_INVOCATION_NAME => Compiler.CALL_OPERATOR_NAME; |
| 48 Compiler.CALL_OPERATOR_NAME; | 56 bool get shouldMinify => false; |
| 57 | |
| 58 bool isReserved(String name) => name == ISOLATE; | |
| 49 | 59 |
| 50 String constantName(Constant constant) { | 60 String constantName(Constant constant) { |
| 51 // In the current implementation it doesn't make sense to give names to | 61 // In the current implementation it doesn't make sense to give names to |
| 52 // function constants since the function-implementation itself serves as | 62 // function constants since the function-implementation itself serves as |
| 53 // constant and can be accessed directly. | 63 // constant and can be accessed directly. |
| 54 assert(!constant.isFunction()); | 64 assert(!constant.isFunction()); |
| 55 String result = constantNames[constant]; | 65 String result = constantNames[constant]; |
| 56 if (result == null) { | 66 if (result == null) { |
| 57 result = getFreshGlobalName("CTC"); | 67 String longName; |
| 68 if (shouldMinify) { | |
| 69 if (constant.isString()) { | |
| 70 StringConstant stringConstant = constant; | |
| 71 longName = stringConstant.value.slowToString(); | |
|
floitsch
2012/11/13 13:35:02
add comment that the minifier doesn't require the
erikcorry
2012/11/16 10:08:30
Done.
| |
| 72 } else { | |
| 73 longName = "C"; | |
| 74 } | |
| 75 } else { | |
| 76 longName = "CTC"; | |
| 77 } | |
| 78 result = getFreshName(longName, usedGlobalNames); | |
| 58 constantNames[constant] = result; | 79 constantNames[constant] = result; |
| 59 } | 80 } |
| 60 return result; | 81 return result; |
| 61 } | 82 } |
| 62 | 83 |
| 63 String closureInvocationName(Selector selector) { | 84 String closureInvocationName(Selector selector) { |
| 64 // TODO(floitsch): mangle, while not conflicting with instance names. | 85 return |
| 65 return instanceMethodInvocationName(null, CLOSURE_INVOCATION_NAME, | 86 instanceMethodInvocationName(null, CLOSURE_INVOCATION_NAME, selector); |
|
floitsch
2012/11/13 13:35:02
one line?
erikcorry
2012/11/16 10:08:30
Doesn't fit.
| |
| 66 selector); | |
| 67 } | 87 } |
| 68 | 88 |
| 69 String breakLabelName(LabelElement label) { | 89 String breakLabelName(LabelElement label) { |
| 70 return '\$${label.labelName}\$${label.target.nestingLevel}'; | 90 return '\$${label.labelName}\$${label.target.nestingLevel}'; |
| 71 } | 91 } |
| 72 | 92 |
| 73 String implicitBreakLabelName(TargetElement target) { | 93 String implicitBreakLabelName(TargetElement target) { |
| 74 return '\$${target.nestingLevel}'; | 94 return '\$${target.nestingLevel}'; |
| 75 } | 95 } |
| 76 | 96 |
| 77 // We sometimes handle continue targets differently from break targets, | 97 // We sometimes handle continue targets differently from break targets, |
| 78 // so we have special continue-only labels. | 98 // so we have special continue-only labels. |
| 79 String continueLabelName(LabelElement label) { | 99 String continueLabelName(LabelElement label) { |
| 80 return 'c\$${label.labelName}\$${label.target.nestingLevel}'; | 100 return 'c\$${label.labelName}\$${label.target.nestingLevel}'; |
| 81 } | 101 } |
| 82 | 102 |
| 83 String implicitContinueLabelName(TargetElement target) { | 103 String implicitContinueLabelName(TargetElement target) { |
| 84 return 'c\$${target.nestingLevel}'; | 104 return 'c\$${target.nestingLevel}'; |
| 85 } | 105 } |
| 86 | 106 |
| 87 /** | 107 /** |
| 88 * If the [name] is not private returns [:name.slowToString():]. Otherwise | 108 * If the [name] is not private returns [:name.slowToString():]. Otherwise |
| 89 * mangles the [name] so that each library has a unique name. | 109 * mangles the [name] so that each library has a unique name. |
| 90 */ | 110 */ |
| 91 String privateName(LibraryElement lib, SourceString name) { | 111 String privateName(LibraryElement lib, SourceString name) { |
| 112 String result; | |
| 92 if (name.isPrivate()) { | 113 if (name.isPrivate()) { |
| 93 String nameString = name.slowToString(); | 114 String nameString = name.slowToString(); |
| 94 // The first library asking for a short private name wins. | 115 // The first library asking for a short private name wins. |
| 95 LibraryElement owner = | 116 LibraryElement owner = |
| 96 shortPrivateNameOwners.putIfAbsent(nameString, () => lib); | 117 shortPrivateNameOwners.putIfAbsent(nameString, () => lib); |
| 97 // If a private name could clash with a mangled private name we don't | 118 // If a private name could clash with a mangled private name we don't |
| 98 // use the short name. For example a private name "_lib3_foo" would | 119 // use the short name. For example a private name "_lib3_foo" would |
| 99 // clash with "_foo" from "lib3". | 120 // clash with "_foo" from "lib3". |
| 100 if (identical(owner, lib) && !nameString.startsWith('_$LIBRARY_PREFIX')) { | 121 if (owner == lib && |
| 101 return nameString; | 122 !nameString.startsWith('_$LIBRARY_PREFIX') && |
| 123 !shouldMinify) { | |
| 124 result = nameString; | |
| 125 } else { | |
| 126 String libName = getName(lib); | |
| 127 // If a library name does not start with the [LIBRARY_PREFIX] then our | |
| 128 // assumptions about clashing with mangled private members do not hold. | |
| 129 assert(shouldMinify || libName.startsWith(LIBRARY_PREFIX)); | |
| 130 // TODO(erikcorry): Fix this with other manglings to avoid clashes. | |
| 131 result = '_lib$libName\$$nameString'; | |
| 102 } | 132 } |
| 103 String libName = getName(lib); | |
| 104 // If a library name does not start with the [LIBRARY_PREFIX] then our | |
| 105 // assumptions about clashing with mangled private members do not hold. | |
| 106 assert(libName.startsWith(LIBRARY_PREFIX)); | |
| 107 return '_$libName$nameString'; | |
| 108 } else { | 133 } else { |
| 109 return name.slowToString(); | 134 result = name.slowToString(); |
| 110 } | 135 } |
| 136 return result; | |
| 111 } | 137 } |
| 112 | 138 |
| 113 String instanceMethodName(FunctionElement element) { | 139 String instanceMethodName(FunctionElement element) { |
| 114 SourceString name = element.name; | 140 SourceString name = element.name; |
| 115 LibraryElement lib = element.getLibrary(); | 141 LibraryElement lib = element.getLibrary(); |
| 116 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { | 142 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { |
| 117 ConstructorBodyElement bodyElement = element; | 143 ConstructorBodyElement bodyElement = element; |
| 118 name = bodyElement.constructor.name; | 144 name = bodyElement.constructor.name; |
| 119 } | 145 } |
| 120 FunctionSignature signature = element.computeSignature(compiler); | 146 FunctionSignature signature = element.computeSignature(compiler); |
| 121 String methodName = | 147 String methodName = |
|
floitsch
2012/11/13 13:35:02
one line?
erikcorry
2012/11/16 10:08:30
Doesn't fit.
| |
| 122 '${privateName(lib, name)}\$${signature.parameterCount}'; | 148 '${privateName(lib, name)}\$${signature.parameterCount}'; |
| 123 if (!signature.optionalParametersAreNamed) { | 149 if (signature.optionalParametersAreNamed && |
| 124 return methodName; | 150 !signature.optionalParameters.isEmpty) { |
| 125 } else if (!signature.optionalParameters.isEmpty) { | |
| 126 StringBuffer buffer = new StringBuffer(); | 151 StringBuffer buffer = new StringBuffer(); |
| 127 signature.orderedOptionalParameters.forEach((Element element) { | 152 signature.orderedOptionalParameters.forEach((Element element) { |
| 128 buffer.add('\$${JsNames.getValid(element.name.slowToString())}'); | 153 buffer.add('\$${JsNames.getValid(element.name.slowToString())}'); |
| 129 }); | 154 }); |
| 130 return '$methodName$buffer'; | 155 methodName = '$methodName$buffer'; |
| 131 } | 156 } |
| 157 return getMappedInstanceName(methodName); | |
| 132 } | 158 } |
| 133 | 159 |
| 134 String publicInstanceMethodNameByArity(SourceString name, int arity) { | 160 String publicInstanceMethodNameByArity(SourceString name, int arity) { |
| 135 assert(!name.isPrivate()); | 161 assert(!name.isPrivate()); |
| 136 return '${name.slowToString()}\$$arity'; | 162 var proposedName = '${name.slowToString()}\$$arity'; |
| 163 return getMappedInstanceName(proposedName); | |
| 137 } | 164 } |
| 138 | 165 |
| 139 String instanceMethodInvocationName(LibraryElement lib, SourceString name, | 166 String instanceMethodInvocationName(LibraryElement lib, SourceString name, |
| 140 Selector selector) { | 167 Selector selector) { |
| 141 // TODO(floitsch): mangle, while preserving uniqueness. | 168 // TODO(floitsch): mangle, while preserving uniqueness. |
| 142 StringBuffer buffer = new StringBuffer(); | 169 StringBuffer buffer = new StringBuffer(); |
| 143 List<SourceString> names = selector.getOrderedNamedArguments(); | 170 List<SourceString> names = selector.getOrderedNamedArguments(); |
| 144 for (SourceString argumentName in names) { | 171 for (SourceString argumentName in names) { |
| 145 buffer.add(r'$'); | 172 buffer.add(r'$'); |
| 146 argumentName.printOn(buffer); | 173 argumentName.printOn(buffer); |
| 147 } | 174 } |
| 148 return '${privateName(lib, name)}\$${selector.argumentCount}$buffer'; | 175 return getMappedInstanceName( |
| 176 '${privateName(lib, name)}\$${selector.argumentCount}$buffer'); | |
| 149 } | 177 } |
| 150 | 178 |
| 151 String instanceFieldName(LibraryElement libraryElement, SourceString name) { | 179 String instanceFieldName(LibraryElement libraryElement, SourceString name) { |
| 152 String proposedName = privateName(libraryElement, name); | 180 String proposedName = privateName(libraryElement, name); |
| 153 return safeName(proposedName); | 181 return getMappedInstanceName(proposedName); |
| 154 } | 182 } |
| 155 | 183 |
| 156 String shadowedFieldName(Element fieldElement) { | 184 String shadowedFieldName(Element fieldElement) { |
| 157 ClassElement cls = fieldElement.getEnclosingClass(); | 185 ClassElement cls = fieldElement.getEnclosingClass(); |
| 158 LibraryElement libraryElement = fieldElement.getLibrary(); | 186 LibraryElement libraryElement = fieldElement.getLibrary(); |
| 159 String libName = getName(libraryElement); | 187 String libName = getName(libraryElement); |
| 160 String clsName = getName(cls); | 188 String clsName = getName(cls); |
| 161 String instanceName = instanceFieldName(libraryElement, fieldElement.name); | 189 String instanceName = instanceFieldName(libraryElement, fieldElement.name); |
| 162 return safeName('$libName\$$clsName\$$instanceName'); | 190 return getMappedInstanceName('$libName\$$clsName\$$instanceName'); |
| 163 } | 191 } |
| 164 | 192 |
| 165 String setterName(LibraryElement lib, SourceString name) { | 193 String setterName(LibraryElement lib, SourceString name) { |
| 166 // We dynamically create setters from the field-name. The setter name must | 194 // We dynamically create setters from the field-name. The setter name must |
| 167 // therefore be derived from the instance field-name. | 195 // therefore be derived from the instance field-name. |
| 168 String fieldName = safeName(privateName(lib, name)); | 196 String fieldName = getMappedInstanceName(privateName(lib, name)); |
| 169 return 'set\$$fieldName'; | 197 return 'set\$$fieldName'; |
| 170 } | 198 } |
| 171 | 199 |
| 172 String publicGetterName(SourceString name) { | 200 String publicGetterName(SourceString name) { |
| 173 // We dynamically create getters from the field-name. The getter name must | 201 // We dynamically create getters from the field-name. The getter name must |
| 174 // therefore be derived from the instance field-name. | 202 // therefore be derived from the instance field-name. |
| 175 String fieldName = safeName(name.slowToString()); | 203 String fieldName = getMappedInstanceName(name.slowToString()); |
| 176 return 'get\$$fieldName'; | 204 return 'get\$$fieldName'; |
| 177 } | 205 } |
| 178 | 206 |
| 179 String getterName(LibraryElement lib, SourceString name) { | 207 String getterName(LibraryElement lib, SourceString name) { |
| 180 // We dynamically create getters from the field-name. The getter name must | 208 // We dynamically create getters from the field-name. The getter name must |
| 181 // therefore be derived from the instance field-name. | 209 // therefore be derived from the instance field-name. |
| 182 String fieldName = safeName(privateName(lib, name)); | 210 String fieldName = getMappedInstanceName(privateName(lib, name)); |
| 183 return 'get\$$fieldName'; | 211 return 'get\$$fieldName'; |
| 184 } | 212 } |
| 185 | 213 |
| 186 String getFreshGlobalName(String proposedName) { | 214 String publicSetterName(SourceString name) { |
| 187 String name = proposedName; | 215 // We dynamically create setter from the field-name. The setter name must |
| 188 int count = usedGlobals[name]; | 216 // therefore be derived from the instance field-name. |
| 189 if (count != null) { | 217 String fieldName = name.slowToString(); |
| 190 // Not the first time we see this name. Append a number to make it unique. | 218 return 'set\$$fieldName'; |
| 191 do { | 219 } |
| 192 name = '$proposedName${count++}'; | 220 |
| 193 } while (usedGlobals[name] != null); | 221 String getMappedGlobalName(String proposedName) { |
| 194 // Record the count in case we see this name later. We | 222 var newName = globalNameMap[proposedName]; |
| 195 // frequently see names multiple times, as all our closures use | 223 if (newName == null) { |
| 196 // the same name for their class. | 224 newName = getFreshName(proposedName, usedGlobalNames); |
| 197 usedGlobals[proposedName] = count; | 225 globalNameMap[proposedName] = newName; |
| 198 } | 226 } |
| 199 usedGlobals[name] = 0; | 227 return newName; |
| 200 return name; | 228 } |
| 229 | |
| 230 String getMappedInstanceName(String proposedName) { | |
| 231 var newName = instanceNameMap[proposedName]; | |
| 232 if (newName == null) { | |
| 233 newName = getFreshName(proposedName, usedInstanceNames); | |
| 234 instanceNameMap[proposedName] = newName; | |
| 235 } | |
| 236 return newName; | |
| 237 } | |
| 238 | |
| 239 String getFreshName(String proposedName, Set<String> usedNames) { | |
| 240 var candidate; | |
| 241 proposedName = safeName(proposedName); | |
| 242 if (!usedNames.contains(proposedName)) { | |
| 243 candidate = proposedName; | |
| 244 } else { | |
| 245 var counter = popularNameCounters[proposedName]; | |
| 246 var i = counter == null ? 0 : counter; | |
| 247 while (usedNames.contains("$proposedName$i")) { | |
| 248 i++; | |
| 249 } | |
| 250 popularNameCounters[proposedName] = i + 1; | |
| 251 candidate = "$proposedName$i"; | |
| 252 } | |
| 253 usedNames.add(candidate); | |
| 254 return candidate; | |
| 201 } | 255 } |
| 202 | 256 |
| 203 static const String LIBRARY_PREFIX = "lib"; | 257 static const String LIBRARY_PREFIX = "lib"; |
| 204 | 258 |
| 205 /** | 259 /** |
| 206 * Returns a preferred JS-id for the given top-level or static element. | 260 * Returns a preferred JS-id for the given top-level or static element. |
| 207 * The returned id is guaranteed to be a valid JS-id. | 261 * The returned id is guaranteed to be a valid JS-id. |
| 208 */ | 262 */ |
| 209 String _computeGuess(Element element) { | 263 String _computeGuess(Element element) { |
| 210 assert(!element.isInstanceMember()); | 264 assert(!element.isInstanceMember()); |
| 211 LibraryElement lib = element.getLibrary(); | 265 LibraryElement lib = element.getLibrary(); |
| 212 String name; | 266 String name; |
| 213 if (element.isGenerativeConstructor()) { | 267 if (element.isGenerativeConstructor()) { |
| 214 if (element.name == element.getEnclosingClass().name) { | 268 if (element.name == element.getEnclosingClass().name) { |
| 215 // Keep the class name for the class and not the factory. | 269 // Keep the class name for the class and not the factory. |
| 216 name = "${element.name.slowToString()}\$"; | 270 name = "${element.name.slowToString()}\$"; |
| 217 } else { | 271 } else { |
| 218 name = element.name.slowToString(); | 272 name = element.name.slowToString(); |
| 219 } | 273 } |
| 220 } else if (Elements.isStaticOrTopLevel(element)) { | 274 } else if (Elements.isStaticOrTopLevel(element)) { |
| 221 if (element.isMember()) { | 275 if (element.isMember()) { |
| 222 ClassElement enclosingClass = element.getEnclosingClass(); | 276 ClassElement enclosingClass = element.getEnclosingClass(); |
| 223 name = "${enclosingClass.name.slowToString()}_" | 277 name = "${enclosingClass.name.slowToString()}_" |
| 224 "${element.name.slowToString()}"; | 278 "${element.name.slowToString()}"; |
| 225 } else { | 279 } else { |
| 226 name = element.name.slowToString(); | 280 name = element.name.slowToString(); |
| 227 } | 281 } |
| 228 } else if (identical(element.kind, ElementKind.LIBRARY)) { | 282 } else if (element.isLibrary()) { |
| 229 name = LIBRARY_PREFIX; | 283 name = LIBRARY_PREFIX; |
| 230 } else { | 284 } else { |
| 231 name = element.name.slowToString(); | 285 name = element.name.slowToString(); |
| 232 } | 286 } |
| 233 // Prefix the name with '$' if it is reserved. | 287 // Prefix the name with '$' if it is reserved. |
| 234 return safeName(name); | 288 return name; |
| 235 } | 289 } |
| 236 | 290 |
| 237 String getBailoutName(Element element) { | 291 String getBailoutName(Element element) { |
| 238 return '${getName(element)}\$bailout'; | 292 bool global = !element.isInstanceMember(); |
| 293 var unminifiedName = '${getName(element)}\$bailout'; | |
| 294 if (global) { | |
| 295 return getMappedGlobalName(unminifiedName); | |
| 296 } else { | |
| 297 return getMappedInstanceName(unminifiedName); | |
| 298 } | |
| 239 } | 299 } |
| 240 | 300 |
| 241 /** | 301 /** |
| 242 * Returns a preferred JS-id for the given element. The returned id is | 302 * Returns a preferred JS-id for the given element. The returned id is |
| 243 * guaranteed to be a valid JS-id. Globals and static fields are furthermore | 303 * guaranteed to be a valid JS-id. Globals and static fields are furthermore |
| 244 * guaranteed to be unique. | 304 * guaranteed to be unique. |
| 245 * | 305 * |
| 246 * For accessing statics consider calling | 306 * For accessing statics consider calling |
| 247 * [isolateAccess]/[isolateBailoutAccess] or [isolatePropertyAccess] instead. | 307 * [isolateAccess]/[isolateBailoutAccess] or [isolatePropertyAccess] instead. |
| 248 */ | 308 */ |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 267 | 327 |
| 268 // Dealing with a top-level or static element. | 328 // Dealing with a top-level or static element. |
| 269 String cached = globals[element]; | 329 String cached = globals[element]; |
| 270 if (cached != null) return cached; | 330 if (cached != null) return cached; |
| 271 | 331 |
| 272 String guess = _computeGuess(element); | 332 String guess = _computeGuess(element); |
| 273 ElementKind kind = element.kind; | 333 ElementKind kind = element.kind; |
| 274 if (identical(kind, ElementKind.VARIABLE) || | 334 if (identical(kind, ElementKind.VARIABLE) || |
| 275 identical(kind, ElementKind.PARAMETER)) { | 335 identical(kind, ElementKind.PARAMETER)) { |
| 276 // The name is not guaranteed to be unique. | 336 // The name is not guaranteed to be unique. |
| 277 return guess; | 337 return safeName(guess); |
| 278 } | 338 } |
| 279 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || | 339 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR || |
| 280 identical(kind, ElementKind.FUNCTION) || | 340 kind == ElementKind.FUNCTION || |
| 281 identical(kind, ElementKind.CLASS) || | 341 kind == ElementKind.CLASS || |
| 282 identical(kind, ElementKind.FIELD) || | 342 kind == ElementKind.FIELD || |
| 283 identical(kind, ElementKind.GETTER) || | 343 kind == ElementKind.GETTER || |
| 284 identical(kind, ElementKind.SETTER) || | 344 kind == ElementKind.SETTER || |
| 285 identical(kind, ElementKind.TYPEDEF) || | 345 kind == ElementKind.TYPEDEF || |
| 286 identical(kind, ElementKind.LIBRARY)) { | 346 kind == ElementKind.LIBRARY) { |
| 287 String result = getFreshGlobalName(guess); | 347 bool isNative = false; |
| 348 if (identical(kind, ElementKind.CLASS)) { | |
| 349 ClassElement class_elt = element; | |
| 350 isNative = class_elt.isNative(); | |
| 351 } | |
| 352 if (Elements.isInstanceField(element)) { | |
| 353 isNative = element.isNative(); | |
| 354 } | |
| 355 String result = isNative ? guess : getFreshName(guess, usedGlobalNames); | |
| 288 globals[element] = result; | 356 globals[element] = result; |
| 289 return result; | 357 return result; |
| 290 } | 358 } |
| 291 compiler.internalError('getName for unknown kind: ${element.kind}', | 359 compiler.internalError('getName for unknown kind: ${element.kind}', |
| 292 node: element.parseNode(compiler)); | 360 node: element.parseNode(compiler)); |
| 293 } | 361 } |
| 294 } | 362 } |
| 295 | 363 |
| 296 String getLazyInitializerName(Element element) { | 364 String getLazyInitializerName(Element element) { |
| 297 // TODO(floitsch): mangle while not conflicting with other statics. | |
| 298 assert(Elements.isStaticOrTopLevelField(element)); | 365 assert(Elements.isStaticOrTopLevelField(element)); |
| 299 return "get\$${getName(element)}"; | 366 return getMappedGlobalName("get\$${getName(element)}"); |
| 300 } | 367 } |
| 301 | 368 |
| 302 String isolatePropertiesAccess(Element element) { | 369 String isolatePropertiesAccess(Element element) { |
| 303 return "$ISOLATE.$ISOLATE_PROPERTIES.${getName(element)}"; | 370 return "$ISOLATE.$ISOLATE_PROPERTIES.${getName(element)}"; |
| 304 } | 371 } |
| 305 | 372 |
| 306 String isolatePropertiesAccessForConstant(String constantName) { | 373 String isolatePropertiesAccessForConstant(String constantName) { |
| 307 return "$ISOLATE.$ISOLATE_PROPERTIES.$constantName"; | 374 return "$ISOLATE.$ISOLATE_PROPERTIES.$constantName"; |
| 308 } | 375 } |
| 309 | 376 |
| 310 String isolateAccess(Element element) { | 377 String isolateAccess(Element element) { |
| 311 return "$CURRENT_ISOLATE.${getName(element)}"; | 378 return "$CURRENT_ISOLATE.${getName(element)}"; |
| 312 } | 379 } |
| 313 | 380 |
| 314 String isolateBailoutAccess(Element element) { | 381 String isolateBailoutAccess(Element element) { |
| 315 return '${isolateAccess(element)}\$bailout'; | 382 String newName = getMappedGlobalName('${getName(element)}\$bailout'); |
| 383 return '$CURRENT_ISOLATE.$newName'; | |
| 316 } | 384 } |
| 317 | 385 |
| 318 String isolateLazyInitializerAccess(Element element) { | 386 String isolateLazyInitializerAccess(Element element) { |
| 319 return "$CURRENT_ISOLATE.${getLazyInitializerName(element)}"; | 387 return "$CURRENT_ISOLATE.${getLazyInitializerName(element)}"; |
| 320 } | 388 } |
| 321 | 389 |
| 322 String operatorIs(Element element) { | 390 String operatorIs(Element element) { |
| 391 // TODO(erikcorry): Reduce from is$x to ix when we are minifying. | |
| 323 return 'is\$${getName(element)}'; | 392 return 'is\$${getName(element)}'; |
| 324 } | 393 } |
| 325 | 394 |
| 326 String safeName(String name) { | 395 String safeName(String name) { |
| 327 if (jsReserved.contains(name) || name.startsWith('\$')) { | 396 if (jsReserved.contains(name) || name.startsWith('\$')) { |
| 328 name = "\$$name"; | 397 name = "\$$name"; |
| 329 assert(!jsReserved.contains(name)); | 398 assert(!jsReserved.contains(name)); |
| 330 } | 399 } |
| 331 return name; | 400 return name; |
| 332 } | 401 } |
| 333 } | 402 } |
| OLD | NEW |