more reliable parsing of wrapped expressions

fixed #801
This commit is contained in:
Tobias Koppers 2015-02-28 00:51:15 +01:00
parent 3d153efe27
commit 3ddb26ff36
5 changed files with 33 additions and 11 deletions

View File

@ -35,7 +35,7 @@ BasicEvaluatedExpression.prototype.isIdentifier = function() {
return Object.prototype.hasOwnProperty.call(this, "identifier");
};
BasicEvaluatedExpression.prototype.isWrapped = function() {
return Object.prototype.hasOwnProperty.call(this, "prefix");
return Object.prototype.hasOwnProperty.call(this, "prefix") || Object.prototype.hasOwnProperty.call(this, "postfix");
};
BasicEvaluatedExpression.prototype.asBool = function() {
if(this.isBoolean()) return this.bool;

View File

@ -66,14 +66,14 @@ Parser.prototype.initializeEvaluating = function() {
res.setString(left.string + right.string);
} else if(right.isNumber()) {
res.setString(left.string + right.number);
} else if(right.isWrapped() && right.prefix.isString()) {
} else if(right.isWrapped() && right.prefix && right.prefix.isString()) {
res.setWrapped(
new BasicEvaluatedExpression()
.setString(left.string + right.prefix.string)
.setRange(joinRanges(left.range, right.prefix.range)),
right.postfix);
} else {
res.setWrapped(left, new BasicEvaluatedExpression().setString(""))
res.setWrapped(left, null)
}
} else if(left.isNumber()) {
if(right.isString()) {
@ -82,13 +82,13 @@ Parser.prototype.initializeEvaluating = function() {
res.setNumber(left.number + right.number);
}
} else if(left.isWrapped()) {
if(left.postfix.isString() && right.isString()) {
if(left.postfix && left.postfix.isString() && right.isString()) {
res.setWrapped(left.prefix,
new BasicEvaluatedExpression()
.setString(left.postfix.string + right.string)
.setRange(joinRanges(left.postfix.range, right.range))
);
} else if(left.postfix.isString() && right.isNumber()) {
} else if(left.postfix && left.postfix.isString() && right.isNumber()) {
res.setWrapped(left.prefix,
new BasicEvaluatedExpression()
.setString(left.postfix.string + right.number)
@ -106,7 +106,7 @@ Parser.prototype.initializeEvaluating = function() {
}
} else {
if(right.isString()) {
res.setWrapped(new BasicEvaluatedExpression().setString(""), right);
res.setWrapped(null, right);
}
}
res.setRange(expr.range);

View File

@ -5,10 +5,10 @@
var ContextDependencyHelpers = exports;
ContextDependencyHelpers.create = function(Dep, range, param, expr, options) {
if(param.isWrapped() && param.prefix.isString()) {
var prefix = param.prefix.string;
var postfix = param.postfix.isString() ? param.postfix.string : "";
var prefixRange = param.prefix.range;
if(param.isWrapped() && (param.prefix && param.prefix.isString() || param.postfix && param.postfix.isString())) {
var prefix = param.prefix && param.prefix.isString() ? param.prefix.string : "";
var postfix = param.postfix && param.postfix.isString() ? param.postfix.string : "";
var prefixRange = param.prefix && param.prefix.isString() ? param.prefix.range : null;
var valueRange = [prefixRange ? prefixRange[1] : param.range[0], param.range[1]];
var idx = prefix.lastIndexOf("/");
var context = ".";
@ -22,7 +22,7 @@ ContextDependencyHelpers.create = function(Dep, range, param, expr, options) {
postfix.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") + "$");
var dep = new Dep(context, options.wrappedContextRecursive, regExp, range, valueRange);
dep.loc = expr.loc;
dep.prepend = prefix;
dep.prepend = param.prefix && param.prefix.isString() ? prefix : null;
dep.critical = options.wrappedContextCritical && "a part of the request of a dependency is an expression";
return dep;
} else {

View File

@ -0,0 +1,15 @@
module.exports = function(arg) {
try {
var a = require(arg + ".js");
} catch(e) {}
try {
var b = require("" + arg + ".js");
} catch(e) {}
try {
var c = require("./" + arg + ".js");
} catch(e) {}
try {
var d = require("./" + arg);
} catch(e) {}
return {a: typeof a === "function", b: typeof b === "function", c: typeof c === "function", d: typeof d === "function"}
};

View File

@ -0,0 +1,7 @@
it("should emit valid code for dynamic require string with expr", function() {
var test = require("./folder/file");
test("file").should.be.eql({ a: false, b: false, c: true, d: true });
test("file.js").should.be.eql({ a: false, b: false, c: false, d: true });
test("./file").should.be.eql({ a: true, b: true, c: false, d: false });
test("./file.js").should.be.eql({ a: false, b: false, c: false, d: false });
});