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