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 { |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 usedGlobals[name] = 0; | 201 usedGlobals[name] = 0; |
202 return name; | 202 return name; |
203 } | 203 } |
204 | 204 |
205 static const String LIBRARY_PREFIX = "lib"; | 205 static const String LIBRARY_PREFIX = "lib"; |
206 | 206 |
207 /** | 207 /** |
208 * Returns a preferred JS-id for the given top-level or static element. | 208 * Returns a preferred JS-id for the given top-level or static element. |
209 * The returned id is guaranteed to be a valid JS-id. | 209 * The returned id is guaranteed to be a valid JS-id. |
210 */ | 210 */ |
211 String _computeGuess(Element element) { | 211 String _computeGuess(Element element, bool allowUnsafeName) { |
212 assert(!element.isInstanceMember()); | 212 assert(!element.isInstanceMember()); |
213 LibraryElement lib = element.getLibrary(); | 213 LibraryElement lib = element.getLibrary(); |
214 String name; | 214 String name; |
215 if (element.isGenerativeConstructor()) { | 215 if (element.isGenerativeConstructor()) { |
216 if (element.name == element.getEnclosingClass().name) { | 216 if (element.name == element.getEnclosingClass().name) { |
217 // Keep the class name for the class and not the factory. | 217 // Keep the class name for the class and not the factory. |
218 name = "${element.name.slowToString()}\$"; | 218 name = "${element.name.slowToString()}\$"; |
219 } else { | 219 } else { |
220 name = element.name.slowToString(); | 220 name = element.name.slowToString(); |
221 } | 221 } |
222 } else if (Elements.isStaticOrTopLevel(element)) { | 222 } else if (Elements.isStaticOrTopLevel(element)) { |
223 if (element.isMember()) { | 223 if (element.isMember()) { |
224 ClassElement enclosingClass = element.getEnclosingClass(); | 224 ClassElement enclosingClass = element.getEnclosingClass(); |
225 name = "${enclosingClass.name.slowToString()}_" | 225 name = "${enclosingClass.name.slowToString()}_" |
226 "${element.name.slowToString()}"; | 226 "${element.name.slowToString()}"; |
227 } else { | 227 } else { |
228 name = element.name.slowToString(); | 228 name = element.name.slowToString(); |
229 } | 229 } |
230 } else if (identical(element.kind, ElementKind.LIBRARY)) { | 230 } else if (identical(element.kind, ElementKind.LIBRARY)) { |
231 name = LIBRARY_PREFIX; | 231 name = LIBRARY_PREFIX; |
232 } else { | 232 } else { |
233 name = element.name.slowToString(); | 233 name = element.name.slowToString(); |
234 } | 234 } |
235 // Prefix the name with '$' if it is reserved. | 235 // Prefix the name with '$' if it is reserved and we generate safe names. |
236 return safeName(name); | 236 return allowUnsafeName ? name : safeName(name); |
237 } | 237 } |
238 | 238 |
239 String getBailoutName(Element element) { | 239 String getBailoutName(Element element) { |
240 return '${getName(element)}\$bailout'; | 240 return '${getName(element)}\$bailout'; |
241 } | 241 } |
242 | 242 |
243 /** | 243 /** |
244 * Returns a preferred JS-id for the given element. The returned id is | 244 * Returns a preferred JS-id for the given element. The returned id is |
245 * guaranteed to be a valid JS-id. Globals and static fields are furthermore | 245 * guaranteed to be a valid JS-id. Globals and static fields are furthermore |
246 * guaranteed to be unique. | 246 * guaranteed to be unique. |
247 * | 247 * |
248 * For accessing statics consider calling | 248 * For accessing statics consider calling |
249 * [isolateAccess]/[isolateBailoutAccess] or [isolatePropertyAccess] instead. | 249 * [isolateAccess]/[isolateBailoutAccess] or [isolatePropertyAccess] instead. |
250 */ | 250 */ |
251 String getName(Element element) { | 251 String getName(Element element, {bool allowUnsafeName: false}) { |
252 if (element.isInstanceMember()) { | 252 if (element.isInstanceMember()) { |
253 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY | 253 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY |
254 || element.kind == ElementKind.FUNCTION) { | 254 || element.kind == ElementKind.FUNCTION) { |
255 return instanceMethodName(element); | 255 return instanceMethodName(element); |
256 } else if (element.kind == ElementKind.GETTER) { | 256 } else if (element.kind == ElementKind.GETTER) { |
257 return getterName(element.getLibrary(), element.name); | 257 return getterName(element.getLibrary(), element.name); |
258 } else if (element.kind == ElementKind.SETTER) { | 258 } else if (element.kind == ElementKind.SETTER) { |
259 return setterName(element.getLibrary(), element.name); | 259 return setterName(element.getLibrary(), element.name); |
260 } else if (element.kind == ElementKind.FIELD) { | 260 } else if (element.kind == ElementKind.FIELD) { |
261 return instanceFieldName(element.getLibrary(), element.name); | 261 return instanceFieldName(element.getLibrary(), element.name); |
262 } else { | 262 } else { |
263 compiler.internalError('getName for bad kind: ${element.kind}', | 263 compiler.internalError('getName for bad kind: ${element.kind}', |
264 node: element.parseNode(compiler)); | 264 node: element.parseNode(compiler)); |
265 } | 265 } |
266 } else { | 266 } else { |
267 // Use declaration element to ensure invariant on [globals]. | 267 // Use declaration element to ensure invariant on [globals]. |
268 element = element.declaration; | 268 element = element.declaration; |
269 | |
270 // Dealing with a top-level or static element. | 269 // Dealing with a top-level or static element. |
271 String cached = globals[element]; | 270 String cached = globals[element]; |
272 if (cached != null) return cached; | 271 if (cached != null) return cached; |
273 | 272 |
274 String guess = _computeGuess(element); | 273 String guess = _computeGuess(element, allowUnsafeName); |
275 ElementKind kind = element.kind; | 274 ElementKind kind = element.kind; |
276 if (identical(kind, ElementKind.VARIABLE) || | 275 if (identical(kind, ElementKind.VARIABLE) || |
277 identical(kind, ElementKind.PARAMETER)) { | 276 identical(kind, ElementKind.PARAMETER)) { |
278 // The name is not guaranteed to be unique. | 277 // The name is not guaranteed to be unique. |
279 return guess; | 278 return guess; |
280 } | 279 } |
281 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || | 280 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || |
282 identical(kind, ElementKind.FUNCTION) || | 281 identical(kind, ElementKind.FUNCTION) || |
283 identical(kind, ElementKind.CLASS) || | 282 identical(kind, ElementKind.CLASS) || |
284 identical(kind, ElementKind.FIELD) || | 283 identical(kind, ElementKind.FIELD) || |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 } | 325 } |
327 | 326 |
328 String safeName(String name) { | 327 String safeName(String name) { |
329 if (jsReserved.contains(name) || name.startsWith('\$')) { | 328 if (jsReserved.contains(name) || name.startsWith('\$')) { |
330 name = "\$$name"; | 329 name = "\$$name"; |
331 assert(!jsReserved.contains(name)); | 330 assert(!jsReserved.contains(name)); |
332 } | 331 } |
333 return name; | 332 return name; |
334 } | 333 } |
335 } | 334 } |
OLD | NEW |