| 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 static Set<String> _jsReserved = null; | 9 static Set<String> _jsReserved = null; |
| 10 Set<String> get jsReserved() { | 10 Set<String> get jsReserved() { |
| 11 if (_jsReserved === null) { | 11 if (_jsReserved === null) { |
| 12 _jsReserved = new Set<String>(); | 12 _jsReserved = new Set<String>(); |
| 13 _jsReserved.addAll(JsNames.javaScriptKeywords); | 13 _jsReserved.addAll(JsNames.javaScriptKeywords); |
| 14 _jsReserved.addAll(JsNames.reservedPropertySymbols); | 14 _jsReserved.addAll(JsNames.reservedPropertySymbols); |
| 15 } | 15 } |
| 16 return _jsReserved; | 16 return _jsReserved; |
| 17 } | 17 } |
| 18 | 18 |
| 19 Map<Element, String> globals; | 19 Map<Element, String> globals; |
| 20 Map<String, int> usedGlobals; | 20 Map<String, int> usedGlobals; |
| 21 | 21 |
| 22 Namer() | 22 Namer() |
| 23 : globals = new Map<Element, String>(), | 23 : globals = new Map<Element, String>(), |
| 24 usedGlobals = new Map<String, int>(); | 24 usedGlobals = new Map<String, int>(); |
| 25 | 25 |
| 26 String get currentIsolate() => "currentIsolate"; | 26 String get currentIsolate() => "currentIsolate"; |
| 27 String get isolate() => "Isolate"; | 27 String get isolate() => "Isolate"; |
| 28 | 28 |
| 29 |
| 30 String instanceName(SourceString instanceName) { |
| 31 String candidate = '$instanceName'; |
| 32 // TODO(floitsch): mangle, while preserving uniqueness. |
| 33 return candidate; |
| 34 } |
| 35 |
| 36 /** |
| 37 * The constructor-body name is computed from the corresponding |
| 38 * constructor element because, in the case of a super-initialization, the |
| 39 * body element is not accessible. |
| 40 */ |
| 41 String constructorBodyName(Element element) { |
| 42 assert(element.kind == ElementKind.CONSTRUCTOR); |
| 43 // TODO(floitsch): the constructor-body name must not conflict with other |
| 44 // instance fields. |
| 45 // TOD(floitsch): deal with named constructors. |
| 46 return instanceName(element.name); |
| 47 } |
| 48 |
| 49 /** |
| 50 * Returns a preferred JS-id for the given element. The returned id is |
| 51 * guaranteed to be a valid JS-id. |
| 52 * |
| 53 * For instance-members the returned strings are guaranteed not to clash. For |
| 54 * static variables there might be clashes. In the latter case the caller |
| 55 * needs to ensure uniqueness. |
| 56 */ |
| 57 String getName(Element element) { |
| 58 switch (element.kind) { |
| 59 case ElementKind.CONSTRUCTOR_BODY: |
| 60 ConstructorBodyElement bodyElement = element; |
| 61 return constructorBodyName(bodyElement.constructor); |
| 62 |
| 63 case ElementKind.CONSTRUCTOR: |
| 64 default: |
| 65 if (element.isInstanceMember()) { |
| 66 return instanceName(element.name); |
| 67 } |
| 68 // TODO(floitsch): deal with named constructors. |
| 69 String name = '${element.name}'; |
| 70 // Prefix the name with '$' if it is reserved. |
| 71 if (jsReserved.contains(name)) { |
| 72 name = "\$$propertyName"; |
| 73 assert(!jsReserved.contains(name)); |
| 74 } |
| 75 return name; |
| 76 } |
| 77 } |
| 78 |
| 79 /** |
| 80 * Don't use this method from the outside. Go through [isolateAccess] or |
| 81 * [isolatePropertyAccess] instead. |
| 82 */ |
| 29 String define(Element element) { | 83 String define(Element element) { |
| 30 assert(globals[element] === null); | 84 assert(globals[element] === null); |
| 31 | 85 |
| 32 String dartId = '${element.name}'; | 86 String name = getName(element); |
| 33 // Prefix the dartId with '$' if the name is reserved. | 87 int usedCount = usedGlobals[name]; |
| 34 if (jsReserved.contains(dartId)) { | |
| 35 dartId = "\$$dartId"; | |
| 36 assert(!jsReserved.contains(dartId)); | |
| 37 } | |
| 38 | |
| 39 int usedCount = usedGlobals[dartId]; | |
| 40 if (usedCount === null) { | 88 if (usedCount === null) { |
| 41 // No element with this name has been used before. | 89 // No element with this name has been used before. |
| 42 usedGlobals[dartId] = 1; | 90 usedGlobals[name] = 1; |
| 43 globals[element] = dartId; | 91 globals[element] = name; |
| 44 return dartId; | 92 return name; |
| 45 } else { | 93 } else { |
| 46 // Not the first time we see an element with this name. Append a number | 94 // Not the first time we see an element with this name. Append a number |
| 47 // to make it unique. | 95 // to make it unique. |
| 48 String id; | 96 String id; |
| 49 do { | 97 do { |
| 50 usedCount++; | 98 usedCount++; |
| 51 id = '$dartId$usedCount'; | 99 id = '$name$usedCount'; |
| 52 } while (usedGlobals[id] !== null); | 100 } while (usedGlobals[id] !== null); |
| 53 usedGlobals[dartId] = usedCount; | 101 usedGlobals[name] = usedCount; |
| 54 globals[element] = id; | 102 globals[element] = id; |
| 55 return id; | 103 return id; |
| 56 } | 104 } |
| 57 } | 105 } |
| 58 | 106 |
| 59 String isolateAccess(Element element) { | 107 String isolateAccess(Element element) { |
| 60 String jsId = globals[element]; | 108 String jsId = globals[element]; |
| 61 if (jsId === null) jsId = define(element); | 109 if (jsId === null) jsId = define(element); |
| 62 return "$currentIsolate.$jsId"; | 110 return "$currentIsolate.$jsId"; |
| 63 } | 111 } |
| 64 | 112 |
| 65 String isolatePropertyAccess(Element element) { | 113 String isolatePropertyAccess(Element element) { |
| 66 String jsId = globals[element]; | 114 String jsId = globals[element]; |
| 67 if (jsId === null) jsId = define(element); | 115 if (jsId === null) jsId = define(element); |
| 68 return "$isolate.prototype.$jsId"; | 116 return "$isolate.prototype.$jsId"; |
| 69 } | 117 } |
| 70 | |
| 71 String methodName(Element element) { | |
| 72 // TODO(floitsch): mangle if necessary. | |
| 73 return '${element.name}'; | |
| 74 } | |
| 75 } | 118 } |
| OLD | NEW |