Chromium Code Reviews| Index: lib/compiler/implementation/js_backend/minify_namer.dart |
| diff --git a/lib/compiler/implementation/js_backend/minify_namer.dart b/lib/compiler/implementation/js_backend/minify_namer.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..823ffef6dbe982d13d3247af9d96fd010424d1e7 |
| --- /dev/null |
| +++ b/lib/compiler/implementation/js_backend/minify_namer.dart |
| @@ -0,0 +1,95 @@ |
| +// Copyright (c) 2011, 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. |
| + |
| +/** |
| + * Assigns JavaScript identifiers to Dart variables, class-names and members. |
| + */ |
| +class MinifyNamer extends Namer { |
| + MinifyNamer(Compiler compiler) : super(compiler); |
| + |
| + String get ISOLATE => 'I'; |
| + String get ISOLATE_PROPERTIES => 'p'; |
| + bool get minify => true; |
|
floitsch
2012/10/25 12:58:38
I think I prefer "shouldMinify" or "isMinifying",
erikcorry
2012/12/06 09:38:07
Done.
|
| + |
| + String getFreshName(String proposedName, Set<String> usedNames) { |
| + var freshName = _getUnusedName(proposedName, usedNames); |
| + usedNames.add(freshName); |
| + return freshName; |
| + } |
| + |
| + // This gets a minified name based on a hash of the proposed name. This |
| + // is slightly less efficient than just getting the next name in a series, |
| + // but it means that small changes in the input program will give smallish |
| + // changes in the output, which can be useful for diffing etc. |
| + String _getUnusedName(String proposedName, Set<String> usedNames) { |
| + // Try single-character names with characters that occur in the |
| + // input. |
| + for (int i = 0; i < proposedName.length; i++) { |
| + String candidate = proposedName[i]; |
| + int code = candidate.charCodeAt(0); |
| + if (code < $A) continue; |
| + if (code > $z) continue; |
| + if (code > $Z && code < $a) continue; |
| + if (!usedNames.contains(candidate)) return candidate; |
| + } |
| + |
| + int hash = _calculateHash(proposedName); |
| + // Avoid very small hashes that won't try many names. |
| + hash = hash < 1000 ? hash * 314159 : hash; |
| + |
| + // Try other n-character names based on the hash. |
|
floitsch
2012/10/25 12:58:38
Give a small description maybe mentioning that:
-
erikcorry
2012/12/06 09:38:07
Done.
|
| + for (var n = 1; n <= 3; n++) { |
| + int h = hash; |
| + while (h > 10) { |
| + var codes = <int>[_letterNumber(h)]; |
|
floitsch
2012/10/25 12:58:38
It probably doesn't matter, but you could allocate
erikcorry
2012/12/06 09:38:07
I tried it and it got uglier, so I'll leave it as
|
| + var divisor = 26; |
|
floitsch
2012/10/25 12:58:38
62.
erikcorry
2012/12/06 09:38:07
Done.
|
| + for (var i = 1; i < n; i++) { |
| + codes.add(_alphaNumericNumber(h ~/ divisor)); |
| + divisor *= 26; |
| + } |
| + final candidate = new String.fromCharCodes(codes); |
| + if (!usedNames.contains(candidate) && !jsReserved.contains(candidate)) { |
| + return candidate; |
| + } |
| + h ~/= 7; |
| + } |
| + } |
| + |
| + // If we can't find a hash based name in the three-letter space, then base |
| + // the name on a letter and a counter. |
| + proposedName = new String.fromCharCodes([_letterNumber(hash)]); |
| + var i = 0; |
| + while (usedNames.contains("$proposedName$i")) { |
| + i++; |
| + } |
| + return "$proposedName$i"; |
| + } |
| + |
| + int _calculateHash(String name) { |
| + int h = 0; |
| + for (int i = 0; i < name.length; i++) { |
| + h += name.charCodeAt(i); |
| + h &= 0xffffffff; |
| + h += h << 10; |
| + h &= 0xffffffff; |
| + h ^= h >> 6; |
| + h &= 0xffffffff; |
| + } |
| + return h; |
| + } |
| + |
| + int _letterNumber(int x) { |
| + if (x >= 52) x %= 52; |
| + if (x < 26) return $a + x; |
| + return $A + x - 26; |
| + } |
| + |
| + int _alphaNumericNumber(int x) { |
| + if (x >= 62) x %= 62; |
| + if (x < 26) return $a + x; |
| + if (x < 52) return $A + x - 26; |
| + return $0 + x - 52; |
| + } |
| + |
| +} |