| 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 MinifyNamer extends Namer with _MinifiedFieldNamer, | 10 class MinifyNamer extends Namer with _MinifiedFieldNamer, |
| 11 _MinifiedOneShotInterceptorNamer { | 11 _MinifyConstructorBodyNamer, _MinifiedOneShotInterceptorNamer { |
| 12 MinifyNamer(Compiler compiler) : super(compiler) { | 12 MinifyNamer(Compiler compiler) : super(compiler) { |
| 13 reserveBackendNames(); | 13 reserveBackendNames(); |
| 14 fieldRegistry = new _FieldNamingRegistry(this); | 14 fieldRegistry = new _FieldNamingRegistry(this); |
| 15 } | 15 } |
| 16 | 16 |
| 17 _FieldNamingRegistry fieldRegistry; | 17 _FieldNamingRegistry fieldRegistry; |
| 18 | 18 |
| 19 String get isolateName => 'I'; | 19 String get isolateName => 'I'; |
| 20 String get isolatePropertiesName => 'p'; | 20 String get isolatePropertiesName => 'p'; |
| 21 bool get shouldMinify => true; | 21 bool get shouldMinify => true; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 @override | 249 @override |
| 250 jsAst.Name instanceFieldPropertyName(Element element) { | 250 jsAst.Name instanceFieldPropertyName(Element element) { |
| 251 jsAst.Name proposed = _minifiedInstanceFieldPropertyName(element); | 251 jsAst.Name proposed = _minifiedInstanceFieldPropertyName(element); |
| 252 if (proposed != null) { | 252 if (proposed != null) { |
| 253 return proposed; | 253 return proposed; |
| 254 } | 254 } |
| 255 return super.instanceFieldPropertyName(element); | 255 return super.instanceFieldPropertyName(element); |
| 256 } | 256 } |
| 257 } | 257 } |
| 258 | 258 |
| 259 /// Implements naming for constructor bodies. |
| 260 /// |
| 261 /// Constructor bodies are only called in settings where the target is |
| 262 /// statically known. Therefore, we can share their names between classes. |
| 263 /// However, to support calling the constructor body of a super constructor, |
| 264 /// each level in the inheritance tree has to use its own names. |
| 265 /// |
| 266 /// This class implements a naming scheme by counting the distance from |
| 267 /// a given constructor to [Object], where distance is the number of |
| 268 /// constructors declared along the inheritance chain. |
| 269 class _ConstructorBodyNamingScope { |
| 270 final int _startIndex; |
| 271 final List _constructors; |
| 272 |
| 273 int get numberOfConstructors => _constructors.length; |
| 274 |
| 275 _ConstructorBodyNamingScope _superScope; |
| 276 |
| 277 _ConstructorBodyNamingScope.rootScope(ClassElement cls) |
| 278 : _superScope = null, |
| 279 _startIndex = 0, |
| 280 _constructors = cls.constructors.toList(growable: false); |
| 281 |
| 282 _ConstructorBodyNamingScope.forClass(ClassElement cls, |
| 283 _ConstructorBodyNamingScope superScope) |
| 284 : _superScope = superScope, |
| 285 _startIndex = superScope._startIndex + superScope.numberOfConstructors, |
| 286 _constructors = cls.constructors.toList(growable: false); |
| 287 |
| 288 // Mixin Applications have constructors but we never generate code for them, |
| 289 // so they do not count in the inheritance chain. |
| 290 _ConstructorBodyNamingScope.forMixinApplication(ClassElement cls, |
| 291 _ConstructorBodyNamingScope superScope) |
| 292 : _superScope = superScope, |
| 293 _startIndex = superScope._startIndex + superScope.numberOfConstructors, |
| 294 _constructors = const []; |
| 295 |
| 296 factory _ConstructorBodyNamingScope(ClassElement cls, |
| 297 Map<ClassElement, _ConstructorBodyNamingScope> registry) { |
| 298 return registry.putIfAbsent(cls, () { |
| 299 if (cls.superclass == null) { |
| 300 return new _ConstructorBodyNamingScope.rootScope(cls); |
| 301 } else if (cls.isMixinApplication) { |
| 302 return new _ConstructorBodyNamingScope.forMixinApplication(cls, |
| 303 new _ConstructorBodyNamingScope(cls.superclass, registry)); |
| 304 } else { |
| 305 return new _ConstructorBodyNamingScope.forClass(cls, |
| 306 new _ConstructorBodyNamingScope(cls.superclass, registry)); |
| 307 } |
| 308 }); |
| 309 } |
| 310 |
| 311 String constructorBodyKeyFor(ConstructorBodyElement body) { |
| 312 int position = _constructors.indexOf(body.constructor); |
| 313 assert(invariant(body, position >= 0, message: "constructor body missing")); |
| 314 return "@constructorBody@${_startIndex + position}"; |
| 315 } |
| 316 } |
| 317 |
| 318 abstract class _MinifyConstructorBodyNamer implements Namer { |
| 319 Map<ClassElement, _ConstructorBodyNamingScope> _constructorBodyScopes = |
| 320 new Map<ClassElement, _ConstructorBodyNamingScope>(); |
| 321 |
| 322 @override |
| 323 jsAst.Name constructorBodyName(FunctionElement method) { |
| 324 _ConstructorBodyNamingScope scope = |
| 325 new _ConstructorBodyNamingScope(method.enclosingClass, |
| 326 _constructorBodyScopes); |
| 327 String key = scope.constructorBodyKeyFor(method); |
| 328 return _disambiguateMemberByKey(key, |
| 329 () => _proposeNameForConstructorBody(method)); |
| 330 } |
| 331 } |
| 332 |
| 259 abstract class _MinifiedOneShotInterceptorNamer implements Namer { | 333 abstract class _MinifiedOneShotInterceptorNamer implements Namer { |
| 260 /// Property name used for the one-shot interceptor method for the given | 334 /// Property name used for the one-shot interceptor method for the given |
| 261 /// [selector] and return-type specialization. | 335 /// [selector] and return-type specialization. |
| 262 @override | 336 @override |
| 263 jsAst.Name nameForGetOneShotInterceptor(Selector selector, | 337 jsAst.Name nameForGetOneShotInterceptor(Selector selector, |
| 264 Iterable<ClassElement> classes) { | 338 Iterable<ClassElement> classes) { |
| 265 String root = selector.isOperator | 339 String root = selector.isOperator |
| 266 ? operatorNameToIdentifier(selector.name) | 340 ? operatorNameToIdentifier(selector.name) |
| 267 : privateName(selector.memberName); | 341 : privateName(selector.memberName); |
| 268 String prefix = selector.isGetter | 342 String prefix = selector.isGetter |
| 269 ? r"$get" | 343 ? r"$get" |
| 270 : selector.isSetter ? r"$set" : ""; | 344 : selector.isSetter ? r"$set" : ""; |
| 271 String arity = selector.isCall ? "${selector.argumentCount}" : ""; | 345 String arity = selector.isCall ? "${selector.argumentCount}" : ""; |
| 272 String suffix = suffixForGetInterceptor(classes); | 346 String suffix = suffixForGetInterceptor(classes); |
| 273 String fullName = "\$intercepted$prefix\$$root$arity\$$suffix"; | 347 String fullName = "\$intercepted$prefix\$$root$arity\$$suffix"; |
| 274 return _disambiguateInternalGlobal(fullName); | 348 return _disambiguateInternalGlobal(fullName); |
| 275 } | 349 } |
| 276 } | 350 } |
| 277 | 351 |
| OLD | NEW |