| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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 | 
|  | 3 // BSD-style license that can be found in the LICENSE file. | 
|  | 4 | 
|  | 5 part of js_backend; | 
|  | 6 | 
|  | 7 /** | 
|  | 8  * Assigns JavaScript identifiers to Dart variables, class-names and members. | 
|  | 9  */ | 
|  | 10 class MinifyNamer extends Namer { | 
|  | 11   MinifyNamer(Compiler compiler) : super(compiler); | 
|  | 12 | 
|  | 13   String get isolateName => 'I'; | 
|  | 14   String get isolatePropertiesName => 'p'; | 
|  | 15   bool get shouldMinify => true; | 
|  | 16 | 
|  | 17   const ALPHABET_CHARACTERS = 52;  // a-zA-Z. | 
|  | 18   const ALPHANUMERIC_CHARACTERS = 62;  // a-zA-Z0-9. | 
|  | 19 | 
|  | 20   // You can pass an invalid identifier to this and unlike its non-minifying | 
|  | 21   // counterpart it will never return the proposedName as the new fresh name. | 
|  | 22   String getFreshName(String proposedName, Set<String> usedNames) { | 
|  | 23     var freshName = _getUnusedName(proposedName, usedNames); | 
|  | 24     usedNames.add(freshName); | 
|  | 25     return freshName; | 
|  | 26   } | 
|  | 27 | 
|  | 28   // This gets a minified name based on a hash of the proposed name.  This | 
|  | 29   // is slightly less efficient than just getting the next name in a series, | 
|  | 30   // but it means that small changes in the input program will give smallish | 
|  | 31   // changes in the output, which can be useful for diffing etc. | 
|  | 32   String _getUnusedName(String proposedName, Set<String> usedNames) { | 
|  | 33     // Try single-character names with characters that occur in the | 
|  | 34     // input. | 
|  | 35     for (int i = 0; i < proposedName.length; i++) { | 
|  | 36       String candidate = proposedName[i]; | 
|  | 37       int code = candidate.charCodeAt(0); | 
|  | 38       if (code < $A) continue; | 
|  | 39       if (code > $z) continue; | 
|  | 40       if (code > $Z && code < $a) continue; | 
|  | 41       if (!usedNames.contains(candidate)) return candidate; | 
|  | 42     } | 
|  | 43 | 
|  | 44     int hash = _calculateHash(proposedName); | 
|  | 45     // Avoid very small hashes that won't try many names. | 
|  | 46     hash = hash < 1000 ? hash * 314159 : hash;  // Yes, it's prime. | 
|  | 47 | 
|  | 48     // Try other n-character names based on the hash.  We try one to three | 
|  | 49     // character identifiers.  For each length we try around 10 different names | 
|  | 50     // in a predictable order determined by the proposed name.  This is in order | 
|  | 51     // to make the renamer stable: small changes in the input should nornally | 
|  | 52     // result in relatively small changes in the output. | 
|  | 53     for (var n = 1; n <= 3; n++) { | 
|  | 54       int h = hash; | 
|  | 55       while (h > 10) { | 
|  | 56         var codes = <int>[_letterNumber(h)]; | 
|  | 57         int h2 = h ~/ ALPHABET_CHARACTERS; | 
|  | 58         for (var i = 1; i < n; i++) { | 
|  | 59           codes.add(_alphaNumericNumber(h2)); | 
|  | 60           h2 ~/= ALPHANUMERIC_CHARACTERS; | 
|  | 61         } | 
|  | 62         final candidate = new String.fromCharCodes(codes); | 
|  | 63         if (!usedNames.contains(candidate) && !jsReserved.contains(candidate)) { | 
|  | 64           return candidate; | 
|  | 65         } | 
|  | 66         // Try again with a slightly different hash.  After around 10 turns | 
|  | 67         // around this loop h is zero and we try a longer name. | 
|  | 68         h ~/= 7; | 
|  | 69       } | 
|  | 70     } | 
|  | 71 | 
|  | 72     // If we can't find a hash based name in the three-letter space, then base | 
|  | 73     // the name on a letter and a counter. | 
|  | 74     var startLetter = new String.fromCharCodes([_letterNumber(hash)]); | 
|  | 75     var i = 0; | 
|  | 76     while (usedNames.contains("$startLetter$i")) { | 
|  | 77       i++; | 
|  | 78     } | 
|  | 79     return "$startLetter$i"; | 
|  | 80   } | 
|  | 81 | 
|  | 82   int _calculateHash(String name) { | 
|  | 83     int h = 0; | 
|  | 84     for (int i = 0; i < name.length; i++) { | 
|  | 85       h += name.charCodeAt(i); | 
|  | 86       h &= 0xffffffff; | 
|  | 87       h += h << 10; | 
|  | 88       h &= 0xffffffff; | 
|  | 89       h ^= h >> 6; | 
|  | 90       h &= 0xffffffff; | 
|  | 91     } | 
|  | 92     return h; | 
|  | 93   } | 
|  | 94 | 
|  | 95   int _letterNumber(int x) { | 
|  | 96     if (x >= ALPHABET_CHARACTERS) x %= ALPHABET_CHARACTERS; | 
|  | 97     if (x < 26) return $a + x; | 
|  | 98     return $A + x - 26; | 
|  | 99   } | 
|  | 100 | 
|  | 101   int _alphaNumericNumber(int x) { | 
|  | 102     if (x >= ALPHANUMERIC_CHARACTERS) x %= ALPHANUMERIC_CHARACTERS; | 
|  | 103     if (x < 26) return $a + x; | 
|  | 104     if (x < 52) return $A + x - 26; | 
|  | 105     return $0 + x - 52; | 
|  | 106   } | 
|  | 107 | 
|  | 108 } | 
| OLD | NEW | 
|---|