Merge pull request babel/babel-eslint#97 from hzoo/fix-templates
fix template type issues
This commit is contained in:
parent
9731e496c8
commit
730f2528dc
@ -36,7 +36,7 @@ exports.toToken = function (token) {
|
|||||||
token.type = "JSXIdentifier";
|
token.type = "JSXIdentifier";
|
||||||
} else if (type.keyword === "null") {
|
} else if (type.keyword === "null") {
|
||||||
token.type = "Null";
|
token.type = "Null";
|
||||||
} else if (type.keyword === "false" || token.keyword === "true") {
|
} else if (type.keyword === "false" || type.keyword === "true") {
|
||||||
token.type = "Boolean";
|
token.type = "Boolean";
|
||||||
} else if (type.keyword) {
|
} else if (type.keyword) {
|
||||||
token.type = "Keyword";
|
token.type = "Keyword";
|
||||||
@ -48,6 +48,11 @@ exports.toToken = function (token) {
|
|||||||
token.value = JSON.stringify(token.value);
|
token.value = JSON.stringify(token.value);
|
||||||
} else if (type === tt.regexp) {
|
} else if (type === tt.regexp) {
|
||||||
token.type = "RegularExpression";
|
token.type = "RegularExpression";
|
||||||
|
token.regex = {
|
||||||
|
pattern: token.value.pattern,
|
||||||
|
flags: token.value.flags
|
||||||
|
};
|
||||||
|
token.value = String(token.value.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
@ -73,17 +78,23 @@ function convertTemplateType(tokens) {
|
|||||||
var startingToken = 0;
|
var startingToken = 0;
|
||||||
var currentToken = 0;
|
var currentToken = 0;
|
||||||
var numBraces = 0;
|
var numBraces = 0;
|
||||||
|
var hasTemplateEnded = true;
|
||||||
|
|
||||||
|
function isBackQuote(token) {
|
||||||
|
return tokens[token].type === tt.backQuote;
|
||||||
|
}
|
||||||
|
|
||||||
function isTemplateStarter(token) {
|
function isTemplateStarter(token) {
|
||||||
return tokens[token].type === tt.backQuote ||
|
return isBackQuote(token) ||
|
||||||
tokens[token].type === tt.braceR;
|
tokens[token].type === tt.braceR;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isTemplateEnder(token) {
|
function isTemplateEnder(token) {
|
||||||
return tokens[token].type === tt.dollarBraceL ||
|
return isBackQuote(token) ||
|
||||||
tokens[token].type === tt.backQuote;
|
tokens[token].type === tt.dollarBraceL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// append the values between start and end
|
||||||
function createTemplateValue(start, end) {
|
function createTemplateValue(start, end) {
|
||||||
var value = "";
|
var value = "";
|
||||||
while (start <= end) {
|
while (start <= end) {
|
||||||
@ -97,6 +108,7 @@ function convertTemplateType(tokens) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create Template token
|
||||||
function replaceWithTemplateType(start, end) {
|
function replaceWithTemplateType(start, end) {
|
||||||
var templateToken = {
|
var templateToken = {
|
||||||
type: 'Template',
|
type: 'Template',
|
||||||
@ -107,10 +119,12 @@ function convertTemplateType(tokens) {
|
|||||||
end: tokens[end].loc.end
|
end: tokens[end].loc.end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// put new token in place of old tokens
|
||||||
tokens.splice(start, end - start + 1, templateToken);
|
tokens.splice(start, end - start + 1, templateToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkNumBraces(token) {
|
function trackNumBraces(token) {
|
||||||
if (tokens[token].type === tt.braceL) {
|
if (tokens[token].type === tt.braceL) {
|
||||||
numBraces++;
|
numBraces++;
|
||||||
} else if (tokens[token].type === tt.braceR) {
|
} else if (tokens[token].type === tt.braceR) {
|
||||||
@ -119,18 +133,30 @@ function convertTemplateType(tokens) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (startingToken < tokens.length) {
|
while (startingToken < tokens.length) {
|
||||||
|
// template start: check if ` or }
|
||||||
if (isTemplateStarter(startingToken) && numBraces === 0) {
|
if (isTemplateStarter(startingToken) && numBraces === 0) {
|
||||||
currentToken = startingToken + 1;
|
currentToken = startingToken + 1;
|
||||||
while (currentToken < tokens.length - 1 && !isTemplateEnder(currentToken)) {
|
|
||||||
checkNumBraces(currentToken);
|
// check if token after template start is "template"
|
||||||
|
if (currentToken >= tokens.length - 1 || tokens[currentToken].type !== tt.template) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// template end: find ` or ${
|
||||||
|
while (!isTemplateEnder(currentToken)) {
|
||||||
|
if (currentToken >= tokens.length - 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
currentToken++;
|
currentToken++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasTemplateEnded = isBackQuote(currentToken);
|
||||||
|
// template start and end found: create new token
|
||||||
replaceWithTemplateType(startingToken, currentToken);
|
replaceWithTemplateType(startingToken, currentToken);
|
||||||
startingToken++;
|
} else if (!hasTemplateEnded) {
|
||||||
} else {
|
trackNumBraces(startingToken);
|
||||||
checkNumBraces(startingToken);
|
|
||||||
startingToken++;
|
|
||||||
}
|
}
|
||||||
|
startingToken++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,12 @@ function assertImplementsAST(target, source, path) {
|
|||||||
|
|
||||||
function parseAndAssertSame(code) {
|
function parseAndAssertSame(code) {
|
||||||
var esAST = espree.parse(code, {
|
var esAST = espree.parse(code, {
|
||||||
|
env: {
|
||||||
|
"es6": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
ecmaFeatures: {
|
ecmaFeatures: {
|
||||||
|
blockBindings: true,
|
||||||
templateStrings: true,
|
templateStrings: true,
|
||||||
modules: true,
|
modules: true,
|
||||||
classes: true,
|
classes: true,
|
||||||
@ -103,6 +108,22 @@ describe("acorn-to-esprima", function () {
|
|||||||
it("template with nested function/object", function () {
|
it("template with nested function/object", function () {
|
||||||
parseAndAssertSame("`outer${{x: {y: 10}}}bar${`nested${function(){return 1;}}endnest`}end`");
|
parseAndAssertSame("`outer${{x: {y: 10}}}bar${`nested${function(){return 1;}}endnest`}end`");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("template with braces inside and outside of template string #96", function () {
|
||||||
|
parseAndAssertSame("if (a) { var target = `{}a:${webpackPort}{}}}}`; } else { app.use(); }");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("template also with braces #96", function () {
|
||||||
|
parseAndAssertSame(
|
||||||
|
"export default function f1() {" +
|
||||||
|
"function f2(foo) {" +
|
||||||
|
"const bar = 3;" +
|
||||||
|
"return `${foo} ${bar}`;" +
|
||||||
|
"}" +
|
||||||
|
"return f2;" +
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("simple expression", function () {
|
it("simple expression", function () {
|
||||||
@ -203,4 +224,20 @@ describe("acorn-to-esprima", function () {
|
|||||||
" */"
|
" */"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("null", function () {
|
||||||
|
parseAndAssertSame("null");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("boolean", function () {
|
||||||
|
parseAndAssertSame("if (true) {} else if (false) {}");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("regexp", function () {
|
||||||
|
parseAndAssertSame("/affix-top|affix-bottom|affix|[a-z]/");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("regexp in a template string", function () {
|
||||||
|
parseAndAssertSame("`${/\\d/.exec(\"1\")[0]}`");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -147,6 +147,4 @@ describe("verify", function () {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user