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