Merge 1aa26cdef1 into ee6c9fabb7
This commit is contained in:
commit
319a2461b8
12
lib/parse.js
12
lib/parse.js
|
|
@ -46,14 +46,16 @@
|
|||
|
||||
var KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with';
|
||||
var KEYWORDS_ATOM = 'false null true';
|
||||
var RESERVED_WORDS = 'abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield'
|
||||
+ " " + KEYWORDS_ATOM + " " + KEYWORDS;
|
||||
var RESERVED_WORDS = 'abstract boolean byte char class double enum export extends final float goto import int long native short super synchronized this throws transient volatile yield'
|
||||
+ " " + KEYWORDS_ATOM + " " + KEYWORDS; // 'yield' is reserved in Firefox even outside strict mode.
|
||||
var KEYWORDS_BEFORE_EXPRESSION = 'return new delete throw else case';
|
||||
var RESERVED_WORDS_STRICT_ONLY = 'implements interface let package private protected public static';
|
||||
|
||||
KEYWORDS = makePredicate(KEYWORDS);
|
||||
RESERVED_WORDS = makePredicate(RESERVED_WORDS);
|
||||
KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION);
|
||||
KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM);
|
||||
RESERVED_WORDS_STRICT_ONLY = makePredicate(RESERVED_WORDS_STRICT_ONLY);
|
||||
|
||||
var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^"));
|
||||
|
||||
|
|
@ -152,8 +154,10 @@ function is_unicode_connector_punctuation(ch) {
|
|||
return UNICODE.connector_punctuation.test(ch);
|
||||
};
|
||||
|
||||
function is_identifier(name) {
|
||||
return !RESERVED_WORDS(name) && /^[a-z_$][a-z0-9_$]*$/i.test(name);
|
||||
function is_identifier(name, strict_mode) {
|
||||
return !RESERVED_WORDS(name)
|
||||
&& /^[a-z_$][a-z0-9_$]*$/i.test(name)
|
||||
&& (!strict_mode || !RESERVED_WORDS_STRICT_ONLY(name));
|
||||
};
|
||||
|
||||
function is_identifier_start(code) {
|
||||
|
|
|
|||
|
|
@ -134,6 +134,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||
s.uses_with = true;
|
||||
return;
|
||||
}
|
||||
if (node instanceof AST_Directive) {
|
||||
scope.directives.push(node.value);
|
||||
return;
|
||||
}
|
||||
if (node instanceof AST_Symbol) {
|
||||
node.scope = scope;
|
||||
}
|
||||
|
|
@ -237,6 +241,7 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
|||
this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes
|
||||
this.cname = -1; // the current index for mangling functions/variables
|
||||
this.nesting = nesting; // the nesting level of this scope (0 means toplevel)
|
||||
this.directives = []; // a list of directives like "use strict" present in this scope
|
||||
});
|
||||
|
||||
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||
|
|
@ -287,7 +292,7 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
|
|||
var ext = this.enclosed;
|
||||
out: while (true) {
|
||||
var m = base54(++this.cname);
|
||||
if (!is_identifier(m)) continue; // skip over "do"
|
||||
if (!is_identifier(m, this.directives.indexOf('use strict') >= 0)) continue; // skip over "do"
|
||||
|
||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||
// shadow a name excepted from mangling.
|
||||
|
|
|
|||
98
test/compress/strict-mode.js
Normal file
98
test/compress/strict-mode.js
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
keep_non_reserved_in_non_strict_mode: {
|
||||
input: {
|
||||
function outer() {
|
||||
var implements = 1;
|
||||
var interface = 1;
|
||||
var let = 1;
|
||||
var package = 1;
|
||||
var private = 1;
|
||||
var protected = 1;
|
||||
var public = 1;
|
||||
var static = 1;
|
||||
|
||||
function inner() {
|
||||
implements++;
|
||||
interface++;
|
||||
let++;
|
||||
package++;
|
||||
private++;
|
||||
protected++;
|
||||
public++;
|
||||
static++;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function outer() {
|
||||
var implements = 1;
|
||||
var interface = 1;
|
||||
var let = 1;
|
||||
var package = 1;
|
||||
var private = 1;
|
||||
var protected = 1;
|
||||
var public = 1;
|
||||
var static = 1;
|
||||
|
||||
function inner() {
|
||||
implements++;
|
||||
interface++;
|
||||
let++;
|
||||
package++;
|
||||
private++;
|
||||
protected++;
|
||||
public++;
|
||||
static++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mangle_non_reserved_in_non_strict_mode: {
|
||||
mangle = {}
|
||||
input: {
|
||||
function outer() {
|
||||
var implements = 1;
|
||||
var interface = 1;
|
||||
var let = 1;
|
||||
var package = 1;
|
||||
var private = 1;
|
||||
var protected = 1;
|
||||
var public = 1;
|
||||
var static = 1;
|
||||
|
||||
function inner() {
|
||||
implements++;
|
||||
interface++;
|
||||
let++;
|
||||
package++;
|
||||
private++;
|
||||
protected++;
|
||||
public++;
|
||||
static++;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function outer() {
|
||||
var r=1;
|
||||
var a=1;
|
||||
var v=1;
|
||||
var n=1;
|
||||
var o=1;
|
||||
var t=1;
|
||||
var u=1;
|
||||
var c=1;
|
||||
function f() {
|
||||
r++;
|
||||
a++;
|
||||
v++;
|
||||
n++;
|
||||
o++;
|
||||
t++;
|
||||
u++;
|
||||
c++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
77
test/strict-mode-mangler.js
Normal file
77
test/strict-mode-mangler.js
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
var UglifyJS = require("..");
|
||||
var assert = require("assert");
|
||||
|
||||
var alphabet = "abcdefghijklmnop".split("");
|
||||
var perms = [];
|
||||
var linesOfCode = [];
|
||||
var startTime = new Date().getTime();
|
||||
|
||||
console.log("--- Strict mode mangling tests");
|
||||
|
||||
function permute(text) {
|
||||
perms.push(text);
|
||||
if(text.length < 4) {
|
||||
for(var i = 0; i < alphabet.length; i++) {
|
||||
permute(text + alphabet[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
permute("");
|
||||
|
||||
var permuteTime = new Date().getTime() - startTime;
|
||||
|
||||
console.log(" - Generated perms in " + permuteTime + "ms")
|
||||
console.log(" - Testing with " + perms.length + " identifiers");
|
||||
console.log(" - Mangling (this will take some time)...");
|
||||
|
||||
function getCode(withStrictMode) {
|
||||
|
||||
linesOfCode = " function outer() {\n";
|
||||
if (!!withStrictMode) {
|
||||
linesOfCode += " \"use strict\";\n";
|
||||
}
|
||||
for (var i in perms) {
|
||||
linesOfCode += " var _" + perms[i] + " = 1;\n"
|
||||
}
|
||||
linesOfCode += " function inner() {\n";
|
||||
for (var i in perms) {
|
||||
linesOfCode += " _" + perms[i] + "++;\n";
|
||||
}
|
||||
linesOfCode += " }\n";
|
||||
linesOfCode += " }\n";
|
||||
|
||||
return linesOfCode;
|
||||
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
|
||||
var startManglingTime = new Date().getTime();
|
||||
var mangled_code = mangle(getCode(false));
|
||||
|
||||
console.log(" - Found 'var let' at char: " + mangled_code.indexOf('var let'));
|
||||
console.log(" - Mangled code with no strict mode in " + Math.floor((new Date().getTime() - startManglingTime)/ 1000) + "s");
|
||||
assert(mangled_code.indexOf('var let') >= 0, "No 'var let' produced in the mangled code outside strict mode.");
|
||||
|
||||
startManglingTime = new Date().getTime();
|
||||
var mangled_strict_code = mangle(getCode(true));
|
||||
console.log(" - This should be -1: " + mangled_strict_code.indexOf('var let'));
|
||||
console.log(" - Mangled code with strict mode in " + Math.floor((new Date().getTime() - startManglingTime)/ 1000) + "s");
|
||||
assert(mangled_strict_code.indexOf('var let') === -1, "A 'var let' statement was produced inside strict mode.");
|
||||
|
||||
}
|
||||
|
||||
function mangle(js) {
|
||||
var stream = UglifyJS.OutputStream();
|
||||
var parsed = UglifyJS.parse(js);
|
||||
parsed.figure_out_scope();
|
||||
parsed.mangle_names();
|
||||
parsed.print(stream);
|
||||
return stream.toString();
|
||||
}
|
||||
|
||||
// Run standalone
|
||||
if (module.parent === null) {
|
||||
module.exports();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user