Skip to content
This repository has been archived by the owner on Aug 18, 2021. It is now read-only.

Use babylon estree and ranges #489

Merged
merged 5 commits into from
Jun 15, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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