diff options
Diffstat (limited to 'node_modules/webpack/lib/Parser.js')
-rw-r--r-- | node_modules/webpack/lib/Parser.js | 181 |
1 files changed, 104 insertions, 77 deletions
diff --git a/node_modules/webpack/lib/Parser.js b/node_modules/webpack/lib/Parser.js index bd81b55ab..88f9b65db 100644 --- a/node_modules/webpack/lib/Parser.js +++ b/node_modules/webpack/lib/Parser.js @@ -17,10 +17,12 @@ function joinRanges(startRange, endRange) { return [startRange[0], endRange[1]];
}
+const ECMA_VERSION = 2017;
+
const POSSIBLE_AST_OPTIONS = [{
ranges: true,
locations: true,
- ecmaVersion: 2017,
+ ecmaVersion: ECMA_VERSION,
sourceType: "module",
plugins: {
dynamicImport: true
@@ -28,7 +30,7 @@ const POSSIBLE_AST_OPTIONS = [{ }, {
ranges: true,
locations: true,
- ecmaVersion: 2017,
+ ecmaVersion: ECMA_VERSION,
sourceType: "script",
plugins: {
dynamicImport: true
@@ -212,19 +214,10 @@ class Parser extends Tapable { }
}
if(expr.argument.type === "MemberExpression") {
- let expression = expr.argument;
- let exprName = [];
- while(expression.type === "MemberExpression" && !expression.computed) {
- exprName.unshift(this.scope.renames["$" + expression.property.name] || expression.property.name);
- expression = expression.object;
- }
- if(expression.type === "Identifier") {
- exprName.unshift(this.scope.renames["$" + expression.name] || expression.name);
- if(this.scope.definitions.indexOf(name) === -1) {
- exprName = exprName.join(".");
- res = this.applyPluginsBailResult1("evaluate typeof " + exprName, expr);
- if(res !== undefined) return res;
- }
+ const exprName = this.getNameForExpression(expr.argument);
+ if(exprName && exprName.free) {
+ res = this.applyPluginsBailResult1("evaluate typeof " + exprName.name, expr);
+ if(res !== undefined) return res;
}
}
if(expr.argument.type === "FunctionExpression") {
@@ -240,6 +233,10 @@ class Parser extends Tapable { if(!argument) return;
if(argument.isBoolean()) {
return new BasicEvaluatedExpression().setBoolean(!argument.bool).setRange(expr.range);
+ } else if(argument.isTruthy()) {
+ return new BasicEvaluatedExpression().setBoolean(false).setRange(expr.range);
+ } else if(argument.isFalsy()) {
+ return new BasicEvaluatedExpression().setBoolean(true).setRange(expr.range);
} else if(argument.isString()) {
return new BasicEvaluatedExpression().setBoolean(!argument.string).setRange(expr.range);
} else if(argument.isNumber()) {
@@ -260,25 +257,23 @@ class Parser extends Tapable { return this.applyPluginsBailResult1("evaluate defined Identifier " + name, expr);
}
});
- this.plugin("evaluate MemberExpression", function(expression) {
- let expr = expression;
- let exprName = [];
- while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) {
- exprName.unshift(expr.property.name || expr.property.value);
- expr = expr.object;
+ this.plugin("evaluate ThisExpression", function(expr) {
+ const name = this.scope.renames.$this;
+ if(name) {
+ const result = this.applyPluginsBailResult1("evaluate Identifier " + name, expr);
+ if(result) return result;
+ return new BasicEvaluatedExpression().setIdentifier(name).setRange(expr.range);
}
- if(expr.type === "Identifier") {
- const name = this.scope.renames["$" + expr.name] || expr.name;
- if(this.scope.definitions.indexOf(name) === -1) {
- exprName.unshift(name);
- exprName = exprName.join(".");
- if(this.scope.definitions.indexOf(expr.name) === -1) {
- const result = this.applyPluginsBailResult1("evaluate Identifier " + exprName, expression);
- if(result) return result;
- return new BasicEvaluatedExpression().setIdentifier(exprName).setRange(expression.range);
- } else {
- return this.applyPluginsBailResult1("evaluate defined Identifier " + exprName, expression);
- }
+ });
+ this.plugin("evaluate MemberExpression", function(expression) {
+ let exprName = this.getNameForExpression(expression);
+ if(exprName) {
+ if(exprName.free) {
+ const result = this.applyPluginsBailResult1("evaluate Identifier " + exprName.name, expression);
+ if(result) return result;
+ return new BasicEvaluatedExpression().setIdentifier(exprName.name).setRange(expression.range);
+ } else {
+ return this.applyPluginsBailResult1("evaluate defined Identifier " + exprName.name, expression);
}
}
});
@@ -639,14 +634,14 @@ class Parser extends Tapable { statement.params.forEach(param => {
this.walkPattern(param);
});
- this.inScope(statement.params, function() {
+ this.inScope(statement.params, () => {
if(statement.body.type === "BlockStatement") {
this.prewalkStatement(statement.body);
this.walkStatement(statement.body);
} else {
this.walkExpression(statement.body);
}
- }.bind(this));
+ });
}
prewalkImportDeclaration(statement) {
@@ -789,10 +784,10 @@ class Parser extends Tapable { }
walkCatchClause(catchClause) {
- this.inScope([catchClause.param], function() {
+ this.inScope([catchClause.param], () => {
this.prewalkStatement(catchClause.body);
this.walkStatement(catchClause.body);
- }.bind(this));
+ });
}
prewalkVariableDeclarators(declarators) {
@@ -921,28 +916,28 @@ class Parser extends Tapable { expression.params.forEach(param => {
this.walkPattern(param);
});
- this.inScope(expression.params, function() {
+ this.inScope(expression.params, () => {
if(expression.body.type === "BlockStatement") {
this.prewalkStatement(expression.body);
this.walkStatement(expression.body);
} else {
this.walkExpression(expression.body);
}
- }.bind(this));
+ });
}
walkArrowFunctionExpression(expression) {
expression.params.forEach(param => {
this.walkPattern(param);
});
- this.inScope(expression.params, function() {
+ this.inScope(expression.params, () => {
if(expression.body.type === "BlockStatement") {
this.prewalkStatement(expression.body);
this.walkStatement(expression.body);
} else {
this.walkExpression(expression.body);
}
- }.bind(this));
+ });
}
walkSequenceExpression(expression) {
@@ -956,16 +951,9 @@ class Parser extends Tapable { walkUnaryExpression(expression) {
if(expression.operator === "typeof") {
- let expr = expression.argument;
- let exprName = [];
- while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) {
- exprName.unshift(expr.property.name || expr.property.value);
- expr = expr.object;
- }
- if(expr.type === "Identifier" && this.scope.definitions.indexOf(expr.name) === -1) {
- exprName.unshift(this.scope.renames["$" + expr.name] || expr.name);
- exprName = exprName.join(".");
- const result = this.applyPluginsBailResult1("typeof " + exprName, expression);
+ const exprName = this.getNameForExpression(expression.argument);
+ if(exprName && exprName.free) {
+ const result = this.applyPluginsBailResult1("typeof " + exprName.name, expression);
if(result === true)
return;
}
@@ -1057,19 +1045,24 @@ class Parser extends Tapable { walkCallExpression(expression) {
let result;
- function walkIIFE(functionExpression, options) {
- const params = functionExpression.params;
- const args = options.map(function(arg) {
- const renameIdentifier = this.getRenameIdentifier(arg);
- if(renameIdentifier && this.applyPluginsBailResult1("can-rename " + renameIdentifier, arg)) {
- if(!this.applyPluginsBailResult1("rename " + renameIdentifier, arg))
+ function walkIIFE(functionExpression, options, currentThis) {
+ function renameArgOrThis(argOrThis) {
+ const renameIdentifier = this.getRenameIdentifier(argOrThis);
+ if(renameIdentifier && this.applyPluginsBailResult1("can-rename " + renameIdentifier, argOrThis)) {
+ if(!this.applyPluginsBailResult1("rename " + renameIdentifier, argOrThis))
return renameIdentifier;
}
- this.walkExpression(arg);
- }, this);
+ this.walkExpression(argOrThis);
+ }
+ const params = functionExpression.params;
+ const renameThis = currentThis ? renameArgOrThis.call(this, currentThis) : null;
+ const args = options.map(renameArgOrThis, this);
this.inScope(params.filter(function(identifier, idx) {
return !args[idx];
- }), function() {
+ }), () => {
+ if(renameThis) {
+ this.scope.renames.$this = renameThis;
+ }
for(let i = 0; i < args.length; i++) {
const param = args[i];
if(!param) continue;
@@ -1081,18 +1074,17 @@ class Parser extends Tapable { this.walkStatement(functionExpression.body);
} else
this.walkExpression(functionExpression.body);
- }.bind(this));
+ });
}
if(expression.callee.type === "MemberExpression" &&
expression.callee.object.type === "FunctionExpression" &&
!expression.callee.computed &&
(["call", "bind"]).indexOf(expression.callee.property.name) >= 0 &&
expression.arguments &&
- expression.arguments.length > 1
+ expression.arguments.length > 0
) {
// (function(...) { }.call/bind(?, ...))
- walkIIFE.call(this, expression.callee.object, expression.arguments.slice(1));
- this.walkExpression(expression.arguments[0]);
+ walkIIFE.call(this, expression.callee.object, expression.arguments.slice(1), expression.arguments[0]);
} else if(expression.callee.type === "FunctionExpression" && expression.arguments) {
// (function(...) { }(...))
walkIIFE.call(this, expression.callee, expression.arguments);
@@ -1110,6 +1102,12 @@ class Parser extends Tapable { result = this.applyPluginsBailResult1("call " + callee.identifier, expression);
if(result === true)
return;
+ let identifier = callee.identifier.replace(/\.[^.]+$/, ".*");
+ if(identifier !== callee.identifier) {
+ result = this.applyPluginsBailResult1("call " + identifier, expression);
+ if(result === true)
+ return;
+ }
}
if(expression.callee)
@@ -1120,19 +1118,12 @@ class Parser extends Tapable { }
walkMemberExpression(expression) {
- let expr = expression;
- let exprName = [];
- while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) {
- exprName.unshift(expr.property.name || expr.property.value);
- expr = expr.object;
- }
- if(expr.type === "Identifier" && this.scope.definitions.indexOf(expr.name) === -1) {
- exprName.unshift(this.scope.renames["$" + expr.name] || expr.name);
- let result = this.applyPluginsBailResult1("expression " + exprName.join("."), expression);
+ const exprName = this.getNameForExpression(expression);
+ if(exprName && exprName.free) {
+ let result = this.applyPluginsBailResult1("expression " + exprName.name, expression);
if(result === true)
return;
- exprName[exprName.length - 1] = "*";
- result = this.applyPluginsBailResult1("expression " + exprName.join("."), expression);
+ result = this.applyPluginsBailResult1("expression " + exprName.nameGeneral, expression);
if(result === true)
return;
}
@@ -1158,6 +1149,8 @@ class Parser extends Tapable { renames: Object.create(oldScope.renames)
};
+ this.scope.renames.$this = undefined;
+
for(let paramIndex = 0, len = params.length; paramIndex < len; paramIndex++) {
const param = params[paramIndex];
@@ -1335,7 +1328,7 @@ class Parser extends Tapable { ast = acorn.parse(source, {
ranges: true,
locations: true,
- ecmaVersion: 2017,
+ ecmaVersion: ECMA_VERSION,
sourceType: "module",
plugins: {
dynamicImport: true
@@ -1369,7 +1362,7 @@ class Parser extends Tapable { const ast = acorn.parse("(" + source + ")", {
ranges: true,
locations: true,
- ecmaVersion: 2017,
+ ecmaVersion: ECMA_VERSION,
sourceType: "module",
plugins: {
dynamicImport: true
@@ -1399,6 +1392,40 @@ class Parser extends Tapable { return options.reduce((o, i) => Object.assign(o, i), {});
}
+ getNameForExpression(expression) {
+ let expr = expression;
+ const exprName = [];
+ while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) {
+ exprName.push(expr.computed ? expr.property.value : expr.property.name);
+ expr = expr.object;
+ }
+ let free;
+ if(expr.type === "Identifier") {
+ free = this.scope.definitions.indexOf(expr.name) === -1;
+ exprName.push(this.scope.renames["$" + expr.name] || expr.name);
+ } else if(expr.type === "ThisExpression" && this.scope.renames.$this) {
+ free = true;
+ exprName.push(this.scope.renames.$this);
+ } else if(expr.type === "ThisExpression") {
+ free = false;
+ exprName.push("this");
+ } else {
+ return null;
+ }
+ let prefix = "";
+ for(let i = exprName.length - 1; i >= 1; i--)
+ prefix += exprName[i] + ".";
+ const name = prefix + exprName[0];
+ const nameGeneral = prefix + "*";
+ return {
+ name,
+ nameGeneral,
+ free
+ };
+ }
+
}
+Parser.ECMA_VERSION = ECMA_VERSION;
+
module.exports = Parser;
|