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

Unified Diff: pkg/compiler/lib/src/js_backend/frequency_namer.dart

Issue 1212613009: dart2js: Implement frequency based naming. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Reserve reserved names :) Created 5 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/js_backend/frequency_namer.dart
diff --git a/pkg/compiler/lib/src/js_backend/frequency_namer.dart b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
new file mode 100644
index 0000000000000000000000000000000000000000..0aaf8f6703737c9e5bf4d06f6f67cb8124f96b31
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
@@ -0,0 +1,142 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of js_backend;
+
+class FrequencyBasedNamer extends Namer with _MinifiedFieldNamer,
+ _MinifiedOneShotInterceptorNamer implements jsAst.TokenFinalizer {
+ _FieldNamingRegistry fieldRegistry;
+ List<TokenName> tokens = new List<TokenName>();
+
+ Map<NamingScope, TokenScope> _tokenScopes =
+ new Maplet<NamingScope, TokenScope>();
+
+ // Some basic settings for smaller names
+ String get isolateName => 'I';
+ String get isolatePropertiesName => 'p';
+ bool get shouldMinify => true;
+
+ final String getterPrefix = 'g';
+ final String setterPrefix = 's';
+ final String callPrefix = ''; // this will create function names $<n>
+
+ FrequencyBasedNamer(Compiler compiler) : super(compiler) {
+ fieldRegistry = new _FieldNamingRegistry(this);
+ }
+
+ TokenScope newScopeFor(NamingScope scope) {
+ if (scope == NamingScope.instance) {
+ Set<String> illegalNames = new Set<String>.from(jsReserved);
+ for (String illegal in MinifyNamer._reservedNativeProperties) {
+ illegalNames.add(illegal);
+ if (MinifyNamer._hasBannedPrefix(illegal)) {
+ illegalNames.add(illegal.substring(1));
+ }
+ }
+ return new TokenScope(illegalNames);
+ } else {
+ return new TokenScope(jsReserved);
+ }
+ }
+
+ @override
+ jsAst.Name getFreshName(NamingScope scope, String proposedName,
+ {bool sanitizeForNatives: false,
+ bool sanitizeForAnnotations: false}) {
+ // Grab the scope for this token
+ TokenScope tokenScope = _tokenScopes.putIfAbsent(scope,
+ () => newScopeFor(scope));
+
+ // Get the name the normal namer would use as a key.
+ String proposed = _generateFreshStringForName(proposedName,
+ getUsedNames(scope),
+ getSuggestedNames(scope),
+ sanitizeForNatives:
+ sanitizeForNatives,
+ sanitizeForAnnotations:
+ sanitizeForAnnotations);
+
+ TokenName name = new TokenName(tokenScope, proposed);
+ tokens.add(name);
+ return name;
+ }
+
+ @override
+ jsAst.Name instanceFieldPropertyName(Element element) {
+ jsAst.Name proposed = _minifiedInstanceFieldPropertyName(element);
+ if (proposed != null) {
+ return proposed;
+ }
+ return super.instanceFieldPropertyName(element);
+ }
+
+ @override
+ void finalizeTokens() {
+ int compareReferenceCount(TokenName a, TokenName b) {
+ int result = b._rc - a._rc;
+ if (result == 0) result = a.key.compareTo(b.key);
+ return result;
+ }
+
+ List<TokenName> usedNames =
+ tokens.where((TokenName a) => a._rc > 0).toList();
+ usedNames.sort(compareReferenceCount);
+ usedNames.forEach((TokenName token) => token.finalize());
+ }
+}
+
+class TokenScope {
+ List<int> _nextName = [$a];
+ final Set<String> illegalNames;
+
+ TokenScope([this.illegalNames = const ImmutableEmptySet()]);
+
+ /// Increments the letter at [pos] in the current name. Also takes care of
+ /// overflows to the left. Returns the carry bit, i.e., it returns `true`
+ /// if all positions to the left have wrapped around.
+ ///
+ /// If [_nextName] is initially 'a', this will generate the sequence
+ ///
+ /// [a-zA-Z]
+ /// [a-zA-Z][_0-9a-zA-Z]
+ /// [a-zA-Z][_0-9a-zA-Z][_0-9a-zA-Z]
+ /// ...
+ bool _incrementPosition(int pos) {
+ bool overflow = false;
+ if (pos < 0) return true;
+ int value = _nextName[pos];
+ if (value == $_) {
+ value = $0;
+ } else if (value == $9) {
+ value = $a;
+ } else if (value == $z) {
+ value = $A;
+ } else if (value == $Z) {
+ overflow = _incrementPosition(pos - 1);
+ value = (pos > 0) ? $_ : $a;
+ } else {
+ value++;
+ }
+ _nextName[pos] = value;
+ return overflow;
+ }
+
+ _incrementName() {
+ if (_incrementPosition(_nextName.length - 1)) {
+ _nextName.add($_);
+ }
+ }
+
+ String getNextName() {
+ String proposal;
+ do {
+ proposal = new String.fromCharCodes(_nextName);
+ _incrementName();
+ } while (MinifyNamer._hasBannedPrefix(proposal) ||
+ illegalNames.contains(proposal));
+
+ return proposal;
+ }
+}
+
« no previous file with comments | « pkg/compiler/lib/src/js_backend/field_naming_mixin.dart ('k') | pkg/compiler/lib/src/js_backend/js_backend.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698