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) {
|
if (type === tokTypes.name) {
|
||||||
token.type = "Identifier";
|
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.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;
|
return token;
|
||||||
@ -50,7 +65,12 @@ var astTransformVisitor = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// classes
|
// classes
|
||||||
|
|
||||||
|
if (t.isClassDeclaration(node) || t.isClassExpression(node)) {
|
||||||
|
node.name = node.id;
|
||||||
|
delete node.id;
|
||||||
|
}
|
||||||
|
|
||||||
if (t.isReferencedIdentifier(node, parent, { name: "super" })) {
|
if (t.isReferencedIdentifier(node, parent, { name: "super" })) {
|
||||||
return t.inherits(t.thisExpression(), node);
|
return t.inherits(t.thisExpression(), node);
|
||||||
}
|
}
|
||||||
@ -60,22 +80,6 @@ var astTransformVisitor = {
|
|||||||
this.remove();
|
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
|
// functions
|
||||||
|
|
||||||
if (t.isFunction(node)) {
|
if (t.isFunction(node)) {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ function monkeypatch() {
|
|||||||
|
|
||||||
var eslintLoc;
|
var eslintLoc;
|
||||||
try {
|
try {
|
||||||
eslintLoc = require.resolve("eslint");
|
eslintLoc = Module._resolveFilename("eslint", module.parent);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new ReferenceError("couldn't resolve eslint");
|
throw new ReferenceError("couldn't resolve eslint");
|
||||||
}
|
}
|
||||||
@ -43,6 +43,17 @@ function monkeypatch() {
|
|||||||
opts.sourceType = "module";
|
opts.sourceType = "module";
|
||||||
return analyze.call(this, ast, opts)
|
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) {
|
exports.parse = function (code) {
|
||||||
|
|||||||
@ -16,5 +16,13 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/babel/babel-eslint/issues"
|
"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