Skip to content

Commit

Permalink
Use babylon estree and ranges (babel#489)
Browse files Browse the repository at this point in the history
  • Loading branch information
danez authored and hzoo committed Jun 15, 2017
1 parent 1aedb95 commit 39b4a6a
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 153 deletions.
1 change: 0 additions & 1 deletion babylon-to-espree/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ module.exports = function (ast, traverse, tt, code) {
ast.directives = ast.program.directives;
ast.body = ast.program.body;
delete ast.program;
delete ast._paths;

attachComments(ast, ast.comments, ast.tokens);
};
165 changes: 14 additions & 151 deletions babylon-to-espree/toAST.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
"use strict";

var t = require("babel-types");
var convertComments = require("./convertComments");

module.exports = function (ast, traverse, code) {
var state = { source: code };
ast.range = [ast.start, ast.end];

// Monkey patch visitor keys in order to be able to traverse the estree nodes
t.VISITOR_KEYS.Property = t.VISITOR_KEYS.ObjectProperty;
t.VISITOR_KEYS.MethodDefinition = ["key", "value", "decorators", "returnType", "typeParameters"];

traverse(ast, astTransformVisitor, null, state);
};

function changeToLiteral(node, state) {
node.type = "Literal";
if (!node.raw) {
if (node.extra && node.extra.raw) {
node.raw = node.extra.raw;
} else {
node.raw = state.source.slice(node.start, node.end);
}
}
}
delete t.VISITOR_KEYS.Property;
delete t.VISITOR_KEYS.MethodDefinition;
};

var astTransformVisitor = {
noScope: true,
enter (path) {
var node = path.node;

node.range = [node.start, node.end];

// private var to track original node type
node._babelType = node.type;

Expand All @@ -41,133 +36,17 @@ var astTransformVisitor = {
if (node.leadingComments) {
convertComments(node.leadingComments);
}

// make '_paths' non-enumerable (babel-eslint #200)
Object.defineProperty(node, "_paths", { value: node._paths, writable: true });
},
exit (path, state) {
exit (path) {
var node = path.node;

// 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";
node.raw = node.value;
}

if (path.isNumericLiteral() ||
path.isStringLiteral()) {
changeToLiteral(node, state);
}

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;
try {
node.value = new RegExp(node.pattern, node.flags);
} catch (err) {
node.value = null;
}
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 = state.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";
}
node.shorthand = false;
}

delete node.body;
delete node.id;
delete node.async;
delete node.generator;
delete node.expression;
delete node.params;
delete node.returnType;
delete node.typeParameters;
// TODO estree plugin bug
if (node.type === "Property") {
if (!node.shorthand) node.shorthand = false;
}

if (path.isRestElement() && path.parent && path.parent.type === "ObjectPattern") {
Expand All @@ -178,7 +57,7 @@ var astTransformVisitor = {
node.type = "ExperimentalSpreadProperty";
}

if (path.isTypeParameter && path.isTypeParameter()) {
if (path.isTypeParameter()) {
node.type = "Identifier";
node.typeAnnotation = node.bound;
delete node.bound;
Expand Down Expand Up @@ -208,22 +87,6 @@ var astTransformVisitor = {
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";
}
}

// TODO: remove (old esprima)
if (path.isFunction()) {
if (!node.defaults) {
node.defaults = [];
}
}

// template string range fixes
if (path.isTemplateLiteral()) {
for (var j = 0; j < node.quasis.length; j++) {
Expand Down
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,11 @@ exports.parseNoPatch = function (code, options) {
allowImportExportEverywhere: options.allowImportExportEverywhere, // consistent with espree
allowReturnOutsideFunction: true,
allowSuperOutsideMethod: true,
ranges: true,
plugins: [
"flow",
"jsx",
"estree",
"asyncFunctions",
"asyncGenerators",
"classConstructorCall",
Expand Down
2 changes: 1 addition & 1 deletion test/babel-eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ describe("babylon-to-esprima", () => {
);
});

describe("babel 6 tests", () => {
describe("babel tests", () => {
it("MethodDefinition", () => {
parseAndAssertSame(
unpad(`
Expand Down

0 comments on commit 39b4a6a

Please sign in to comment.