diff --git a/babylon-to-espree/attachComments.js b/babylon-to-espree/attachComments.js index 4040ce7e..9fc9f339 100644 --- a/babylon-to-espree/attachComments.js +++ b/babylon-to-espree/attachComments.js @@ -1,3 +1,5 @@ +"use strict"; + // comment fixes module.exports = function (ast, comments, tokens) { if (comments.length) { diff --git a/babylon-to-espree/convertComments.js b/babylon-to-espree/convertComments.js new file mode 100644 index 00000000..19c6ce8c --- /dev/null +++ b/babylon-to-espree/convertComments.js @@ -0,0 +1,17 @@ +"use strict"; + +module.exports = 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]; + } + } +}; diff --git a/babylon-to-espree/convertTemplateType.js b/babylon-to-espree/convertTemplateType.js index c9537ddd..8b647c39 100644 --- a/babylon-to-espree/convertTemplateType.js +++ b/babylon-to-espree/convertTemplateType.js @@ -1,3 +1,5 @@ +"use strict"; + module.exports = function (tokens, tt) { var startingToken = 0; var currentToken = 0; diff --git a/babylon-to-espree/index.js b/babylon-to-espree/index.js index 401570b6..94e6832f 100644 --- a/babylon-to-espree/index.js +++ b/babylon-to-espree/index.js @@ -1,20 +1,36 @@ -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]; - } - } +"use strict"; + +var attachComments = require("./attachComments"); +var convertComments = require("./convertComments"); +var toTokens = require("./toTokens"); +var toAST = require("./toAST"); + +module.exports = function (ast, traverse, tt, code) { + // remove EOF token, eslint doesn't use this for anything and it interferes + // with some rules see https://github.com/babel/babel-eslint/issues/2 + // todo: find a more elegant way to do this + ast.tokens.pop(); + + // convert tokens + ast.tokens = toTokens(ast.tokens, tt, code); + + // add comments + convertComments(ast.comments); + + // transform esprima and acorn divergent nodes + toAST(ast, traverse, code); + + // ast.program.tokens = ast.tokens; + // ast.program.comments = ast.comments; + // ast = ast.program; + + // remove File + ast.type = "Program"; + ast.sourceType = ast.program.sourceType; + ast.directives = ast.program.directives; + ast.body = ast.program.body; + delete ast.program; + delete ast._paths; + + attachComments(ast, ast.comments, ast.tokens); }; diff --git a/babylon-to-espree/toAST.js b/babylon-to-espree/toAST.js index c26fa5ba..84d77a53 100644 --- a/babylon-to-espree/toAST.js +++ b/babylon-to-espree/toAST.js @@ -1,31 +1,21 @@ -var source; +"use strict"; + +var convertComments = require("./convertComments"); module.exports = function (ast, traverse, code) { - source = code; + var state = { source: code }; ast.range = [ast.start, ast.end]; - traverse(ast, astTransformVisitor); + traverse(ast, astTransformVisitor, null, state); }; -function changeToLiteral(node) { +function changeToLiteral(node, state) { 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); - } - } -} - -function changeComments(nodeComments) { - for (var i = 0; i < nodeComments.length; i++) { - var comment = nodeComments[i]; - if (comment.type === "CommentLine") { - comment.type = "Line"; - } else if (comment.type === "CommentBlock") { - comment.type = "Block"; + node.raw = state.source.slice(node.start, node.end); } - comment.range = [comment.start, comment.end]; } } @@ -45,24 +35,40 @@ var astTransformVisitor = { } if (node.trailingComments) { - changeComments(node.trailingComments); + convertComments(node.trailingComments); } if (node.leadingComments) { - changeComments(node.leadingComments); + convertComments(node.leadingComments); } // make '_paths' non-enumerable (babel-eslint #200) Object.defineProperty(node, "_paths", { value: node._paths, writable: true }); }, - exit (path) { + exit (path, state) { var node = path.node; - [ - fixDirectives, - ].forEach((fixer) => { - fixer(path); - }); + // fixDirectives + if (path.isFunction() || path.isProgram()) { + var directivesContainer = node; + var body = node.body; + if (node.type !== "Program") { + directivesContainer = body; + body = body.body; + } + if (directivesContainer.directives) { + for (var i = directivesContainer.directives.length - 1; i >= 0; i--) { + var directive = directivesContainer.directives[i]; + directive.type = "ExpressionStatement"; + directive.expression = directive.value; + delete directive.value; + directive.expression.type = "Literal"; + changeToLiteral(directive.expression, state); + body.unshift(directive); + } + delete directivesContainer.directives; + } + } if (path.isJSXText()) { node.type = "Literal"; @@ -71,7 +77,7 @@ var astTransformVisitor = { if (path.isNumericLiteral() || path.isStringLiteral()) { - changeToLiteral(node); + changeToLiteral(node, state); } if (path.isBooleanLiteral()) { @@ -104,7 +110,7 @@ var astTransformVisitor = { } if (path.isClassMethod() || path.isObjectMethod()) { - var code = source.slice(node.key.end, node.body.start); + var code = state.source.slice(node.key.end, node.body.start); var offset = code.indexOf("("); node.value = { @@ -211,7 +217,8 @@ var astTransformVisitor = { // template string range fixes if (path.isTemplateLiteral()) { - node.quasis.forEach((q) => { + for (var j = 0; j < node.quasis.length; j++) { + var q = node.quasis[j]; q.range[0] -= 1; if (q.tail) { q.range[1] += 1; @@ -224,34 +231,7 @@ var astTransformVisitor = { } 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((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 diff --git a/babylon-to-espree/toToken.js b/babylon-to-espree/toToken.js index dcfd48f8..6173f760 100644 --- a/babylon-to-espree/toToken.js +++ b/babylon-to-espree/toToken.js @@ -1,3 +1,5 @@ +"use strict"; + module.exports = function (token, tt, source) { var type = token.type; token.range = [token.start, token.end]; diff --git a/babylon-to-espree/toTokens.js b/babylon-to-espree/toTokens.js index 1f06d3e5..81ec9850 100644 --- a/babylon-to-espree/toTokens.js +++ b/babylon-to-espree/toTokens.js @@ -1,15 +1,18 @@ +"use strict"; + 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((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); + var transformedTokens = []; + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + if (token.type !== "CommentLine" && token.type !== "CommentBlock") { + transformedTokens.push(toToken(token, tt, code)); + } } return transformedTokens; diff --git a/index.js b/index.js index 3b243cc8..b56f74e5 100644 --- a/index.js +++ b/index.js @@ -428,33 +428,7 @@ exports.parseNoPatch = function (code, options) { throw err; } - // remove EOF token, eslint doesn't use this for anything and it interferes with some rules - // see https://github.com/babel/babel-eslint/issues/2 for more info - // todo: find a more elegant way to do this - ast.tokens.pop(); - - // convert tokens - ast.tokens = babylonToEspree.toTokens(ast.tokens, tt, code); - - // add comments - babylonToEspree.convertComments(ast.comments); - - // transform esprima and acorn divergent nodes - babylonToEspree.toAST(ast, traverse, code); - - // ast.program.tokens = ast.tokens; - // ast.program.comments = ast.comments; - // ast = ast.program; - - // remove File - ast.type = "Program"; - ast.sourceType = ast.program.sourceType; - ast.directives = ast.program.directives; - ast.body = ast.program.body; - delete ast.program; - delete ast._paths; - - babylonToEspree.attachComments(ast, ast.comments, ast.tokens); + babylonToEspree(ast, traverse, tt, code); return ast; };