Skip to content

Commit da5c735

Browse files
author
Diogo Franco (Kovensky)
committed
Add implementation
1 parent 52d8fbc commit da5c735

File tree

4 files changed

+78
-9
lines changed

4 files changed

+78
-9
lines changed

lib/BasicEvaluatedExpression.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ BasicEvaluatedExpression.prototype.isIdentifier = function() {
3737
BasicEvaluatedExpression.prototype.isWrapped = function() {
3838
return Object.prototype.hasOwnProperty.call(this, "prefix") || Object.prototype.hasOwnProperty.call(this, "postfix");
3939
};
40+
BasicEvaluatedExpression.prototype.isTemplateString = function() {
41+
return Object.prototype.hasOwnProperty.call(this, "quasis");
42+
}
4043
BasicEvaluatedExpression.prototype.asBool = function() {
4144
if(this.isBoolean()) return this.bool;
4245
else if(this.isNull()) return false;
@@ -46,6 +49,13 @@ BasicEvaluatedExpression.prototype.asBool = function() {
4649
else if(this.isArray()) return true;
4750
else if(this.isConstArray()) return true;
4851
else if(this.isWrapped()) return this.prefix && this.prefix.asBool() || this.postfix && this.postfix.asBool() ? true : undefined;
52+
else if(this.isTemplateString()) {
53+
if (this.quasis.length === 1) return this.quasis[0].asBool();
54+
for (var i = 0; i < this.quasis.length; i++) {
55+
if (this.quasis[i].asBool()) return true;
56+
}
57+
// can't tell if string will be empty without executing
58+
}
4959
return undefined;
5060
};
5161
BasicEvaluatedExpression.prototype.set = function(value) {
@@ -127,6 +137,13 @@ BasicEvaluatedExpression.prototype.setArray = function(array) {
127137
this.array = array;
128138
return this;
129139
};
140+
BasicEvaluatedExpression.prototype.setTemplateString = function(quasis) {
141+
if (quasis === null)
142+
delete this.quasis;
143+
else
144+
this.quasis = quasis;
145+
return this;
146+
}
130147
BasicEvaluatedExpression.prototype.addOptions = function(options) {
131148
if(!this.options) this.options = [];
132149
options.forEach(function(item) {

lib/Parser.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,29 @@ Parser.prototype.initializeEvaluating = function() {
297297
}
298298
return new BasicEvaluatedExpression().setString(result).setRange(expr.range);
299299
});
300+
this.plugin("evaluate TemplateLiteral", function(node) {
301+
var i, quasis = node.quasis, exprs = [];
302+
for (i = 0; i < quasis.length; i++) {
303+
exprs.push(this.evaluateExpression(quasis[i]).cooked);
304+
// possible improvement: evaluate node.expressions[i-1]
305+
// and append to previous quasis if has a set value
306+
}
307+
return new BasicEvaluatedExpression().setTemplateString(exprs).setRange(node.range);
308+
});
309+
this.plugin("evaluate TaggedTemplateExpression", function(node) {
310+
if (this.evaluateExpression(node.tag).identifier !== 'String.raw') return;
311+
var i, quasis = node.quasi.quasis, exprs = [];
312+
for (i = 0; i < quasis.length; i++) {
313+
exprs.push(this.evaluateExpression(quasis[i]).raw);
314+
}
315+
return new BasicEvaluatedExpression().setTemplateString(exprs).setRange(node.range);
316+
});
317+
this.plugin("evaluate TemplateElement", function(node) {
318+
return {
319+
raw: new BasicEvaluatedExpression().setString(node.value.raw).setRange(node.range),
320+
cooked: new BasicEvaluatedExpression().setString(node.value.cooked).setRange(node.range)
321+
};
322+
})
300323
}, this);
301324
this.plugin("evaluate CallExpression .split", function(expr, param) {
302325
if(!param.isString()) return;

lib/dependencies/ContextDependencyHelpers.js

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,43 @@
55
var ContextDependencyHelpers = exports;
66

77
ContextDependencyHelpers.create = function(Dep, range, param, expr, options) {
8-
var dep;
9-
if(param.isWrapped() && (param.prefix && param.prefix.isString() || param.postfix && param.postfix.isString())) {
10-
var prefix = param.prefix && param.prefix.isString() ? param.prefix.string : "";
11-
var postfix = param.postfix && param.postfix.isString() ? param.postfix.string : "";
12-
var prefixRange = param.prefix && param.prefix.isString() ? param.prefix.range : null;
13-
var valueRange = [prefixRange ? prefixRange[1] : param.range[0], param.range[1]];
14-
var idx = prefix.lastIndexOf("/");
15-
var context = ".";
8+
var dep, prefix, postfix, prefixRange, valueRange, idx, context, regExp;
9+
if(param.isTemplateString()) {
10+
prefix = param.quasis[0].string;
11+
postfix = param.quasis.length > 1 ? param.quasis[param.quasis.length - 1].string : "";
12+
prefixRange = [param.quasis[0].range[0], param.quasis[0].range[1]];
13+
valueRange = param.range;
14+
idx = prefix.lastIndexOf("/");
15+
context = ".";
1616
if(idx >= 0) {
1717
context = prefix.substr(0, idx);
1818
prefix = "." + prefix.substr(idx);
1919
}
20-
var regExp = new RegExp("^" +
20+
// If there are more than two quasis, maybe the generated RegExp can be more precise?
21+
regExp = new RegExp("^" +
22+
prefix.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") +
23+
options.wrappedContextRegExp.source +
24+
postfix.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") + "$");
25+
dep = new Dep(context, options.wrappedContextRecursive, regExp, range, valueRange);
26+
dep.loc = expr.loc;
27+
dep.replaces = [{
28+
range: prefixRange,
29+
value: prefix
30+
}];
31+
dep.critical = options.wrappedContextCritical && "a part of the request of a dependency is an expression";
32+
return dep;
33+
} else if(param.isWrapped() && (param.prefix && param.prefix.isString() || param.postfix && param.postfix.isString())) {
34+
prefix = param.prefix && param.prefix.isString() ? param.prefix.string : "";
35+
postfix = param.postfix && param.postfix.isString() ? param.postfix.string : "";
36+
prefixRange = param.prefix && param.prefix.isString() ? param.prefix.range : null;
37+
valueRange = [prefixRange ? prefixRange[1] : param.range[0], param.range[1]];
38+
idx = prefix.lastIndexOf("/");
39+
context = ".";
40+
if(idx >= 0) {
41+
context = prefix.substr(0, idx);
42+
prefix = "." + prefix.substr(idx);
43+
}
44+
regExp = new RegExp("^" +
2145
prefix.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") +
2246
options.wrappedContextRegExp.source +
2347
postfix.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") + "$");

lib/dependencies/ContextDependencyTemplateAsRequireCall.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ ContextDependencyTemplateAsRequireCall.prototype.apply = function(dep, source, o
1212
var isAsync = dep.module && dep.module.async;
1313
if(dep.module && (isAsync || containsDeps)) {
1414
if(dep.valueRange) {
15+
if(Array.isArray(dep.replaces))
16+
for(var i = 0; i < dep.replaces.length; i++) {
17+
var rep = dep.replaces[i];
18+
source.replace(rep.range[0], rep.range[1] - 1, rep.value)
19+
}
1520
source.replace(dep.valueRange[1], dep.range[1] - 1, ")");
1621
source.replace(dep.range[0], dep.valueRange[0] - 1, "__webpack_require__(" + comment + JSON.stringify(dep.module.id) + ")(" + (typeof dep.prepend === "string" ? JSON.stringify(dep.prepend) : "") + "");
1722
} else {

0 commit comments

Comments
 (0)