Merge branch 'master' of github.com:babel/babel-eslint
This commit is contained in:
parent
a31835836d
commit
6556b06f23
@ -7,9 +7,24 @@ exports.toToken = function (token) {
|
||||
|
||||
if (type === tokTypes.name) {
|
||||
token.type = "Identifier";
|
||||
} else if (type === tokTypes.semi || type === tokTypes.comma || type === tokTypes.parenL || type === tokTypes.parenR || type === tokTypes.braceL || type === tokTypes.braceR) {
|
||||
} else if (type === tokTypes.semi || type === tokTypes.comma || type === tokTypes.parenL || type === tokTypes.parenR || type === tokTypes.braceL || type === tokTypes.braceR || type === tokTypes.slash || type === tokTypes.dot || type.isAssign) {
|
||||
token.type = "Punctuator";
|
||||
token.value = type.type;
|
||||
if (!token.value) {
|
||||
token.value = type.type;
|
||||
}
|
||||
} else if (type === tokTypes.jsxTagStart) {
|
||||
token.type = "Punctuator";
|
||||
token.value = "<";
|
||||
} else if (type === tokTypes.jsxTagEnd) {
|
||||
token.type = "Punctuator";
|
||||
token.value = ">";
|
||||
} else if (type === tokTypes.jsxName) {
|
||||
token.type = "JSXIdentifier";
|
||||
} else if (type.keyword) {
|
||||
token.type = "Keyword";
|
||||
} else if (type === tokTypes.num) {
|
||||
token.type = "Numeric";
|
||||
token.value = String(token.value);
|
||||
}
|
||||
|
||||
return token;
|
||||
@ -51,6 +66,11 @@ var astTransformVisitor = {
|
||||
|
||||
// classes
|
||||
|
||||
if (t.isClassDeclaration(node) || t.isClassExpression(node)) {
|
||||
node.name = node.id;
|
||||
delete node.id;
|
||||
}
|
||||
|
||||
if (t.isReferencedIdentifier(node, parent, { name: "super" })) {
|
||||
return t.inherits(t.thisExpression(), node);
|
||||
}
|
||||
@ -60,22 +80,6 @@ var astTransformVisitor = {
|
||||
this.remove();
|
||||
}
|
||||
|
||||
// JSX
|
||||
|
||||
if (t.isJSXIdentifier(node)) {
|
||||
if (node.name === "this" && t.isReferenced(node, parent)) {
|
||||
return t.inherits(t.thisExpression(), node);
|
||||
} else if (!t.isJSXAttribute(parent) && !isCompatTag(node.name)) {
|
||||
node.type = "Identifier";
|
||||
} else {
|
||||
// just ignore this node as it'd be something like <div> or an attribute name
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isJSXMemberExpression(node)) {
|
||||
node.type = "MemberExpression";
|
||||
}
|
||||
|
||||
// functions
|
||||
|
||||
if (t.isFunction(node)) {
|
||||
|
||||
@ -21,7 +21,7 @@ function monkeypatch() {
|
||||
|
||||
var eslintLoc;
|
||||
try {
|
||||
eslintLoc = require.resolve("eslint");
|
||||
eslintLoc = Module._resolveFilename("eslint", module.parent);
|
||||
} catch (err) {
|
||||
throw new ReferenceError("couldn't resolve eslint");
|
||||
}
|
||||
@ -43,6 +43,17 @@ function monkeypatch() {
|
||||
opts.sourceType = "module";
|
||||
return analyze.call(this, ast, opts)
|
||||
};
|
||||
|
||||
var eslint = require(eslintLoc);
|
||||
var getScope = eslint.linter.getScope;
|
||||
eslint.linter.getScope = function () {
|
||||
var scope = getScope.apply(this, arguments);
|
||||
if (scope.type === "global" && !scope.__patchedWithModuleVariables) {
|
||||
scope.__patchedWithModuleVariables = true;
|
||||
scope.variables.push.apply(scope.variables, scope.childScopes[0].variables);
|
||||
}
|
||||
return scope;
|
||||
};
|
||||
}
|
||||
|
||||
exports.parse = function (code) {
|
||||
|
||||
@ -16,5 +16,13 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/babel/babel-eslint/issues"
|
||||
},
|
||||
"homepage": "https://github.com/babel/babel-eslint"
|
||||
"homepage": "https://github.com/babel/babel-eslint",
|
||||
"devDependencies": {
|
||||
"eslint": "^0.15.1",
|
||||
"espree": "^1.10.0",
|
||||
"mocha": "^2.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
}
|
||||
}
|
||||
|
||||
90
eslint/babel-eslint-parser/test/babel-eslint.js
Normal file
90
eslint/babel-eslint-parser/test/babel-eslint.js
Normal file
@ -0,0 +1,90 @@
|
||||
var util = require("util");
|
||||
var espree = require("espree");
|
||||
var babelEslint = require("..");
|
||||
|
||||
|
||||
function assertSameAST(a, b, path) {
|
||||
if (!path) {
|
||||
path = [];
|
||||
}
|
||||
|
||||
function error(text) {
|
||||
throw new Error("At " + path.join(".") + ": " + text + ":\n" + util.inspect(a) + "\n" + util.inspect(b));
|
||||
}
|
||||
|
||||
var typeA = a === null ? "null" : typeof a;
|
||||
var typeB = b === null ? "null" : typeof b;
|
||||
if (typeA !== typeB) {
|
||||
error("have not the same type (" + typeA + " !== " + typeB + ")");
|
||||
} else if (typeA === "object") {
|
||||
var keysA = Object.keys(a);
|
||||
var keysB = Object.keys(b);
|
||||
keysA.sort();
|
||||
keysB.sort();
|
||||
while (true) {
|
||||
var keyA = keysA.shift();
|
||||
|
||||
// Exception: ignore "end" and "start" outside "loc" properties
|
||||
if ((keyA === "end" || keyA === "start") && path[path.length - 1] !== "loc") continue;
|
||||
// Exception: ignore root "comments" property
|
||||
if (keyA === "comments" && path.length === 0) continue;
|
||||
|
||||
var keyB = keysB.shift();
|
||||
|
||||
if (keyA === undefined && keyB === undefined) break;
|
||||
if (keyA === undefined || keyA > keyB) error("first does not have key \"" + keyB + "\"");
|
||||
if (keyB === undefined || keyA < keyB) error("second does not have key \"" + keyA + "\"");
|
||||
path.push(keyA);
|
||||
assertSameAST(a[keyA], b[keyB], path);
|
||||
path.pop();
|
||||
}
|
||||
} else if (a !== b) {
|
||||
error("are different (" + JSON.stringify(a) + " !== " + JSON.stringify(b) + ")");
|
||||
}
|
||||
}
|
||||
|
||||
function parseAndAssertSame(code) {
|
||||
var esAST = espree.parse(code, {
|
||||
ecmaFeatures: {
|
||||
classes: true,
|
||||
jsx: true
|
||||
},
|
||||
tokens: true,
|
||||
loc: true,
|
||||
range: true
|
||||
});
|
||||
var acornAST = babelEslint.parse(code);
|
||||
assertSameAST(acornAST, esAST);
|
||||
}
|
||||
|
||||
describe("acorn-to-esprima", function () {
|
||||
|
||||
it("simple expression", function () {
|
||||
parseAndAssertSame("a = 1");
|
||||
});
|
||||
|
||||
it("class declaration", function () {
|
||||
parseAndAssertSame("class Foo {}");
|
||||
});
|
||||
|
||||
it("class expression", function () {
|
||||
parseAndAssertSame("var a = class Foo {}");
|
||||
});
|
||||
|
||||
it("jsx expression", function () {
|
||||
parseAndAssertSame("<App />");
|
||||
});
|
||||
|
||||
it("jsx expression with 'this' as identifier", function () {
|
||||
parseAndAssertSame("<this />");
|
||||
});
|
||||
|
||||
it("jsx expression with a dynamic attribute", function () {
|
||||
parseAndAssertSame("<App foo={bar} />");
|
||||
});
|
||||
|
||||
it("jsx expression with a member expression as identifier", function () {
|
||||
parseAndAssertSame("<foo.bar />");
|
||||
});
|
||||
|
||||
});
|
||||
145
eslint/babel-eslint-parser/test/non-regression.js
Normal file
145
eslint/babel-eslint-parser/test/non-regression.js
Normal file
@ -0,0 +1,145 @@
|
||||
/*eslint-env mocha*/
|
||||
"use strict";
|
||||
var eslint = require("eslint");
|
||||
|
||||
function verifyAndAssertMessages(code, rules, expectedMessages) {
|
||||
var messages = eslint.linter.verify(
|
||||
code,
|
||||
{
|
||||
parser: require.resolve(".."),
|
||||
rules: rules,
|
||||
env: {
|
||||
node: true
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (messages.length !== expectedMessages.length) {
|
||||
throw new Error("Expected " + expectedMessages.length + " message(s), got " + messages.length);
|
||||
}
|
||||
|
||||
messages.forEach(function (message, i) {
|
||||
var formatedMessage = message.line + ":" + message.column + " " + message.message + (message.ruleId ? " " + message.ruleId : "");
|
||||
if (formatedMessage !== expectedMessages[i]) {
|
||||
throw new Error("Message " + i + " does not match:\nExpected: " + expectedMessages[i] + "\nActual: " + formatedMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
describe("verify", function () {
|
||||
|
||||
it("arrow function support (issue #1)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"describe('stuff', () => {});",
|
||||
{},
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("EOL validation (issue #2)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"module.exports = \"something\";",
|
||||
{ "eol-last": 1, "semi": 1 },
|
||||
[ "1:1 Newline required at end of file but not found. eol-last" ]
|
||||
);
|
||||
});
|
||||
|
||||
it("Readable error messages (issue #3)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"{ , res }",
|
||||
{},
|
||||
[ "1:2 Unexpected token" ]
|
||||
);
|
||||
});
|
||||
|
||||
it("Unused vars in JSX (issue #5)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"var App = require('./App');\n" +
|
||||
"module.exports = <App />;",
|
||||
{ "no-unused-vars": 1 },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("Modules support (issue #5)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"import Foo from 'foo';\n" +
|
||||
"export default Foo;",
|
||||
{ },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("Rest parameters (issue #7)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"function foo(...args) { return args; }",
|
||||
{ "no-undef": 1 },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("Exported classes should be used (issue #8)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"class Foo {} module.exports = Foo;",
|
||||
{ "no-unused-vars": 1 },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("super keyword in class (issue #10)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"class Foo { constructor() { super() } }",
|
||||
{ "no-undef": 1 },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("Rest parameter in destructuring assignment (issue #11)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"const [a, ...rest] = ['1', '2', '3']; module.exports = rest;",
|
||||
{ "no-undef": 1 },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("JSX attribute names marked as variables (issue #12)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"module.exports = <div className=\"foo\" />",
|
||||
{ "no-undef": 1 },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("Variables in JSX should be used (issues #15, #17, #21, #29)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"import App from './App'; export default (<App />);",
|
||||
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("Multiple destructured assignment with compound properties (issue #16)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"module.exports = { ...a.a, ...a.b };",
|
||||
{ "no-dupe-keys": 1 },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("Arrow function with non-block bodies (issue #20)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"\"use strict\"; () => 1",
|
||||
{ "strict": 1 },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("await keyword (issue #22)", function () {
|
||||
verifyAndAssertMessages(
|
||||
"async function foo() { await bar(); }",
|
||||
{ "no-unused-expressions": 1 },
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user