| Index: pkg/compiler/lib/src/js_backend/minify_namer.dart
|
| diff --git a/pkg/compiler/lib/src/js_backend/minify_namer.dart b/pkg/compiler/lib/src/js_backend/minify_namer.dart
|
| index 2f0b37cac60070b4876a3399e3717047d6a2817b..9a2d1e3fc4a1290eb5a086a1cceeaae5933d20fe 100644
|
| --- a/pkg/compiler/lib/src/js_backend/minify_namer.dart
|
| +++ b/pkg/compiler/lib/src/js_backend/minify_namer.dart
|
| @@ -7,12 +7,14 @@ part of js_backend;
|
| /**
|
| * Assigns JavaScript identifiers to Dart variables, class-names and members.
|
| */
|
| -class MinifyNamer extends Namer {
|
| +class MinifyNamer extends Namer with _MinifiedFieldNamer {
|
| MinifyNamer(Compiler compiler) : super(compiler) {
|
| reserveBackendNames();
|
| fieldRegistry = new _FieldNamingRegistry(this);
|
| }
|
|
|
| + _FieldNamingRegistry fieldRegistry;
|
| +
|
| String get isolateName => 'I';
|
| String get isolatePropertiesName => 'p';
|
| bool get shouldMinify => true;
|
| @@ -24,18 +26,17 @@ class MinifyNamer extends Namer {
|
| final ALPHABET_CHARACTERS = 52; // a-zA-Z.
|
| final ALPHANUMERIC_CHARACTERS = 62; // a-zA-Z0-9.
|
|
|
| - _FieldNamingRegistry fieldRegistry;
|
| -
|
| /// You can pass an invalid identifier to this and unlike its non-minifying
|
| /// counterpart it will never return the proposedName as the new fresh name.
|
| ///
|
| /// [sanitizeForNatives] and [sanitizeForAnnotations] are ignored because the
|
| /// minified names will always avoid clashing with annotated names or natives.
|
| + @override
|
| jsAst.Name getFreshName(String proposedName,
|
| - Set<String> usedNames,
|
| - Map<String, String> suggestedNames,
|
| - {bool sanitizeForNatives: false,
|
| - bool sanitizeForAnnotations: false}) {
|
| + Set<String> usedNames,
|
| + Map<String, String> suggestedNames,
|
| + {bool sanitizeForNatives: false,
|
| + bool sanitizeForAnnotations: false}) {
|
| String freshName;
|
| String suggestion = suggestedNames[proposedName];
|
| if (suggestion != null && !usedNames.contains(suggestion)) {
|
| @@ -244,209 +245,13 @@ class MinifyNamer extends Namer {
|
| return $0 + x - 52;
|
| }
|
|
|
| + @override
|
| jsAst.Name instanceFieldPropertyName(Element element) {
|
| - if (element.hasFixedBackendName) {
|
| - return new StringBackedName(element.fixedBackendName);
|
| - }
|
| -
|
| - _FieldNamingScope names;
|
| - if (element is BoxFieldElement) {
|
| - names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
|
| - } else {
|
| - ClassElement cls = element is ClosureFieldElement
|
| - ? element.closureClass : element.enclosingClass;
|
| - names = new _FieldNamingScope.forClass(cls, compiler.world,
|
| - fieldRegistry);
|
| - }
|
| -
|
| - // The inheritance scope based naming did not yield a name. For instance,
|
| - // this could be because the field belongs to a mixin.
|
| - if (!names.containsField(element)) {
|
| - return super.instanceFieldPropertyName(element);
|
| - }
|
| -
|
| - return names[element];
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Encapsulates the global state of field naming.
|
| - */
|
| -class _FieldNamingRegistry {
|
| - final MinifyNamer namer;
|
| -
|
| - final Map<Entity, _FieldNamingScope> scopes =
|
| - new Map<Entity, _FieldNamingScope>();
|
| -
|
| - final Map<Entity, jsAst.Name> globalNames = new Map<Entity, jsAst.Name>();
|
| -
|
| - int globalCount = 0;
|
| -
|
| - final List<jsAst.Name> nameStore = new List<jsAst.Name>();
|
| -
|
| - _FieldNamingRegistry(this.namer);
|
| -
|
| - jsAst.Name getName(int count) {
|
| - if (count >= nameStore.length) {
|
| - // The namer usually does not use certain names as they clash with
|
| - // existing properties on JS objects (see [_reservedNativeProperties]).
|
| - // However, some of them are really short and safe to use for fields.
|
| - // Thus, we shortcut the namer to use those first.
|
| - if (count < MinifyNamer._reservedNativeProperties.length &&
|
| - MinifyNamer._reservedNativeProperties[count].length <= 2) {
|
| - nameStore.add(new StringBackedName(
|
| - MinifyNamer._reservedNativeProperties[count]));
|
| - } else {
|
| - nameStore.add(namer.getFreshName("field$count",
|
| - namer.usedInstanceNames, namer.suggestedInstanceNames));
|
| - }
|
| - }
|
| -
|
| - return nameStore[count];
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * A [_FieldNamingScope] encodes a node in the inheritance tree of the current
|
| - * class hierarchy. The root node typically is the node corresponding to the
|
| - * `Object` class. It is used to assign a unique name to each field of a class.
|
| - * Unique here means unique wrt. all fields along the path back to the root.
|
| - * This is achieved at construction time via the [_fieldNameCounter] field that
|
| - * counts the number of fields on the path to the root node that have been
|
| - * encountered so far.
|
| - *
|
| - * Obviously, this only works if no fields are added to a parent node after its
|
| - * children have added their first field.
|
| - */
|
| -class _FieldNamingScope {
|
| - final _FieldNamingScope superScope;
|
| - final Entity container;
|
| - final Map<Element, jsAst.Name> names = new Maplet<Element, jsAst.Name>();
|
| - final _FieldNamingRegistry registry;
|
| -
|
| - /// Naming counter used for fields of ordinary classes.
|
| - int _fieldNameCounter;
|
| -
|
| - /// The number of fields along the superclass chain that use inheritance
|
| - /// based naming, including the ones allocated for this scope.
|
| - int get inheritanceBasedFieldNameCounter => _fieldNameCounter;
|
| -
|
| - /// The number of locally used fields. Depending on the naming source
|
| - /// (e.g. inheritance based or globally unique for mixixns) this
|
| - /// might be different from [inheritanceBasedFieldNameCounter].
|
| - int get _localFieldNameCounter => _fieldNameCounter;
|
| - void set _localFieldNameCounter(int val) { _fieldNameCounter = val; }
|
| -
|
| - factory _FieldNamingScope.forClass(ClassElement cls, ClassWorld world,
|
| - _FieldNamingRegistry registry) {
|
| - _FieldNamingScope result = registry.scopes[cls];
|
| - if (result != null) return result;
|
| -
|
| - if (world.isUsedAsMixin(cls)) {
|
| - result = new _MixinFieldNamingScope.mixin(cls, registry);
|
| - } else {
|
| - if (cls.superclass == null) {
|
| - result = new _FieldNamingScope.rootScope(cls, registry);
|
| - } else {
|
| - _FieldNamingScope superScope = new _FieldNamingScope.forClass(
|
| - cls.superclass, world, registry);
|
| - if (cls.isMixinApplication) {
|
| - result = new _MixinFieldNamingScope.mixedIn(cls, superScope,
|
| - registry);
|
| - } else {
|
| - result = new _FieldNamingScope.inherit(cls, superScope, registry);
|
| - }
|
| - }
|
| + jsAst.Name proposed = _minifiedInstanceFieldPropertyName(element);
|
| + if (proposed != null) {
|
| + return proposed;
|
| }
|
| -
|
| - cls.forEachInstanceField((cls, field) => result.add(field));
|
| -
|
| - registry.scopes[cls] = result;
|
| - return result;
|
| - }
|
| -
|
| - factory _FieldNamingScope.forBox(Local box, _FieldNamingRegistry registry) {
|
| - return registry.scopes.putIfAbsent(box,
|
| - () => new _BoxFieldNamingScope(box, registry));
|
| - }
|
| -
|
| - _FieldNamingScope.rootScope(this.container, this.registry)
|
| - : superScope = null,
|
| - _fieldNameCounter = 0;
|
| -
|
| - _FieldNamingScope.inherit(this.container, this.superScope, this.registry) {
|
| - _fieldNameCounter = superScope.inheritanceBasedFieldNameCounter;
|
| - }
|
| -
|
| - /**
|
| - * Checks whether [name] is already used in the current scope chain.
|
| - */
|
| - _isNameUnused(jsAst.Name name) {
|
| - return !names.values.contains(name) &&
|
| - ((superScope == null) || superScope._isNameUnused(name));
|
| + return super.instanceFieldPropertyName(element);
|
| }
|
| -
|
| - jsAst.Name _nextName() => registry.getName(_localFieldNameCounter++);
|
| -
|
| - jsAst.Name operator[](Element field) {
|
| - jsAst.Name name = names[field];
|
| - if (name == null && superScope != null) return superScope[field];
|
| - return name;
|
| - }
|
| -
|
| - void add(Element field) {
|
| - if (names.containsKey(field)) return;
|
| -
|
| - jsAst.Name value = _nextName();
|
| - assert(invariant(field, _isNameUnused(value)));
|
| - names[field] = value;
|
| - }
|
| -
|
| - bool containsField(Element field) => names.containsKey(field);
|
| }
|
|
|
| -/**
|
| - * Field names for mixins have two constraints: They need to be unique in the
|
| - * hierarchy of each application of a mixin and they need to be the same for
|
| - * all applications of a mixin. To achieve this, we use global naming for
|
| - * mixins from the same name pool as fields and add a `$` at the end to ensure
|
| - * they do not collide with normal field names. The `$` sign is typically used
|
| - * as a separator between method names and argument counts and does not appear
|
| - * in generated names themselves.
|
| - */
|
| -class _MixinFieldNamingScope extends _FieldNamingScope {
|
| - int get _localFieldNameCounter => registry.globalCount;
|
| - void set _localFieldNameCounter(int val) { registry.globalCount = val; }
|
| -
|
| - Map<Entity, jsAst.Name> get names => registry.globalNames;
|
| -
|
| - _MixinFieldNamingScope.mixin(ClassElement cls, _FieldNamingRegistry registry)
|
| - : super.rootScope(cls, registry);
|
| -
|
| - _MixinFieldNamingScope.mixedIn(MixinApplicationElement container,
|
| - _FieldNamingScope superScope, _FieldNamingRegistry registry)
|
| - : super.inherit(container, superScope, registry);
|
| -
|
| - jsAst.Name _nextName() {
|
| - jsAst.Name proposed = super._nextName();
|
| - return new CompoundName([proposed, Namer._literalDollar]);
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * [BoxFieldElement] fields work differently in that they do not belong to an
|
| - * actual class but an anonymous box associated to a [Local]. As there is no
|
| - * inheritance chain, we do not need to compute fields a priori but can assign
|
| - * names on the fly.
|
| - */
|
| -class _BoxFieldNamingScope extends _FieldNamingScope {
|
| - _BoxFieldNamingScope(Local box, _FieldNamingRegistry registry) :
|
| - super.rootScope(box, registry);
|
| -
|
| - bool containsField(_) => true;
|
| -
|
| - jsAst.Name operator[](Element field) {
|
| - if (!names.containsKey(field)) add(field);
|
| - return names[field];
|
| - }
|
| -}
|
|
|