parent
dce22ce5f6
commit
511862c4ee
@ -0,0 +1,57 @@
|
|||||||
|
// comment fixes
|
||||||
|
module.exports = function (ast, comments, tokens) {
|
||||||
|
if (comments.length) {
|
||||||
|
var firstComment = comments[0];
|
||||||
|
var lastComment = comments[comments.length - 1];
|
||||||
|
// fixup program start
|
||||||
|
if (!tokens.length) {
|
||||||
|
// if no tokens, the program starts at the end of the last comment
|
||||||
|
ast.start = lastComment.end;
|
||||||
|
ast.loc.start.line = lastComment.loc.end.line;
|
||||||
|
ast.loc.start.column = lastComment.loc.end.column;
|
||||||
|
|
||||||
|
if (ast.leadingComments === null && ast.innerComments.length) {
|
||||||
|
ast.leadingComments = ast.innerComments;
|
||||||
|
}
|
||||||
|
} else if (firstComment.start < tokens[0].start) {
|
||||||
|
// if there are comments before the first token, the program starts at the first token
|
||||||
|
var token = tokens[0];
|
||||||
|
// ast.start = token.start;
|
||||||
|
// ast.loc.start.line = token.loc.start.line;
|
||||||
|
// ast.loc.start.column = token.loc.start.column;
|
||||||
|
|
||||||
|
// estraverse do not put leading comments on first node when the comment
|
||||||
|
// appear before the first token
|
||||||
|
if (ast.body.length) {
|
||||||
|
var node = ast.body[0];
|
||||||
|
node.leadingComments = [];
|
||||||
|
var firstTokenStart = token.start;
|
||||||
|
var len = comments.length;
|
||||||
|
for (var i = 0; i < len && comments[i].start < firstTokenStart; i++) {
|
||||||
|
node.leadingComments.push(comments[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fixup program end
|
||||||
|
if (tokens.length) {
|
||||||
|
var lastToken = tokens[tokens.length - 1];
|
||||||
|
if (lastComment.end > lastToken.end) {
|
||||||
|
// If there is a comment after the last token, the program ends at the
|
||||||
|
// last token and not the comment
|
||||||
|
// ast.end = lastToken.end;
|
||||||
|
ast.range[1] = lastToken.end;
|
||||||
|
ast.loc.end.line = lastToken.loc.end.line;
|
||||||
|
ast.loc.end.column = lastToken.loc.end.column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!tokens.length) {
|
||||||
|
ast.loc.start.line = 1;
|
||||||
|
ast.loc.end.line = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ast.body && ast.body.length > 0) {
|
||||||
|
ast.loc.start.line = ast.body[0].loc.start.line;
|
||||||
|
ast.range[0] = ast.body[0].start;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
module.exports = function (tokens, tt) {
|
||||||
|
var startingToken = 0;
|
||||||
|
var currentToken = 0;
|
||||||
|
var numBraces = 0; // track use of {}
|
||||||
|
var numBackQuotes = 0; // track number of nested templates
|
||||||
|
|
||||||
|
function isBackQuote(token) {
|
||||||
|
return tokens[token].type === tt.backQuote;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isTemplateStarter(token) {
|
||||||
|
return isBackQuote(token) ||
|
||||||
|
// only can be a template starter when in a template already
|
||||||
|
tokens[token].type === tt.braceR && numBackQuotes > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isTemplateEnder(token) {
|
||||||
|
return isBackQuote(token) ||
|
||||||
|
tokens[token].type === tt.dollarBraceL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// append the values between start and end
|
||||||
|
function createTemplateValue(start, end) {
|
||||||
|
var value = "";
|
||||||
|
while (start <= end) {
|
||||||
|
if (tokens[start].value) {
|
||||||
|
value += tokens[start].value;
|
||||||
|
} else if (tokens[start].type !== tt.template) {
|
||||||
|
value += tokens[start].type.label;
|
||||||
|
}
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create Template token
|
||||||
|
function replaceWithTemplateType(start, end) {
|
||||||
|
var templateToken = {
|
||||||
|
type: "Template",
|
||||||
|
value: createTemplateValue(start, end),
|
||||||
|
start: tokens[start].start,
|
||||||
|
end: tokens[end].end,
|
||||||
|
loc: {
|
||||||
|
start: tokens[start].loc.start,
|
||||||
|
end: tokens[end].loc.end
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// put new token in place of old tokens
|
||||||
|
tokens.splice(start, end - start + 1, templateToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
function trackNumBraces(token) {
|
||||||
|
if (tokens[token].type === tt.braceL) {
|
||||||
|
numBraces++;
|
||||||
|
} else if (tokens[token].type === tt.braceR) {
|
||||||
|
numBraces--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (startingToken < tokens.length) {
|
||||||
|
// template start: check if ` or }
|
||||||
|
if (isTemplateStarter(startingToken) && numBraces === 0) {
|
||||||
|
if (isBackQuote(startingToken)) {
|
||||||
|
numBackQuotes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentToken = startingToken + 1;
|
||||||
|
|
||||||
|
// 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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBackQuote(currentToken)) {
|
||||||
|
numBackQuotes--;
|
||||||
|
}
|
||||||
|
// template start and end found: create new token
|
||||||
|
replaceWithTemplateType(startingToken, currentToken);
|
||||||
|
} else if (numBackQuotes > 0) {
|
||||||
|
trackNumBraces(startingToken);
|
||||||
|
}
|
||||||
|
startingToken++;
|
||||||
|
}
|
||||||
|
}
|
||||||
20
eslint/babel-eslint-parser/babylon-to-espree/index.js
Normal file
20
eslint/babel-eslint-parser/babylon-to-espree/index.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
exports.attachComments = require("./attachComments");
|
||||||
|
|
||||||
|
exports.toTokens = require("./toTokens");
|
||||||
|
exports.toAST = require("./toAST");
|
||||||
|
|
||||||
|
exports.convertComments = function (comments) {
|
||||||
|
for (var i = 0; i < comments.length; i++) {
|
||||||
|
var comment = comments[i];
|
||||||
|
if (comment.type === "CommentBlock") {
|
||||||
|
comment.type = "Block";
|
||||||
|
} else if (comment.type === "CommentLine") {
|
||||||
|
comment.type = "Line";
|
||||||
|
}
|
||||||
|
// sometimes comments don't get ranges computed,
|
||||||
|
// even with options.ranges === true
|
||||||
|
if (!comment.range) {
|
||||||
|
comment.range = [comment.start, comment.end];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
272
eslint/babel-eslint-parser/babylon-to-espree/toAST.js
Normal file
272
eslint/babel-eslint-parser/babylon-to-espree/toAST.js
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
var source;
|
||||||
|
|
||||||
|
module.exports = function (ast, traverse, code) {
|
||||||
|
source = code;
|
||||||
|
ast.range = [ast.start, ast.end];
|
||||||
|
traverse(ast, astTransformVisitor);
|
||||||
|
};
|
||||||
|
|
||||||
|
function changeToLiteral(node) {
|
||||||
|
node.type = "Literal";
|
||||||
|
if (!node.raw) {
|
||||||
|
if (node.extra && node.extra.raw) {
|
||||||
|
node.raw = node.extra.raw;
|
||||||
|
} else {
|
||||||
|
node.raw = source.slice(node.start, node.end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var astTransformVisitor = {
|
||||||
|
noScope: true,
|
||||||
|
enter: function (path) {
|
||||||
|
var node = path.node;
|
||||||
|
|
||||||
|
node.range = [node.start, node.end];
|
||||||
|
|
||||||
|
// private var to track original node type
|
||||||
|
node._babelType = node.type;
|
||||||
|
|
||||||
|
if (node.innerComments) {
|
||||||
|
node.trailingComments = node.innerComments;
|
||||||
|
delete node.innerComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.trailingComments) {
|
||||||
|
for (var i = 0; i < node.trailingComments.length; i++) {
|
||||||
|
var comment = node.trailingComments[i];
|
||||||
|
if (comment.type === "CommentLine") {
|
||||||
|
comment.type = "Line";
|
||||||
|
} else if (comment.type === "CommentBlock") {
|
||||||
|
comment.type = "Block";
|
||||||
|
}
|
||||||
|
comment.range = [comment.start, comment.end];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.leadingComments) {
|
||||||
|
for (var i = 0; i < node.leadingComments.length; i++) {
|
||||||
|
var comment = node.leadingComments[i];
|
||||||
|
if (comment.type === "CommentLine") {
|
||||||
|
comment.type = "Line";
|
||||||
|
} else if (comment.type === "CommentBlock") {
|
||||||
|
comment.type = "Block";
|
||||||
|
}
|
||||||
|
comment.range = [comment.start, comment.end];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// make '_paths' non-enumerable (babel-eslint #200)
|
||||||
|
Object.defineProperty(node, "_paths", { value: node._paths, writable: true });
|
||||||
|
},
|
||||||
|
exit: function (path) {
|
||||||
|
var node = path.node;
|
||||||
|
|
||||||
|
[
|
||||||
|
fixDirectives,
|
||||||
|
].forEach(function (fixer) {
|
||||||
|
fixer(path);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (path.isJSXText()) {
|
||||||
|
node.type = "Literal";
|
||||||
|
node.raw = node.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isNumericLiteral() ||
|
||||||
|
path.isStringLiteral()) {
|
||||||
|
changeToLiteral(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isBooleanLiteral()) {
|
||||||
|
node.type = "Literal";
|
||||||
|
node.raw = String(node.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isNullLiteral()) {
|
||||||
|
node.type = "Literal";
|
||||||
|
node.raw = "null";
|
||||||
|
node.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isRegExpLiteral()) {
|
||||||
|
node.type = "Literal";
|
||||||
|
node.raw = node.extra.raw;
|
||||||
|
node.value = {};
|
||||||
|
node.regex = {
|
||||||
|
pattern: node.pattern,
|
||||||
|
flags: node.flags
|
||||||
|
};
|
||||||
|
delete node.extra;
|
||||||
|
delete node.pattern;
|
||||||
|
delete node.flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isObjectProperty()) {
|
||||||
|
node.type = "Property";
|
||||||
|
node.kind = "init";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isClassMethod() || path.isObjectMethod()) {
|
||||||
|
var code = source.slice(node.key.end, node.body.start);
|
||||||
|
var offset = code.indexOf("(");
|
||||||
|
|
||||||
|
node.value = {
|
||||||
|
type: "FunctionExpression",
|
||||||
|
id: node.id,
|
||||||
|
params: node.params,
|
||||||
|
body: node.body,
|
||||||
|
async: node.async,
|
||||||
|
generator: node.generator,
|
||||||
|
expression: node.expression,
|
||||||
|
defaults: [], // basic support - TODO: remove (old esprima)
|
||||||
|
loc: {
|
||||||
|
start: {
|
||||||
|
line: node.key.loc.start.line,
|
||||||
|
column: node.key.loc.end.column + offset // a[() {]
|
||||||
|
},
|
||||||
|
end: node.body.loc.end
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// [asdf]() {
|
||||||
|
node.value.range = [node.key.end + offset, node.body.end];
|
||||||
|
|
||||||
|
node.value.start = node.value.range && node.value.range[0] || node.value.loc.start.column;
|
||||||
|
node.value.end = node.value.range && node.value.range[1] || node.value.loc.end.column;
|
||||||
|
|
||||||
|
if (node.returnType) {
|
||||||
|
node.value.returnType = node.returnType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.typeParameters) {
|
||||||
|
node.value.typeParameters = node.typeParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isClassMethod()) {
|
||||||
|
node.type = "MethodDefinition";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isObjectMethod()) {
|
||||||
|
node.type = "Property";
|
||||||
|
if (node.kind === "method") {
|
||||||
|
node.kind = "init";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete node.body;
|
||||||
|
delete node.id;
|
||||||
|
delete node.async;
|
||||||
|
delete node.generator;
|
||||||
|
delete node.expression;
|
||||||
|
delete node.params;
|
||||||
|
delete node.returnType;
|
||||||
|
delete node.typeParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isRestProperty() || path.isSpreadProperty()) {
|
||||||
|
node.type = "Experimental" + node.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// flow: prevent "no-undef"
|
||||||
|
// for "Component" in: "let x: React.Component"
|
||||||
|
if (path.isQualifiedTypeIdentifier()) {
|
||||||
|
delete node.id;
|
||||||
|
}
|
||||||
|
// for "b" in: "var a: { b: Foo }"
|
||||||
|
if (path.isObjectTypeProperty()) {
|
||||||
|
delete node.key;
|
||||||
|
}
|
||||||
|
// for "indexer" in: "var a: {[indexer: string]: number}"
|
||||||
|
if (path.isObjectTypeIndexer()) {
|
||||||
|
delete node.id;
|
||||||
|
}
|
||||||
|
// for "param" in: "var a: { func(param: Foo): Bar };"
|
||||||
|
if (path.isFunctionTypeParam()) {
|
||||||
|
delete node.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// modules
|
||||||
|
|
||||||
|
if (path.isImportDeclaration()) {
|
||||||
|
delete node.isType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isExportDeclaration()) {
|
||||||
|
var declar = path.get("declaration");
|
||||||
|
if (declar.isClassExpression()) {
|
||||||
|
node.declaration.type = "ClassDeclaration";
|
||||||
|
} else if (declar.isFunctionExpression()) {
|
||||||
|
node.declaration.type = "FunctionDeclaration";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove class property keys (or patch in escope)
|
||||||
|
if (path.isClassProperty()) {
|
||||||
|
delete node.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// async function as generator
|
||||||
|
if (path.isFunction()) {
|
||||||
|
if (node.async) node.generator = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove (old esprima)
|
||||||
|
if (path.isFunction()) {
|
||||||
|
if (!node.defaults) {
|
||||||
|
node.defaults = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// await transform to yield
|
||||||
|
if (path.isAwaitExpression()) {
|
||||||
|
node.type = "YieldExpression";
|
||||||
|
node.delegate = node.all;
|
||||||
|
delete node.all;
|
||||||
|
}
|
||||||
|
|
||||||
|
// template string range fixes
|
||||||
|
if (path.isTemplateLiteral()) {
|
||||||
|
node.quasis.forEach(function (q) {
|
||||||
|
q.range[0] -= 1;
|
||||||
|
if (q.tail) {
|
||||||
|
q.range[1] += 1;
|
||||||
|
} else {
|
||||||
|
q.range[1] += 2;
|
||||||
|
}
|
||||||
|
q.loc.start.column -= 1;
|
||||||
|
if (q.tail) {
|
||||||
|
q.loc.end.column += 1;
|
||||||
|
} else {
|
||||||
|
q.loc.end.column += 2;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function fixDirectives (path) {
|
||||||
|
if (!(path.isProgram() || path.isFunction())) return;
|
||||||
|
|
||||||
|
var node = path.node;
|
||||||
|
var directivesContainer = node;
|
||||||
|
var body = node.body;
|
||||||
|
|
||||||
|
if (node.type !== "Program") {
|
||||||
|
directivesContainer = body;
|
||||||
|
body = body.body;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!directivesContainer.directives) return;
|
||||||
|
|
||||||
|
directivesContainer.directives.reverse().forEach(function (directive) {
|
||||||
|
directive.type = "ExpressionStatement";
|
||||||
|
directive.expression = directive.value;
|
||||||
|
delete directive.value;
|
||||||
|
directive.expression.type = "Literal";
|
||||||
|
changeToLiteral(directive.expression);
|
||||||
|
body.unshift(directive);
|
||||||
|
});
|
||||||
|
delete directivesContainer.directives;
|
||||||
|
}
|
||||||
|
// fixDirectives
|
||||||
60
eslint/babel-eslint-parser/babylon-to-espree/toToken.js
Normal file
60
eslint/babel-eslint-parser/babylon-to-espree/toToken.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
module.exports = function (token, tt, source) {
|
||||||
|
var type = token.type;
|
||||||
|
token.range = [token.start, token.end];
|
||||||
|
|
||||||
|
if (type === tt.name) {
|
||||||
|
token.type = "Identifier";
|
||||||
|
} else if (type === tt.semi || type === tt.comma ||
|
||||||
|
type === tt.parenL || type === tt.parenR ||
|
||||||
|
type === tt.braceL || type === tt.braceR ||
|
||||||
|
type === tt.slash || type === tt.dot ||
|
||||||
|
type === tt.bracketL || type === tt.bracketR ||
|
||||||
|
type === tt.ellipsis || type === tt.arrow ||
|
||||||
|
type === tt.star || type === tt.incDec ||
|
||||||
|
type === tt.colon || type === tt.question ||
|
||||||
|
type === tt.template || type === tt.backQuote ||
|
||||||
|
type === tt.dollarBraceL || type === tt.at ||
|
||||||
|
type === tt.logicalOR || type === tt.logicalAND ||
|
||||||
|
type === tt.bitwiseOR || type === tt.bitwiseXOR ||
|
||||||
|
type === tt.bitwiseAND || type === tt.equality ||
|
||||||
|
type === tt.relational || type === tt.bitShift ||
|
||||||
|
type === tt.plusMin || type === tt.modulo ||
|
||||||
|
type === tt.exponent || type === tt.prefix ||
|
||||||
|
type === tt.doubleColon ||
|
||||||
|
type.isAssign) {
|
||||||
|
token.type = "Punctuator";
|
||||||
|
if (!token.value) token.value = type.label;
|
||||||
|
} else if (type === tt.jsxTagStart) {
|
||||||
|
token.type = "Punctuator";
|
||||||
|
token.value = "<";
|
||||||
|
} else if (type === tt.jsxTagEnd) {
|
||||||
|
token.type = "Punctuator";
|
||||||
|
token.value = ">";
|
||||||
|
} else if (type === tt.jsxName) {
|
||||||
|
token.type = "JSXIdentifier";
|
||||||
|
} else if (type === tt.jsxText) {
|
||||||
|
token.type = "JSXText";
|
||||||
|
} else if (type.keyword === "null") {
|
||||||
|
token.type = "Null";
|
||||||
|
} else if (type.keyword === "false" || type.keyword === "true") {
|
||||||
|
token.type = "Boolean";
|
||||||
|
} else if (type.keyword) {
|
||||||
|
token.type = "Keyword";
|
||||||
|
} else if (type === tt.num) {
|
||||||
|
token.type = "Numeric";
|
||||||
|
token.value = source.slice(token.start, token.end);
|
||||||
|
} else if (type === tt.string) {
|
||||||
|
token.type = "String";
|
||||||
|
token.value = source.slice(token.start, token.end);
|
||||||
|
} else if (type === tt.regexp) {
|
||||||
|
token.type = "RegularExpression";
|
||||||
|
var value = token.value;
|
||||||
|
token.regex = {
|
||||||
|
pattern: value.pattern,
|
||||||
|
flags: value.flags
|
||||||
|
};
|
||||||
|
token.value = "/" + value.pattern + "/" + value.flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
};
|
||||||
16
eslint/babel-eslint-parser/babylon-to-espree/toTokens.js
Normal file
16
eslint/babel-eslint-parser/babylon-to-espree/toTokens.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
var convertTemplateType = require("./convertTemplateType");
|
||||||
|
var toToken = require("./toToken");
|
||||||
|
|
||||||
|
module.exports = function (tokens, tt, code) {
|
||||||
|
// transform tokens to type "Template"
|
||||||
|
convertTemplateType(tokens, tt);
|
||||||
|
var transformedTokens = tokens.filter(function (token) {
|
||||||
|
return token.type !== "CommentLine" && token.type !== "CommentBlock";
|
||||||
|
});
|
||||||
|
|
||||||
|
for (var i = 0, l = transformedTokens.length; i < l; i++) {
|
||||||
|
transformedTokens[i] = toToken(transformedTokens[i], tt, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
return transformedTokens;
|
||||||
|
};
|
||||||
@ -1,4 +1,4 @@
|
|||||||
var acornToEsprima = require("acorn-to-esprima");
|
var babylonToEspree = require("./babylon-to-espree");
|
||||||
var assign = require("lodash.assign");
|
var assign = require("lodash.assign");
|
||||||
var pick = require("lodash.pick");
|
var pick = require("lodash.pick");
|
||||||
var Module = require("module");
|
var Module = require("module");
|
||||||
@ -380,7 +380,9 @@ function monkeypatch() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.parse = function (code) {
|
exports.parse = function (code, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
monkeypatch();
|
monkeypatch();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -388,12 +390,12 @@ exports.parse = function (code) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return exports.parseNoPatch(code);
|
return exports.parseNoPatch(code, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.parseNoPatch = function (code) {
|
exports.parseNoPatch = function (code, options) {
|
||||||
var opts = {
|
var opts = {
|
||||||
sourceType: "module",
|
sourceType: options.sourceType || "module",
|
||||||
strictMode: true,
|
strictMode: true,
|
||||||
allowImportExportEverywhere: false, // consistent with espree
|
allowImportExportEverywhere: false, // consistent with espree
|
||||||
allowReturnOutsideFunction: true,
|
allowReturnOutsideFunction: true,
|
||||||
@ -422,7 +424,7 @@ exports.parseNoPatch = function (code) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof SyntaxError) {
|
if (err instanceof SyntaxError) {
|
||||||
err.lineNumber = err.loc.line;
|
err.lineNumber = err.loc.line;
|
||||||
err.column = err.loc.column;
|
err.column = err.loc.column + 1;
|
||||||
|
|
||||||
// remove trailing "(LINE:COLUMN)" acorn message and add in esprima syntax error message start
|
// remove trailing "(LINE:COLUMN)" acorn message and add in esprima syntax error message start
|
||||||
err.message = "Line " + err.lineNumber + ": " + err.message.replace(/ \((\d+):(\d+)\)$/, "");
|
err.message = "Line " + err.lineNumber + ": " + err.message.replace(/ \((\d+):(\d+)\)$/, "");
|
||||||
@ -437,27 +439,27 @@ exports.parseNoPatch = function (code) {
|
|||||||
ast.tokens.pop();
|
ast.tokens.pop();
|
||||||
|
|
||||||
// convert tokens
|
// convert tokens
|
||||||
ast.tokens = acornToEsprima.toTokens(ast.tokens, tt, code);
|
ast.tokens = babylonToEspree.toTokens(ast.tokens, tt, code);
|
||||||
|
|
||||||
// add comments
|
// add comments
|
||||||
acornToEsprima.convertComments(ast.comments);
|
babylonToEspree.convertComments(ast.comments);
|
||||||
|
|
||||||
// transform esprima and acorn divergent nodes
|
// transform esprima and acorn divergent nodes
|
||||||
acornToEsprima.toAST(ast, traverse, code);
|
babylonToEspree.toAST(ast, traverse, code);
|
||||||
|
|
||||||
// ast.program.tokens = ast.tokens;
|
// ast.program.tokens = ast.tokens;
|
||||||
// ast.program.comments = ast.comments;
|
// ast.program.comments = ast.comments;
|
||||||
// ast = ast.program;
|
// ast = ast.program;
|
||||||
|
|
||||||
// remove File
|
// remove File
|
||||||
ast.type = 'Program';
|
ast.type = "Program";
|
||||||
ast.sourceType = ast.program.sourceType;
|
ast.sourceType = ast.program.sourceType;
|
||||||
ast.directives = ast.program.directives;
|
ast.directives = ast.program.directives;
|
||||||
ast.body = ast.program.body;
|
ast.body = ast.program.body;
|
||||||
delete ast.program;
|
delete ast.program;
|
||||||
delete ast._paths;
|
delete ast._paths;
|
||||||
|
|
||||||
acornToEsprima.attachComments(ast, ast.comments, ast.tokens);
|
babylonToEspree.attachComments(ast, ast.comments, ast.tokens);
|
||||||
|
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "babel-eslint",
|
"name": "babel-eslint",
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"description": "",
|
"description": "Custom parser for ESLint",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"files": [
|
"files": [
|
||||||
"index.js"
|
"index.js",
|
||||||
|
"babylon-to-espree"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/babel/babel-eslint.git"
|
"url": "https://github.com/babel/babel-eslint.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn-to-esprima": "^2.0.4",
|
|
||||||
"babel-traverse": "^6.0.20",
|
"babel-traverse": "^6.0.20",
|
||||||
"babel-types": "^6.0.19",
|
"babel-types": "^6.0.19",
|
||||||
"babylon": "^6.0.18",
|
"babylon": "^6.0.18",
|
||||||
@ -22,7 +22,8 @@
|
|||||||
"bootstrap": "git submodule update --init && cd eslint && npm install",
|
"bootstrap": "git submodule update --init && cd eslint && npm install",
|
||||||
"eslint": "cd eslint && mocha -c tests/lib/rules/*.js -r ../eslint-tester.js",
|
"eslint": "cd eslint && mocha -c tests/lib/rules/*.js -r ../eslint-tester.js",
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
"lint": "./node_modules/eslint/bin/eslint.js ./test index.js acorn-to-esprima.js",
|
"lint": "./node_modules/eslint/bin/eslint.js index.js babylon-to-espree test",
|
||||||
|
"fix": "./node_modules/eslint/bin/eslint.js index.js babylon-to-espree test --fix",
|
||||||
"preversion": "npm test"
|
"preversion": "npm test"
|
||||||
},
|
},
|
||||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||||
@ -32,8 +33,8 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/babel/babel-eslint",
|
"homepage": "https://github.com/babel/babel-eslint",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^1.10.2",
|
"eslint": "^2.0.0",
|
||||||
"espree": "^2.2.5",
|
"espree": "^3.0.0",
|
||||||
"mocha": "^2.3.3"
|
"mocha": "^2.3.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,49 +32,49 @@ function assertImplementsAST(target, source, path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function lookup(obj, keypath, backwardsDepth) {
|
||||||
|
if (!keypath) { return obj; }
|
||||||
|
|
||||||
|
return keypath.split(".").slice(0, -1 * backwardsDepth)
|
||||||
|
.reduce(function (base, segment) { return base && base[segment], obj });
|
||||||
|
}
|
||||||
|
|
||||||
function parseAndAssertSame(code) {
|
function parseAndAssertSame(code) {
|
||||||
var esAST = espree.parse(code, {
|
var esAST = espree.parse(code, {
|
||||||
ecmaFeatures: {
|
ecmaFeatures: {
|
||||||
arrowFunctions: true,
|
// enable JSX parsing
|
||||||
binaryLiterals: true,
|
|
||||||
blockBindings: true,
|
|
||||||
classes: true,
|
|
||||||
defaultParams: true,
|
|
||||||
destructuring: true,
|
|
||||||
forOf: true,
|
|
||||||
generators: true,
|
|
||||||
modules: true,
|
|
||||||
objectLiteralComputedProperties: true,
|
|
||||||
objectLiteralDuplicateProperties: true,
|
|
||||||
objectLiteralShorthandMethods: true,
|
|
||||||
objectLiteralShorthandProperties: true,
|
|
||||||
octalLiterals: true,
|
|
||||||
regexUFlag: true,
|
|
||||||
regexYFlag: true,
|
|
||||||
restParams: true,
|
|
||||||
spread: true,
|
|
||||||
superInFunctions: true,
|
|
||||||
templateStrings: true,
|
|
||||||
unicodeCodePointEscapes: true,
|
|
||||||
globalReturn: true,
|
|
||||||
jsx: true,
|
jsx: true,
|
||||||
experimentalObjectRestSpread: true,
|
// enable return in global scope
|
||||||
|
globalReturn: true,
|
||||||
|
// enable implied strict mode (if ecmaVersion >= 5)
|
||||||
|
impliedStrict: true,
|
||||||
|
// allow experimental object rest/spread
|
||||||
|
experimentalObjectRestSpread: true
|
||||||
},
|
},
|
||||||
tokens: true,
|
tokens: true,
|
||||||
loc: true,
|
loc: true,
|
||||||
range: true,
|
range: true,
|
||||||
comment: true,
|
comment: true,
|
||||||
attachComment: true
|
attachComment: true,
|
||||||
|
ecmaVersion: 6,
|
||||||
|
sourceType: "module"
|
||||||
});
|
});
|
||||||
var babylonAST = babelEslint.parse(code);
|
var babylonAST = babelEslint.parse(code);
|
||||||
try {
|
try {
|
||||||
assertImplementsAST(esAST, babylonAST);
|
assertImplementsAST(esAST, babylonAST);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
var traversal = err.message.slice(3, err.message.indexOf(":"));
|
||||||
|
if (esAST.tokens) {
|
||||||
|
delete esAST.tokens;
|
||||||
|
}
|
||||||
|
if (babylonAST.tokens) {
|
||||||
|
delete babylonAST.tokens;
|
||||||
|
}
|
||||||
err.message +=
|
err.message +=
|
||||||
"\nespree:\n" +
|
"\nespree:\n" +
|
||||||
util.inspect(esAST, {depth: err.depth, colors: true}) +
|
util.inspect(lookup(esAST, traversal, 2), {depth: err.depth, colors: true}) +
|
||||||
"\nbabel-eslint:\n" +
|
"\nbabel-eslint:\n" +
|
||||||
util.inspect(babylonAST, {depth: err.depth, colors: true});
|
util.inspect(lookup(babylonAST, traversal, 2), {depth: err.depth, colors: true});
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
// assert.equal(esAST, babylonAST);
|
// assert.equal(esAST, babylonAST);
|
||||||
@ -394,7 +394,7 @@ describe("acorn-to-esprima", function () {
|
|||||||
it("do not allow import export everywhere", function() {
|
it("do not allow import export everywhere", function() {
|
||||||
assert.throws(function () {
|
assert.throws(function () {
|
||||||
parseAndAssertSame("function F() { import a from \"a\"; }");
|
parseAndAssertSame("function F() { import a from \"a\"; }");
|
||||||
}, /Illegal import declaration/)
|
}, /SyntaxError: 'import' and 'export' may only appear at the top level/)
|
||||||
});
|
});
|
||||||
|
|
||||||
it("return outside function", function () {
|
it("return outside function", function () {
|
||||||
@ -406,7 +406,7 @@ describe("acorn-to-esprima", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("StringLiteral", function () {
|
it("StringLiteral", function () {
|
||||||
parseAndAssertSame('');
|
parseAndAssertSame("");
|
||||||
parseAndAssertSame("");
|
parseAndAssertSame("");
|
||||||
parseAndAssertSame("a");
|
parseAndAssertSame("a");
|
||||||
});
|
});
|
||||||
@ -443,5 +443,17 @@ describe("acorn-to-esprima", function () {
|
|||||||
"};"
|
"};"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("RestOperator", function () {
|
||||||
|
parseAndAssertSame("var { a, ...b } = c");
|
||||||
|
parseAndAssertSame("var [ a, ...b ] = c");
|
||||||
|
parseAndAssertSame("var a = function (...b) {}");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("SpreadOperator", function () {
|
||||||
|
parseAndAssertSame("var a = { b, ...c }");
|
||||||
|
parseAndAssertSame("var a = [ a, ...b ]");
|
||||||
|
parseAndAssertSame("var a = sum(...b)");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,6 +13,9 @@ var errorLevel = 2;
|
|||||||
|
|
||||||
var baseEslintOpts = {
|
var baseEslintOpts = {
|
||||||
parser: require.resolve(".."),
|
parser: require.resolve(".."),
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: "script"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -2,43 +2,25 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
var eslint = require("eslint");
|
var eslint = require("eslint");
|
||||||
|
|
||||||
function verifyAndAssertMessages(code, rules, expectedMessages, features) {
|
function verifyAndAssertMessages(code, rules, expectedMessages, sourceType) {
|
||||||
var defaultEcmaFeatures = {
|
|
||||||
arrowFunctions: true,
|
|
||||||
binaryLiterals: true,
|
|
||||||
blockBindings: true,
|
|
||||||
classes: true,
|
|
||||||
defaultParams: true,
|
|
||||||
destructuring: true,
|
|
||||||
forOf: true,
|
|
||||||
generators: true,
|
|
||||||
modules: true,
|
|
||||||
objectLiteralComputedProperties: true,
|
|
||||||
objectLiteralDuplicateProperties: true,
|
|
||||||
objectLiteralShorthandMethods: true,
|
|
||||||
objectLiteralShorthandProperties: true,
|
|
||||||
octalLiterals: true,
|
|
||||||
regexUFlag: true,
|
|
||||||
regexYFlag: true,
|
|
||||||
restParams: true,
|
|
||||||
spread: true,
|
|
||||||
superInFunctions: true,
|
|
||||||
templateStrings: true,
|
|
||||||
unicodeCodePointEscapes: true,
|
|
||||||
globalReturn: true,
|
|
||||||
jsx: true,
|
|
||||||
experimentalObjectRestSpread: true
|
|
||||||
};
|
|
||||||
|
|
||||||
var messages = eslint.linter.verify(
|
var messages = eslint.linter.verify(
|
||||||
code,
|
code,
|
||||||
{
|
{
|
||||||
parser: require.resolve(".."),
|
parser: require.resolve(".."),
|
||||||
rules: rules,
|
rules: rules,
|
||||||
env: {
|
env: {
|
||||||
node: true
|
node: true,
|
||||||
|
es6: true
|
||||||
},
|
},
|
||||||
ecmaFeatures: features || defaultEcmaFeatures
|
parserOptions: {
|
||||||
|
ecmaVersion: 6,
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
|
experimentalObjectRestSpread: true,
|
||||||
|
globalReturn: true
|
||||||
|
},
|
||||||
|
sourceType: sourceType || "module"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -143,7 +125,7 @@ describe("verify", function () {
|
|||||||
"\"use strict\"; () => 1",
|
"\"use strict\"; () => 1",
|
||||||
{ "strict": [1, "global"] },
|
{ "strict": [1, "global"] },
|
||||||
[],
|
[],
|
||||||
{ modules: false }
|
"script"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -415,8 +397,8 @@ describe("verify", function () {
|
|||||||
"var b: T = 1; b;"
|
"var b: T = 1; b;"
|
||||||
].join("\n"),
|
].join("\n"),
|
||||||
{ "no-unused-vars": 1, "no-undef": 1 },
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
[ "1:21 \"T\" is defined but never used no-unused-vars",
|
[ "1:21 'T' is defined but never used no-unused-vars",
|
||||||
'2:8 "T" is not defined. no-undef' ]
|
"2:8 'T' is not defined. no-undef" ]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -426,7 +408,7 @@ describe("verify", function () {
|
|||||||
"export class Foo extends Bar<T> {}",
|
"export class Foo extends Bar<T> {}",
|
||||||
].join("\n"),
|
].join("\n"),
|
||||||
{ "no-unused-vars": 1, "no-undef": 1 },
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
[ '2:30 "T" is not defined. no-undef' ]
|
[ "2:30 'T' is not defined. no-undef" ]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1151,7 +1133,7 @@ describe("verify", function () {
|
|||||||
verifyAndAssertMessages(
|
verifyAndAssertMessages(
|
||||||
"var unused;",
|
"var unused;",
|
||||||
{ "no-unused-vars": 1 },
|
{ "no-unused-vars": 1 },
|
||||||
[ "1:5 \"unused\" is defined but never used no-unused-vars" ]
|
[ "1:5 'unused' is defined but never used no-unused-vars" ]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1175,7 +1157,7 @@ describe("verify", function () {
|
|||||||
verifyAndAssertMessages(
|
verifyAndAssertMessages(
|
||||||
"const {Bacona} = require('baconjs')",
|
"const {Bacona} = require('baconjs')",
|
||||||
{ "no-undef": 1, "no-unused-vars": 1 },
|
{ "no-undef": 1, "no-unused-vars": 1 },
|
||||||
[ "1:8 \"Bacona\" is defined but never used no-unused-vars" ]
|
[ "1:8 'Bacona' is defined but never used no-unused-vars" ]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1301,7 +1283,7 @@ describe("verify", function () {
|
|||||||
"var x = 1;"
|
"var x = 1;"
|
||||||
].join("\n"),
|
].join("\n"),
|
||||||
{ "no-use-before-define": 1 },
|
{ "no-use-before-define": 1 },
|
||||||
[ "1:13 \"x\" was used before it was defined no-use-before-define" ]
|
[ "1:13 'x' was used before it was defined no-use-before-define" ]
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1316,10 +1298,10 @@ describe("verify", function () {
|
|||||||
it("getter/setter #218", function () {
|
it("getter/setter #218", function () {
|
||||||
verifyAndAssertMessages([
|
verifyAndAssertMessages([
|
||||||
"class Person {",
|
"class Person {",
|
||||||
"set a (v) { }",
|
" set a (v) { }",
|
||||||
"}"
|
"}"
|
||||||
].join("\n"),
|
].join("\n"),
|
||||||
{ "space-before-function-paren": 1, "space-before-keywords": 1, "indent": 1 },
|
{ "space-before-function-paren": 1, "keyword-spacing": [1, {"before": true}], "indent": 1 },
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user