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

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

Issue 11860008: Stop passing library elements to tons of namer functions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Diff against https://codereview.chromium.org/11819060/. Created 7 years, 11 months 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 implements ClosureNamer { 10 class Namer implements ClosureNamer {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 } 92 }
93 } else { 93 } else {
94 longName = "CONSTANT"; 94 longName = "CONSTANT";
95 } 95 }
96 result = getFreshName(longName, usedGlobalNames); 96 result = getFreshName(longName, usedGlobalNames);
97 constantNames[constant] = result; 97 constantNames[constant] = result;
98 } 98 }
99 return result; 99 return result;
100 } 100 }
101 101
102 String closureInvocationName(Selector selector) {
103 return instanceMethodInvocationName(null, closureInvocationSelectorName,
104 selector);
105 }
106
107 String breakLabelName(LabelElement label) { 102 String breakLabelName(LabelElement label) {
108 return '\$${label.labelName}\$${label.target.nestingLevel}'; 103 return '\$${label.labelName}\$${label.target.nestingLevel}';
109 } 104 }
110 105
111 String implicitBreakLabelName(TargetElement target) { 106 String implicitBreakLabelName(TargetElement target) {
112 return '\$${target.nestingLevel}'; 107 return '\$${target.nestingLevel}';
113 } 108 }
114 109
115 // We sometimes handle continue targets differently from break targets, 110 // We sometimes handle continue targets differently from break targets,
116 // so we have special continue-only labels. 111 // so we have special continue-only labels.
117 String continueLabelName(LabelElement label) { 112 String continueLabelName(LabelElement label) {
118 return 'c\$${label.labelName}\$${label.target.nestingLevel}'; 113 return 'c\$${label.labelName}\$${label.target.nestingLevel}';
119 } 114 }
120 115
121 String implicitContinueLabelName(TargetElement target) { 116 String implicitContinueLabelName(TargetElement target) {
122 return 'c\$${target.nestingLevel}'; 117 return 'c\$${target.nestingLevel}';
123 } 118 }
124 119
125 /** 120 /**
126 * If the [name] is not private returns [:name.slowToString():]. Otherwise 121 * If the [name] is not private returns [:name.slowToString():]. Otherwise
127 * mangles the [name] so that each library has a unique name. 122 * mangles the [name] so that each library has a unique name.
128 */ 123 */
129 String privateName(LibraryElement lib, SourceString name) { 124 String privateName(LibraryElement library, SourceString name) {
130 String result; 125 // Public names are easy.
131 if (name.isPrivate()) { 126 String nameString = name.slowToString();
132 String nameString = name.slowToString(); 127 if (!name.isPrivate()) return nameString;
133 // The first library asking for a short private name wins. 128
134 LibraryElement owner = shouldMinify ? 129 // The first library asking for a short private name wins.
135 lib : 130 LibraryElement owner = shouldMinify
136 shortPrivateNameOwners.putIfAbsent(nameString, () => lib); 131 ? library
137 // If a private name could clash with a mangled private name we don't 132 : shortPrivateNameOwners.putIfAbsent(nameString, () => library);
138 // use the short name. For example a private name "_lib3_foo" would 133
139 // clash with "_foo" from "lib3". 134 // If a private name could clash with a mangled private name we don't
140 if (owner == lib && 135 // use the short name. For example a private name "_lib3_foo" would
141 !nameString.startsWith('_$LIBRARY_PREFIX') && 136 // clash with "_foo" from "lib3".
142 !shouldMinify) { 137 if (owner == library &&
143 result = nameString; 138 !nameString.startsWith('_$LIBRARY_PREFIX') &&
144 } else { 139 !shouldMinify) {
145 String libName = getName(lib); 140 return nameString;
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 }
152 } else {
153 result = name.slowToString();
154 } 141 }
155 return result; 142
143 // If a library name does not start with the [LIBRARY_PREFIX] then our
144 // assumptions about clashing with mangled private members do not hold.
145 String libraryName = getName(library);
146 assert(shouldMinify || libraryName.startsWith(LIBRARY_PREFIX));
147 // TODO(erikcorry): Fix this with other manglings to avoid clashes.
148 return '_library$libraryName\$$nameString';
ngeoffray 2013/01/11 10:29:11 Note that you just changed the name to start with
156 } 149 }
157 150
158 String instanceMethodName(FunctionElement element) { 151 String instanceMethodName(FunctionElement element) {
159 SourceString name = Elements.operatorNameToIdentifier(element.name); 152 SourceString name = Elements.operatorNameToIdentifier(element.name);
160 LibraryElement lib = element.getLibrary(); 153 LibraryElement library = element.getLibrary();
161 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { 154 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) {
162 ConstructorBodyElement bodyElement = element; 155 ConstructorBodyElement bodyElement = element;
163 name = bodyElement.constructor.name; 156 name = bodyElement.constructor.name;
164 } 157 }
165 FunctionSignature signature = element.computeSignature(compiler); 158 FunctionSignature signature = element.computeSignature(compiler);
166 String methodName = 159 String methodName =
167 '${privateName(lib, name)}\$${signature.parameterCount}'; 160 '${privateName(library, name)}\$${signature.parameterCount}';
168 if (signature.optionalParametersAreNamed && 161 if (signature.optionalParametersAreNamed &&
169 !signature.optionalParameters.isEmpty) { 162 !signature.optionalParameters.isEmpty) {
170 StringBuffer buffer = new StringBuffer(); 163 StringBuffer buffer = new StringBuffer();
171 signature.orderedOptionalParameters.forEach((Element element) { 164 signature.orderedOptionalParameters.forEach((Element element) {
172 buffer.add('\$${JsNames.getValid(element.name.slowToString())}'); 165 buffer.add('\$${JsNames.getValid(element.name.slowToString())}');
173 }); 166 });
174 methodName = '$methodName$buffer'; 167 methodName = '$methodName$buffer';
175 } 168 }
176 if (name == closureInvocationSelectorName) return methodName; 169 if (name == closureInvocationSelectorName) return methodName;
177 return getMappedInstanceName(methodName); 170 return getMappedInstanceName(methodName);
178 } 171 }
179 172
180 String publicInstanceMethodNameByArity(SourceString name, int arity) { 173 String publicInstanceMethodNameByArity(SourceString name, int arity) {
181 name = Elements.operatorNameToIdentifier(name); 174 name = Elements.operatorNameToIdentifier(name);
182 assert(!name.isPrivate()); 175 assert(!name.isPrivate());
183 var base = name.slowToString(); 176 var base = name.slowToString();
184 // We don't mangle the closure invoking function name because it is 177 // We don't mangle the closure invoking function name because it is
185 // generated in by string concatenation applyFunction from js_helper.dart. 178 // generated in by string concatenation applyFunction from js_helper.dart.
186 var proposedName = '$base\$$arity'; 179 var proposedName = '$base\$$arity';
187 if (base == closureInvocationSelectorName) return proposedName; 180 if (base == closureInvocationSelectorName) return proposedName;
188 return getMappedInstanceName(proposedName); 181 return getMappedInstanceName(proposedName);
189 } 182 }
190 183
191 String instanceMethodInvocationName(LibraryElement lib, SourceString name, 184 String invocationName(Selector selector) {
192 Selector selector) { 185 if (selector.isGetter()) {
193 name = Elements.operatorNameToIdentifier(name); 186 String proposedName = privateName(selector.library, selector.name);
194 // TODO(floitsch): mangle, while preserving uniqueness. 187 return 'get\$${getMappedInstanceName(proposedName)}';
195 StringBuffer buffer = new StringBuffer(); 188 } else if (selector.isSetter()) {
196 List<SourceString> names = selector.getOrderedNamedArguments(); 189 String proposedName = privateName(selector.library, selector.name);
197 for (SourceString argumentName in names) { 190 return 'set\$${getMappedInstanceName(proposedName)}';
198 buffer.add(r'$'); 191 } else {
199 argumentName.printOn(buffer); 192 assert(selector.isCall());
193 SourceString name = Elements.operatorNameToIdentifier(selector.name);
194 StringBuffer buffer = new StringBuffer();
195 for (SourceString argumentName in selector.getOrderedNamedArguments()) {
196 buffer.add(r'$');
197 argumentName.printOn(buffer);
198 }
199 String suffix = '\$${selector.argumentCount}$buffer';
200 // We don't mangle the closure invoking function name because it
201 // is generated in by string concatenation applyFunction from
ngeoffray 2013/01/11 10:29:11 in by string concatenation applyFunction -> by str
202 // js_helper.dart.
203 if (selector.isClosureCall()) return "$name$suffix";
204 String proposedName = privateName(selector.library, name);
205 return getMappedInstanceName('$proposedName$suffix');
200 } 206 }
201 if (name == closureInvocationSelectorName) {
202 // We don't mangle the closure invoking function name because it is
203 // generated in by string concatenation applyFunction from js_helper.dart.
204 return '$closureInvocationSelectorName\$${selector.argumentCount}$buffer';
205 }
206 return getMappedInstanceName(
207 '${privateName(lib, name)}\$${selector.argumentCount}$buffer');
208 } 207 }
209 208
210 /** 209 /**
211 * Returns the internal name used for an invocation mirror of this selector. 210 * Returns the internal name used for an invocation mirror of this selector.
212 */ 211 */
213 String invocationMirrorInternalName(Selector selector) { 212 String invocationMirrorInternalName(Selector selector)
214 if (selector.isGetter()) { 213 => invocationName(selector);
215 return getterName(selector.library, selector.name);
216 } else if (selector.isSetter()) {
217 return setterName(selector.library, selector.name);
218 } else {
219 return instanceMethodInvocationName(
220 selector.library, selector.name, selector);
221 }
222 }
223 214
224 String instanceFieldName(LibraryElement libraryElement, SourceString name) { 215 String instanceFieldName(Element element) {
225 String proposedName = privateName(libraryElement, name); 216 String proposedName = privateName(element.getLibrary(), element.name);
226 return getMappedInstanceName(proposedName); 217 return getMappedInstanceName(proposedName);
227 } 218 }
228 219
229 // Construct a new name for the element based on the library and class it is 220 // Construct a new name for the element based on the library and class it is
230 // in. The name here is not important, we just need to make sure it is 221 // in. The name here is not important, we just need to make sure it is
231 // unique. If we are minifying, we actually construct the name from the 222 // unique. If we are minifying, we actually construct the name from the
232 // minified versions of the class and instance names, but the result is 223 // minified versions of the class and instance names, but the result is
233 // minified once again, so that is not visible in the end result. 224 // minified once again, so that is not visible in the end result.
234 String shadowedFieldName(Element fieldElement) { 225 String shadowedFieldName(Element fieldElement) {
235 // Check for following situation: Native field ${fieldElement.name} has 226 // Check for following situation: Native field ${fieldElement.name} has
236 // fixed JSName ${fieldElement.nativeName()}, but a subclass shadows this 227 // fixed JSName ${fieldElement.nativeName()}, but a subclass shadows this
237 // name. We normally handle that by renaming the superclass field, but we 228 // name. We normally handle that by renaming the superclass field, but we
238 // can't do that because native fields have fixed JsNames. In practice 229 // can't do that because native fields have fixed JsNames. In practice
239 // this can't happen because we can't inherit from native classes. 230 // this can't happen because we can't inherit from native classes.
240 assert (!fieldElement.hasFixedBackendName()); 231 assert (!fieldElement.hasFixedBackendName());
241 232
242 ClassElement cls = fieldElement.getEnclosingClass(); 233 String libraryName = getName(fieldElement.getLibrary());
243 LibraryElement libraryElement = fieldElement.getLibrary(); 234 String className = getName(fieldElement.getEnclosingClass());
244 String libName = getName(libraryElement); 235 String instanceName = instanceFieldName(fieldElement);
245 String clsName = getName(cls); 236 return getMappedInstanceName('$libraryName\$$className\$$instanceName');
246 String instanceName = instanceFieldName(libraryElement, fieldElement.name);
247 return getMappedInstanceName('$libName\$$clsName\$$instanceName');
248 } 237 }
249 238
250 String setterName(LibraryElement lib, SourceString name) { 239 String setterName(Element element) {
251 // We dynamically create setters from the field-name. The setter name must 240 // We dynamically create setters from the field-name. The setter name must
252 // therefore be derived from the instance field-name. 241 // therefore be derived from the instance field-name.
253 String fieldName = getMappedInstanceName(privateName(lib, name)); 242 LibraryElement library = element.getLibrary();
254 return 'set\$$fieldName'; 243 String name = getMappedInstanceName(privateName(library, element.name));
244 return 'set\$$name';
255 } 245 }
256 246
257 String setterNameFromAccessorName(String name) { 247 String setterNameFromAccessorName(String name) {
258 // We dynamically create setters from the field-name. The setter name must 248 // We dynamically create setters from the field-name. The setter name must
259 // therefore be derived from the instance field-name. 249 // therefore be derived from the instance field-name.
260 return 'set\$$name'; 250 return 'set\$$name';
261 } 251 }
262 252
263 String publicGetterName(SourceString name) { 253 String publicGetterName(SourceString name) {
264 // We dynamically create getters from the field-name. The getter name must 254 // We dynamically create getters from the field-name. The getter name must
265 // therefore be derived from the instance field-name. 255 // therefore be derived from the instance field-name.
266 String fieldName = getMappedInstanceName(name.slowToString()); 256 String fieldName = getMappedInstanceName(name.slowToString());
267 return 'get\$$fieldName'; 257 return 'get\$$fieldName';
268 } 258 }
269 259
270 String getterNameFromAccessorName(String name) { 260 String getterNameFromAccessorName(String name) {
271 // 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
272 // therefore be derived from the instance field-name. 262 // therefore be derived from the instance field-name.
273 return 'get\$$name'; 263 return 'get\$$name';
274 } 264 }
275 265
276 String getterName(LibraryElement lib, SourceString name) { 266 String getterName(Element element) {
277 // We dynamically create getters from the field-name. The getter name must 267 // We dynamically create getters from the field-name. The getter name must
278 // therefore be derived from the instance field-name. 268 // therefore be derived from the instance field-name.
279 String fieldName = getMappedInstanceName(privateName(lib, name)); 269 LibraryElement library = element.getLibrary();
280 return 'get\$$fieldName'; 270 String name = getMappedInstanceName(privateName(library, element.name));
271 return 'get\$$name';
281 } 272 }
282 273
283 String getMappedGlobalName(String proposedName) { 274 String getMappedGlobalName(String proposedName) {
284 var newName = globalNameMap[proposedName]; 275 var newName = globalNameMap[proposedName];
285 if (newName == null) { 276 if (newName == null) {
286 newName = getFreshName(proposedName, usedGlobalNames); 277 newName = getFreshName(proposedName, usedGlobalNames);
287 globalNameMap[proposedName] = newName; 278 globalNameMap[proposedName] = newName;
288 } 279 }
289 return newName; 280 return newName;
290 } 281 }
(...skipping 30 matching lines...) Expand all
321 } 312 }
322 313
323 static const String LIBRARY_PREFIX = "lib"; 314 static const String LIBRARY_PREFIX = "lib";
324 315
325 /** 316 /**
326 * Returns a preferred JS-id for the given top-level or static element. 317 * Returns a preferred JS-id for the given top-level or static element.
327 * The returned id is guaranteed to be a valid JS-id. 318 * The returned id is guaranteed to be a valid JS-id.
328 */ 319 */
329 String _computeGuess(Element element) { 320 String _computeGuess(Element element) {
330 assert(!element.isInstanceMember()); 321 assert(!element.isInstanceMember());
331 LibraryElement lib = element.getLibrary();
332 String name; 322 String name;
333 if (element.isGenerativeConstructor()) { 323 if (element.isGenerativeConstructor()) {
334 if (element.name == element.getEnclosingClass().name) { 324 if (element.name == element.getEnclosingClass().name) {
335 // Keep the class name for the class and not the factory. 325 // Keep the class name for the class and not the factory.
336 name = "${element.name.slowToString()}\$"; 326 name = "${element.name.slowToString()}\$";
337 } else { 327 } else {
338 name = element.name.slowToString(); 328 name = element.name.slowToString();
339 } 329 }
340 } else if (Elements.isStaticOrTopLevel(element)) { 330 } else if (Elements.isStaticOrTopLevel(element)) {
341 if (element.isMember()) { 331 if (element.isMember()) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 * 384 *
395 * For accessing statics consider calling 385 * For accessing statics consider calling
396 * [isolateAccess]/[isolateBailoutAccess] or [isolatePropertyAccess] instead. 386 * [isolateAccess]/[isolateBailoutAccess] or [isolatePropertyAccess] instead.
397 */ 387 */
398 String getName(Element element) { 388 String getName(Element element) {
399 if (element.isInstanceMember()) { 389 if (element.isInstanceMember()) {
400 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY 390 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY
401 || element.kind == ElementKind.FUNCTION) { 391 || element.kind == ElementKind.FUNCTION) {
402 return instanceMethodName(element); 392 return instanceMethodName(element);
403 } else if (element.kind == ElementKind.GETTER) { 393 } else if (element.kind == ElementKind.GETTER) {
404 return getterName(element.getLibrary(), element.name); 394 return getterName(element);
405 } else if (element.kind == ElementKind.SETTER) { 395 } else if (element.kind == ElementKind.SETTER) {
406 return setterName(element.getLibrary(), element.name); 396 return setterName(element);
407 } else if (element.kind == ElementKind.FIELD) { 397 } else if (element.kind == ElementKind.FIELD) {
408 return instanceFieldName(element.getLibrary(), element.name); 398 return instanceFieldName(element);
409 } else { 399 } else {
410 compiler.internalError('getName for bad kind: ${element.kind}', 400 compiler.internalError('getName for bad kind: ${element.kind}',
411 node: element.parseNode(compiler)); 401 node: element.parseNode(compiler));
412 } 402 }
413 } else { 403 } else {
414 // Use declaration element to ensure invariant on [globals]. 404 // Use declaration element to ensure invariant on [globals].
415 element = element.declaration; 405 element = element.declaration;
416 // Dealing with a top-level or static element. 406 // Dealing with a top-level or static element.
417 String cached = globals[element]; 407 String cached = globals[element];
418 if (cached != null) return cached; 408 if (cached != null) return cached;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 } 468 }
479 469
480 String safeName(String name) { 470 String safeName(String name) {
481 if (jsReserved.contains(name) || name.startsWith('\$')) { 471 if (jsReserved.contains(name) || name.startsWith('\$')) {
482 name = "\$$name"; 472 name = "\$$name";
483 assert(!jsReserved.contains(name)); 473 assert(!jsReserved.contains(name));
484 } 474 }
485 return name; 475 return name;
486 } 476 }
487 } 477 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698