-
-
Notifications
You must be signed in to change notification settings - Fork 374
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support mangle.nth_identifer to customize base54 behavior (#1038)
* Support nth_identifier option to customize base54 * Ensure base54 is operational immediately
- Loading branch information
1 parent
75df7e0
commit f4a3ca4
Showing
9 changed files
with
150 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -667,8 +667,9 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init) { | |
|
||
function next_mangled(scope, options) { | ||
var ext = scope.enclosed; | ||
var nth_identifier = options.nth_identifier; | ||
out: while (true) { | ||
var m = base54(++scope.cname); | ||
var m = nth_identifier.get(++scope.cname); | ||
if (ALL_RESERVED_WORDS.has(m)) continue; // skip over "do" | ||
|
||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not | ||
|
@@ -744,6 +745,7 @@ AST_Symbol.DEFMETHOD("global", function() { | |
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) { | ||
options = defaults(options, { | ||
eval : false, | ||
nth_identifier : base54, | ||
ie8 : false, | ||
keep_classnames: false, | ||
keep_fnames : false, | ||
|
@@ -765,6 +767,7 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) { | |
|
||
AST_Toplevel.DEFMETHOD("mangle_names", function(options) { | ||
options = this._default_mangler_options(options); | ||
var nth_identifier = options.nth_identifier; | ||
|
||
// We only need to mangle declaration nodes. Special logic wired | ||
// into the code generator will display the mangled name if it's | ||
|
@@ -816,7 +819,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) { | |
if (node instanceof AST_Label) { | ||
let name; | ||
do { | ||
name = base54(++lname); | ||
name = nth_identifier.get(++lname); | ||
} while (ALL_RESERVED_WORDS.has(name)); | ||
node.mangled_name = name; | ||
return true; | ||
|
@@ -878,9 +881,12 @@ AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) { | |
}); | ||
|
||
AST_Toplevel.DEFMETHOD("expand_names", function(options) { | ||
base54.reset(); | ||
base54.sort(); | ||
options = this._default_mangler_options(options); | ||
var nth_identifier = options.nth_identifier; | ||
if (nth_identifier.reset && nth_identifier.sort) { | ||
nth_identifier.reset(); | ||
nth_identifier.sort(); | ||
} | ||
var avoid = this.find_colliding_names(options); | ||
var cname = 0; | ||
this.globals.forEach(rename); | ||
|
@@ -892,7 +898,7 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) { | |
function next_name() { | ||
var name; | ||
do { | ||
name = base54(cname++); | ||
name = nth_identifier.get(cname++); | ||
} while (avoid.has(name) || ALL_RESERVED_WORDS.has(name)); | ||
return name; | ||
} | ||
|
@@ -919,30 +925,37 @@ AST_Sequence.DEFMETHOD("tail_node", function() { | |
|
||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) { | ||
options = this._default_mangler_options(options); | ||
var nth_identifier = options.nth_identifier; | ||
if (!nth_identifier.reset || !nth_identifier.consider || !nth_identifier.sort) { | ||
// If the identifier mangler is invariant, skip computing character frequency. | ||
return; | ||
} | ||
nth_identifier.reset(); | ||
|
||
try { | ||
AST_Node.prototype.print = function(stream, force_parens) { | ||
this._print(stream, force_parens); | ||
if (this instanceof AST_Symbol && !this.unmangleable(options)) { | ||
base54.consider(this.name, -1); | ||
nth_identifier.consider(this.name, -1); | ||
} else if (options.properties) { | ||
if (this instanceof AST_DotHash) { | ||
base54.consider("#" + this.property, -1); | ||
nth_identifier.consider("#" + this.property, -1); | ||
} else if (this instanceof AST_Dot) { | ||
base54.consider(this.property, -1); | ||
nth_identifier.consider(this.property, -1); | ||
} else if (this instanceof AST_Sub) { | ||
skip_string(this.property); | ||
} | ||
} | ||
}; | ||
base54.consider(this.print_to_string(), 1); | ||
nth_identifier.consider(this.print_to_string(), 1); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
jridgewell
Collaborator
|
||
} finally { | ||
AST_Node.prototype.print = AST_Node.prototype._print; | ||
} | ||
base54.sort(); | ||
nth_identifier.sort(); | ||
|
||
function skip_string(node) { | ||
if (node instanceof AST_String) { | ||
base54.consider(node.value, -1); | ||
nth_identifier.consider(node.value, -1); | ||
} else if (node instanceof AST_Conditional) { | ||
skip_string(node.consequent); | ||
skip_string(node.alternative); | ||
|
@@ -966,19 +979,20 @@ const base54 = (() => { | |
frequency.set(ch, 0); | ||
}); | ||
} | ||
base54.consider = function(str, delta) { | ||
function consider(str, delta) { | ||
for (var i = str.length; --i >= 0;) { | ||
frequency.set(str[i], frequency.get(str[i]) + delta); | ||
} | ||
}; | ||
} | ||
function compare(a, b) { | ||
return frequency.get(b) - frequency.get(a); | ||
} | ||
base54.sort = function() { | ||
function sort() { | ||
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare)); | ||
}; | ||
base54.reset = reset; | ||
} | ||
// Ensure this is in a usable initial state. | ||
reset(); | ||
sort(); | ||
function base54(num) { | ||
var ret = "", base = 54; | ||
num++; | ||
|
@@ -990,7 +1004,13 @@ const base54 = (() => { | |
} while (num > 0); | ||
return ret; | ||
} | ||
return base54; | ||
|
||
return { | ||
get: base54, | ||
consider, | ||
reset, | ||
sort | ||
}; | ||
})(); | ||
|
||
export { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Why does this line iterate over all characters in the (compressed but not mangled) source code? I think it will include too many irrelevant characters, like keywords, string values and comments.