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