Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/namer.dart

Issue 11453032: Reapply class/method/field minification (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Changes to bring patch up to date and fix bugs Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
13 static Set<String> _jsReserved = null; 11 static Set<String> _jsReserved = null;
14 Set<String> get jsReserved { 12 Set<String> get jsReserved {
15 if (_jsReserved == null) { 13 if (_jsReserved == null) {
16 _jsReserved = new Set<String>(); 14 _jsReserved = new Set<String>();
17 _jsReserved.addAll(JsNames.javaScriptKeywords); 15 _jsReserved.addAll(JsNames.javaScriptKeywords);
18 _jsReserved.addAll(JsNames.reservedPropertySymbols); 16 _jsReserved.addAll(JsNames.reservedPropertySymbols);
19 } 17 }
20 return _jsReserved; 18 return _jsReserved;
21 } 19 }
22 20
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;
29 final Map<Element, String> globals; 30 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;
32 37
33 /** 38 /**
34 * A cache of names used for bailout methods. We make sure two 39 * A cache of names used for bailout methods. We make sure two
35 * bailout methods cannot have the same name because if the two 40 * bailout methods cannot have the same name because if the two
36 * bailout methods are in a class and a subclass, we would 41 * bailout methods are in a class and a subclass, we would
37 * call the wrong bailout method at runtime. To make it 42 * call the wrong bailout method at runtime. To make it
38 * simple, we don't keep track of inheritance and always avoid 43 * simple, we don't keep track of inheritance and always avoid
39 * similar names. 44 * similar names.
40 */ 45 */
41 final Set<String> usedBailoutInstanceNames; 46 final Set<String> usedBailoutInstanceNames;
42 final Map<Element, String> bailoutNames; 47 final Map<Element, String> bailoutNames;
43 48
44 final Map<Constant, String> constantNames; 49 final Map<Constant, String> constantNames;
45 50
46 Namer(this.compiler) 51 Namer(this.compiler)
47 : globals = new Map<Element, String>(), 52 : globals = new Map<Element, String>(),
48 usedGlobals = new Map<String, int>(),
49 shortPrivateNameOwners = new Map<String, LibraryElement>(), 53 shortPrivateNameOwners = new Map<String, LibraryElement>(),
50 bailoutNames = new Map<Element, String>(), 54 bailoutNames = new Map<Element, String>(),
51 usedBailoutInstanceNames = new Set<String>(), 55 usedBailoutInstanceNames = new Set<String>(),
52 constantNames = new Map<Constant, String>(); 56 usedGlobalNames = new Set<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>();
53 62
54 final String CURRENT_ISOLATE = r'$'; 63 String get ISOLATE => 'Isolate';
55 final String ISOLATE = 'Isolate'; 64 String get ISOLATE_PROPERTIES => r'$isolateProperties';
56 final String ISOLATE_PROPERTIES = r"$isolateProperties";
57 /** 65 /**
58 * Some closures must contain their name. The name is stored in 66 * Some closures must contain their name. The name is stored in
59 * [STATIC_CLOSURE_NAME_NAME]. 67 * [STATIC_CLOSURE_NAME_NAME].
60 */ 68 */
61 final String STATIC_CLOSURE_NAME_NAME = r'$name'; 69 String get STATIC_CLOSURE_NAME_NAME => r'$name';
62 static const SourceString CLOSURE_INVOCATION_NAME = 70 SourceString get CLOSURE_INVOCATION_NAME => Compiler.CALL_OPERATOR_NAME;
63 Compiler.CALL_OPERATOR_NAME; 71 bool get shouldMinify => false;
72
73 bool isReserved(String name) => name == ISOLATE;
64 74
65 String constantName(Constant constant) { 75 String constantName(Constant constant) {
66 // In the current implementation it doesn't make sense to give names to 76 // In the current implementation it doesn't make sense to give names to
67 // function constants since the function-implementation itself serves as 77 // function constants since the function-implementation itself serves as
68 // constant and can be accessed directly. 78 // constant and can be accessed directly.
69 assert(!constant.isFunction()); 79 assert(!constant.isFunction());
70 String result = constantNames[constant]; 80 String result = constantNames[constant];
71 if (result == null) { 81 if (result == null) {
72 result = getFreshGlobalName("CTC"); 82 String longName;
83 if (shouldMinify) {
84 if (constant.isString()) {
85 StringConstant stringConstant = constant;
86 // The minifier never returns the same string as we suggested so we
floitsch 2012/12/07 12:01:01 The minifier always constructs a new name, using t
erikcorry 2012/12/10 08:36:01 Done.
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";
floitsch 2012/12/07 12:01:01 We could maybe switch to "CONSTANT" now? (but no s
erikcorry 2012/12/10 08:36:01 Done.
96 }
97 result = getFreshName(longName, usedGlobalNames);
73 constantNames[constant] = result; 98 constantNames[constant] = result;
74 } 99 }
75 return result; 100 return result;
76 } 101 }
77 102
78 String closureInvocationName(Selector selector) { 103 String closureInvocationName(Selector selector) {
79 // TODO(floitsch): mangle, while not conflicting with instance names. 104 return
80 return instanceMethodInvocationName(null, CLOSURE_INVOCATION_NAME, 105 instanceMethodInvocationName(null, CLOSURE_INVOCATION_NAME, selector);
81 selector);
82 } 106 }
83 107
84 String breakLabelName(LabelElement label) { 108 String breakLabelName(LabelElement label) {
85 return '\$${label.labelName}\$${label.target.nestingLevel}'; 109 return '\$${label.labelName}\$${label.target.nestingLevel}';
86 } 110 }
87 111
88 String implicitBreakLabelName(TargetElement target) { 112 String implicitBreakLabelName(TargetElement target) {
89 return '\$${target.nestingLevel}'; 113 return '\$${target.nestingLevel}';
90 } 114 }
91 115
92 // We sometimes handle continue targets differently from break targets, 116 // We sometimes handle continue targets differently from break targets,
93 // so we have special continue-only labels. 117 // so we have special continue-only labels.
94 String continueLabelName(LabelElement label) { 118 String continueLabelName(LabelElement label) {
95 return 'c\$${label.labelName}\$${label.target.nestingLevel}'; 119 return 'c\$${label.labelName}\$${label.target.nestingLevel}';
96 } 120 }
97 121
98 String implicitContinueLabelName(TargetElement target) { 122 String implicitContinueLabelName(TargetElement target) {
99 return 'c\$${target.nestingLevel}'; 123 return 'c\$${target.nestingLevel}';
100 } 124 }
101 125
102 /** 126 /**
103 * If the [name] is not private returns [:name.slowToString():]. Otherwise 127 * If the [name] is not private returns [:name.slowToString():]. Otherwise
104 * mangles the [name] so that each library has a unique name. 128 * mangles the [name] so that each library has a unique name.
105 */ 129 */
106 String privateName(LibraryElement lib, SourceString name) { 130 String privateName(LibraryElement lib, SourceString name) {
131 String result;
107 if (name.isPrivate()) { 132 if (name.isPrivate()) {
108 String nameString = name.slowToString(); 133 String nameString = name.slowToString();
109 // The first library asking for a short private name wins. 134 // The first library asking for a short private name wins.
110 LibraryElement owner = 135 LibraryElement owner =
floitsch 2012/12/07 12:01:01 I don't think you need to fill the shortPrivateNam
erikcorry 2012/12/10 08:36:01 Done.
111 shortPrivateNameOwners.putIfAbsent(nameString, () => lib); 136 shortPrivateNameOwners.putIfAbsent(nameString, () => lib);
112 // If a private name could clash with a mangled private name we don't 137 // If a private name could clash with a mangled private name we don't
113 // use the short name. For example a private name "_lib3_foo" would 138 // use the short name. For example a private name "_lib3_foo" would
114 // clash with "_foo" from "lib3". 139 // clash with "_foo" from "lib3".
115 if (identical(owner, lib) && !nameString.startsWith('_$LIBRARY_PREFIX')) { 140 if (owner == lib &&
116 return nameString; 141 !nameString.startsWith('_$LIBRARY_PREFIX') &&
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';
117 } 151 }
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';
123 } else { 152 } else {
124 return name.slowToString(); 153 result = name.slowToString();
125 } 154 }
155 return result;
126 } 156 }
127 157
128 String instanceMethodName(FunctionElement element) { 158 String instanceMethodName(FunctionElement element) {
129 SourceString name = Elements.operatorNameToIdentifier(element.name); 159 SourceString name = Elements.operatorNameToIdentifier(element.name);
130 LibraryElement lib = element.getLibrary(); 160 LibraryElement lib = element.getLibrary();
131 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { 161 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) {
132 ConstructorBodyElement bodyElement = element; 162 ConstructorBodyElement bodyElement = element;
133 name = bodyElement.constructor.name; 163 name = bodyElement.constructor.name;
134 } 164 }
135 FunctionSignature signature = element.computeSignature(compiler); 165 FunctionSignature signature = element.computeSignature(compiler);
136 String methodName = 166 String methodName =
137 '${privateName(lib, name)}\$${signature.parameterCount}'; 167 '${privateName(lib, name)}\$${signature.parameterCount}';
138 if (!signature.optionalParametersAreNamed) { 168 if (signature.optionalParametersAreNamed &&
139 return methodName; 169 !signature.optionalParameters.isEmpty) {
140 } else if (!signature.optionalParameters.isEmpty) {
141 StringBuffer buffer = new StringBuffer(); 170 StringBuffer buffer = new StringBuffer();
142 signature.orderedOptionalParameters.forEach((Element element) { 171 signature.orderedOptionalParameters.forEach((Element element) {
143 buffer.add('\$${JsNames.getValid(element.name.slowToString())}'); 172 buffer.add('\$${JsNames.getValid(element.name.slowToString())}');
144 }); 173 });
145 return '$methodName$buffer'; 174 methodName = '$methodName$buffer';
146 } 175 }
176 if (name == CLOSURE_INVOCATION_NAME) return methodName;
177 return getMappedInstanceName(methodName);
147 } 178 }
148 179
149 String publicInstanceMethodNameByArity(SourceString name, int arity) { 180 String publicInstanceMethodNameByArity(SourceString name, int arity) {
150 name = Elements.operatorNameToIdentifier(name); 181 name = Elements.operatorNameToIdentifier(name);
151 assert(!name.isPrivate()); 182 assert(!name.isPrivate());
152 return '${name.slowToString()}\$$arity'; 183 var base = name.slowToString();
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);
153 } 189 }
154 190
155 String instanceMethodInvocationName(LibraryElement lib, SourceString name, 191 String instanceMethodInvocationName(LibraryElement lib, SourceString name,
156 Selector selector) { 192 Selector selector) {
157 name = Elements.operatorNameToIdentifier(name); 193 name = Elements.operatorNameToIdentifier(name);
158 // TODO(floitsch): mangle, while preserving uniqueness. 194 // TODO(floitsch): mangle, while preserving uniqueness.
159 StringBuffer buffer = new StringBuffer(); 195 StringBuffer buffer = new StringBuffer();
160 List<SourceString> names = selector.getOrderedNamedArguments(); 196 List<SourceString> names = selector.getOrderedNamedArguments();
161 for (SourceString argumentName in names) { 197 for (SourceString argumentName in names) {
162 buffer.add(r'$'); 198 buffer.add(r'$');
163 argumentName.printOn(buffer); 199 argumentName.printOn(buffer);
164 } 200 }
165 return '${privateName(lib, name)}\$${selector.argumentCount}$buffer'; 201 if (name == CLOSURE_INVOCATION_NAME) {
floitsch 2012/12/07 12:01:01 Copy comment from above. (saying that closure invo
erikcorry 2012/12/10 08:36:01 Done.
202 return '$CLOSURE_INVOCATION_NAME\$${selector.argumentCount}$buffer';
203 }
204 return getMappedInstanceName(
205 '${privateName(lib, name)}\$${selector.argumentCount}$buffer');
166 } 206 }
167 207
168 String instanceFieldName(LibraryElement libraryElement, SourceString name) { 208 String instanceFieldName(LibraryElement libraryElement, SourceString name) {
169 String proposedName = privateName(libraryElement, name); 209 String proposedName = privateName(libraryElement, name);
170 return safeName(proposedName); 210 return getMappedInstanceName(proposedName);
171 } 211 }
172 212
213 // Construct a new name for the element based on the library and class it is
214 // in. The name here is not important, we just need to make sure it is
215 // unique. If we are minifying, we actually construct the name from the
216 // minfiied versions of the class and instance names, but the result is
sra1 2012/12/07 06:03:18 minfiied -> minified
erikcorry 2012/12/10 08:36:01 Done.
217 // minified once again, so that is not visible in the end result.
173 String shadowedFieldName(Element fieldElement) { 218 String shadowedFieldName(Element fieldElement) {
219 // Check for following situation: Native field ${fieldElement.name} has
220 // fixed JSName ${fieldElement.nativeName()}, but a subclass shadows this
221 // name. We normally handle that by renaming the superclass field, but we
222 // can't do that because native fields have fixed JSNames. In practice
223 // this can't happen because we can't inherit from native classes.
224 assert (!fieldElement.isNative());
225
174 ClassElement cls = fieldElement.getEnclosingClass(); 226 ClassElement cls = fieldElement.getEnclosingClass();
175 LibraryElement libraryElement = fieldElement.getLibrary(); 227 LibraryElement libraryElement = fieldElement.getLibrary();
176 String libName = getName(libraryElement); 228 String libName = getName(libraryElement);
177 String clsName = getName(cls); 229 String clsName = getName(cls);
178 String instanceName = instanceFieldName(libraryElement, fieldElement.name); 230 String instanceName = instanceFieldName(libraryElement, fieldElement.name);
179 return safeName('$libName\$$clsName\$$instanceName'); 231 return getMappedInstanceName('$libName\$$clsName\$$instanceName');
180 } 232 }
181 233
182 String setterName(LibraryElement lib, SourceString name) { 234 String setterName(LibraryElement lib, SourceString name) {
183 // We dynamically create setters from the field-name. The setter name must 235 // We dynamically create setters from the field-name. The setter name must
184 // therefore be derived from the instance field-name. 236 // therefore be derived from the instance field-name.
185 String fieldName = safeName(privateName(lib, name)); 237 String fieldName = getMappedInstanceName(privateName(lib, name));
186 return 'set\$$fieldName'; 238 return 'set\$$fieldName';
187 } 239 }
188 240
241 String setterNameFromAccessorName(String name) {
242 // We dynamically create setters from the field-name. The setter name must
243 // therefore be derived from the instance field-name.
244 return 'set\$$name';
245 }
246
189 String publicGetterName(SourceString name) { 247 String publicGetterName(SourceString name) {
190 // We dynamically create getters from the field-name. The getter name must 248 // We dynamically create getters from the field-name. The getter name must
191 // therefore be derived from the instance field-name. 249 // therefore be derived from the instance field-name.
192 String fieldName = safeName(name.slowToString()); 250 String fieldName = getMappedInstanceName(name.slowToString());
193 return 'get\$$fieldName'; 251 return 'get\$$fieldName';
194 } 252 }
195 253
254 String getterNameFromAccessorName(String name) {
255 // We dynamically create getters from the field-name. The getter name must
256 // therefore be derived from the instance field-name.
257 return 'get\$$name';
258 }
259
196 String getterName(LibraryElement lib, SourceString name) { 260 String getterName(LibraryElement lib, SourceString name) {
197 // We dynamically create getters from the field-name. The getter name must 261 // We dynamically create getters from the field-name. The getter name must
198 // therefore be derived from the instance field-name. 262 // therefore be derived from the instance field-name.
199 String fieldName = safeName(privateName(lib, name)); 263 String fieldName = getMappedInstanceName(privateName(lib, name));
200 return 'get\$$fieldName'; 264 return 'get\$$fieldName';
201 } 265 }
202 266
203 String getFreshGlobalName(String proposedName) { 267 String getMappedGlobalName(String proposedName) {
204 String name = proposedName; 268 var newName = globalNameMap[proposedName];
205 int count = usedGlobals[name]; 269 if (newName == null) {
206 if (count != null) { 270 newName = getFreshName(proposedName, usedGlobalNames);
207 // Not the first time we see this name. Append a number to make it unique. 271 globalNameMap[proposedName] = newName;
208 do {
209 name = '$proposedName${count++}';
210 } while (usedGlobals[name] != null);
211 // Record the count in case we see this name later. We
212 // frequently see names multiple times, as all our closures use
213 // the same name for their class.
214 usedGlobals[proposedName] = count;
215 } 272 }
216 usedGlobals[name] = 0; 273 return newName;
217 return name; 274 }
275
276 String getMappedInstanceName(String proposedName) {
277 var newName = instanceNameMap[proposedName];
278 if (newName == null) {
279 newName = getFreshName(proposedName, usedInstanceNames);
280 instanceNameMap[proposedName] = newName;
281 }
282 return newName;
283 }
284
285 String getFreshName(String proposedName, Set<String> usedNames) {
286 var candidate;
287 proposedName = safeName(proposedName);
288 if (!usedNames.contains(proposedName)) {
289 candidate = proposedName;
290 } else {
291 var counter = popularNameCounters[proposedName];
292 var i = counter == null ? 0 : counter;
293 while (usedNames.contains("$proposedName$i")) {
294 i++;
295 }
296 popularNameCounters[proposedName] = i + 1;
297 candidate = "$proposedName$i";
298 }
299 usedNames.add(candidate);
300 return candidate;
218 } 301 }
219 302
220 static const String LIBRARY_PREFIX = "lib"; 303 static const String LIBRARY_PREFIX = "lib";
221 304
222 /** 305 /**
223 * Returns a preferred JS-id for the given top-level or static element. 306 * Returns a preferred JS-id for the given top-level or static element.
224 * The returned id is guaranteed to be a valid JS-id. 307 * The returned id is guaranteed to be a valid JS-id.
225 */ 308 */
226 String _computeGuess(Element element) { 309 String _computeGuess(Element element) {
227 assert(!element.isInstanceMember()); 310 assert(!element.isInstanceMember());
(...skipping 12 matching lines...) Expand all
240 name = "${enclosingClass.name.slowToString()}_" 323 name = "${enclosingClass.name.slowToString()}_"
241 "${element.name.slowToString()}"; 324 "${element.name.slowToString()}";
242 } else { 325 } else {
243 name = element.name.slowToString(); 326 name = element.name.slowToString();
244 } 327 }
245 } else if (element.isLibrary()) { 328 } else if (element.isLibrary()) {
246 name = LIBRARY_PREFIX; 329 name = LIBRARY_PREFIX;
247 } else { 330 } else {
248 name = element.name.slowToString(); 331 name = element.name.slowToString();
249 } 332 }
250 return safeName(name); 333 return name;
251 } 334 }
252 335
253 String getSpecializedName(Element element, Collection<ClassElement> classes) { 336 String getSpecializedName(Element element, Collection<ClassElement> classes) {
337 // This gets the minified name, but it doesn't really make much difference.
338 // the important thing is that it is a unique name.
254 StringBuffer buffer = new StringBuffer('${getName(element)}\$'); 339 StringBuffer buffer = new StringBuffer('${getName(element)}\$');
255 for (ClassElement cls in classes) { 340 for (ClassElement cls in classes) {
256 buffer.add(getName(cls)); 341 buffer.add(getName(cls));
257 } 342 }
258 return safeName(buffer.toString()); 343 return getMappedGlobalName(buffer.toString());
259 } 344 }
260 345
261 String getBailoutName(Element element) { 346 String getBailoutName(Element element) {
262 String name = bailoutNames[element]; 347 String name = bailoutNames[element];
263 if (name != null) return name; 348 if (name != null) return name;
264 bool global = !element.isInstanceMember(); 349 bool global = !element.isInstanceMember();
350 // Despite the name of the variable, this gets the minified name when we
351 // are minifying, but it doesn't really make much difference. The
352 // important thing is that it is a unique name. We add $bailout and, if we
353 // are minifying, we minify the minified name and '$bailout'.
265 String unminifiedName = '${getName(element)}\$bailout'; 354 String unminifiedName = '${getName(element)}\$bailout';
266 name = unminifiedName; 355 if (global) {
267 if (!global) { 356 name = getMappedGlobalName(unminifiedName);
357 } else {
358 name = unminifiedName;
268 int i = 0; 359 int i = 0;
269 while (usedBailoutInstanceNames.contains(name)) { 360 while (usedBailoutInstanceNames.contains(name)) {
270 name = '$unminifiedName${i++}'; 361 name = '$unminifiedName${i++}';
271 } 362 }
272 usedBailoutInstanceNames.add(name); 363 usedBailoutInstanceNames.add(name);
364 name = getMappedInstanceName(name);
273 } 365 }
274 bailoutNames[element] = name; 366 bailoutNames[element] = name;
275 return name; 367 return name;
276 } 368 }
277 369
278 /** 370 /**
279 * Returns a preferred JS-id for the given element. The returned id is 371 * Returns a preferred JS-id for the given element. The returned id is
280 * guaranteed to be a valid JS-id. Globals and static fields are furthermore 372 * guaranteed to be a valid JS-id. Globals and static fields are furthermore
281 * guaranteed to be unique. 373 * guaranteed to be unique.
282 * 374 *
(...skipping 20 matching lines...) Expand all
303 element = element.declaration; 395 element = element.declaration;
304 // Dealing with a top-level or static element. 396 // Dealing with a top-level or static element.
305 String cached = globals[element]; 397 String cached = globals[element];
306 if (cached != null) return cached; 398 if (cached != null) return cached;
307 399
308 String guess = _computeGuess(element); 400 String guess = _computeGuess(element);
309 ElementKind kind = element.kind; 401 ElementKind kind = element.kind;
310 if (identical(kind, ElementKind.VARIABLE) || 402 if (identical(kind, ElementKind.VARIABLE) ||
311 identical(kind, ElementKind.PARAMETER)) { 403 identical(kind, ElementKind.PARAMETER)) {
312 // The name is not guaranteed to be unique. 404 // The name is not guaranteed to be unique.
313 return guess; 405 return safeName(guess);
314 } 406 }
315 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || 407 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR ||
316 identical(kind, ElementKind.FUNCTION) || 408 kind == ElementKind.FUNCTION ||
317 identical(kind, ElementKind.CLASS) || 409 kind == ElementKind.CLASS ||
318 identical(kind, ElementKind.FIELD) || 410 kind == ElementKind.FIELD ||
319 identical(kind, ElementKind.GETTER) || 411 kind == ElementKind.GETTER ||
320 identical(kind, ElementKind.SETTER) || 412 kind == ElementKind.SETTER ||
321 identical(kind, ElementKind.TYPEDEF) || 413 kind == ElementKind.TYPEDEF ||
322 identical(kind, ElementKind.LIBRARY) || 414 kind == ElementKind.LIBRARY ||
323 identical(kind, ElementKind.MALFORMED_TYPE)) { 415 kind == ElementKind.MALFORMED_TYPE) {
324 String result = getFreshGlobalName(guess); 416 bool isNative = false;
417 if (identical(kind, ElementKind.CLASS)) {
floitsch 2012/12/07 12:01:01 use "=="
erikcorry 2012/12/10 08:36:01 Done.
418 ClassElement class_elt = element;
419 isNative = class_elt.isNative();
420 }
421 if (Elements.isInstanceField(element)) {
422 isNative = element.isNative();
423 }
424 String result = isNative ? guess : getFreshName(guess, usedGlobalNames);
325 globals[element] = result; 425 globals[element] = result;
326 return result; 426 return result;
327 } 427 }
328 compiler.internalError('getName for unknown kind: ${element.kind}', 428 compiler.internalError('getName for unknown kind: ${element.kind}',
329 node: element.parseNode(compiler)); 429 node: element.parseNode(compiler));
330 } 430 }
331 } 431 }
332 432
333 String getLazyInitializerName(Element element) { 433 String getLazyInitializerName(Element element) {
334 // TODO(floitsch): mangle while not conflicting with other statics.
335 assert(Elements.isStaticOrTopLevelField(element)); 434 assert(Elements.isStaticOrTopLevelField(element));
336 return "get\$${getName(element)}"; 435 return getMappedGlobalName("get\$${getName(element)}");
337 } 436 }
338 437
339 String isolatePropertiesAccess(Element element) { 438 String isolatePropertiesAccess(Element element) {
340 return "$ISOLATE.$ISOLATE_PROPERTIES.${getName(element)}"; 439 return "$ISOLATE.$ISOLATE_PROPERTIES.${getName(element)}";
341 } 440 }
342 441
343 String isolateAccess(Element element) { 442 String isolateAccess(Element element) {
344 return "$CURRENT_ISOLATE.${getName(element)}"; 443 return "$CURRENT_ISOLATE.${getName(element)}";
345 } 444 }
346 445
347 String isolateBailoutAccess(Element element) { 446 String isolateBailoutAccess(Element element) {
348 return '${isolateAccess(element)}\$bailout'; 447 String newName = getMappedGlobalName('${getName(element)}\$bailout');
448 return '$CURRENT_ISOLATE.$newName';
349 } 449 }
350 450
351 String isolateLazyInitializerAccess(Element element) { 451 String isolateLazyInitializerAccess(Element element) {
352 return "$CURRENT_ISOLATE.${getLazyInitializerName(element)}"; 452 return "$CURRENT_ISOLATE.${getLazyInitializerName(element)}";
353 } 453 }
354 454
355 String operatorIs(Element element) { 455 String operatorIs(Element element) {
456 // TODO(erikcorry): Reduce from is$x to ix when we are minifying.
356 return 'is\$${getName(element)}'; 457 return 'is\$${getName(element)}';
357 } 458 }
358 459
359 String safeName(String name) { 460 String safeName(String name) {
360 if (jsReserved.contains(name) || name.startsWith('\$')) { 461 if (jsReserved.contains(name) || name.startsWith('\$')) {
361 name = "\$$name"; 462 name = "\$$name";
362 assert(!jsReserved.contains(name)); 463 assert(!jsReserved.contains(name));
363 } 464 }
364 return name; 465 return name;
365 } 466 }
366 } 467 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698