diff --git a/eslint/babel-eslint-parser/.gitignore b/eslint/babel-eslint-parser/.gitignore new file mode 100644 index 0000000000..3c3629e647 --- /dev/null +++ b/eslint/babel-eslint-parser/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/eslint/babel-eslint-parser/LICENSE b/eslint/babel-eslint-parser/LICENSE new file mode 100644 index 0000000000..dac23744b0 --- /dev/null +++ b/eslint/babel-eslint-parser/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2014-2015 Sebastian McKenzie + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/eslint/babel-eslint-parser/README.md b/eslint/babel-eslint-parser/README.md new file mode 100644 index 0000000000..c6a433f04f --- /dev/null +++ b/eslint/babel-eslint-parser/README.md @@ -0,0 +1,34 @@ +# babel-eslint + +**babel-eslint** allows you to lint **ALL** valid Babel code with the fantastic +[eslint](https://github.com/eslint/eslint). + +**NOTE:** Please note that this is experimental and may have numerous bugs. It is however +successfuly linting the [babel core](https://github.com/babel/babel/blob/master/.eslintrc). + +## Usage + +### Install + +```sh +$ npm install eslint babel-eslint +``` + +### Setup + +**.eslintrc** + +```json +{ + "parser": "babel-eslint", + "rules": { + "strict": 0 + } +} +``` + +### Run + +```sh +$ eslint your-files-here +``` diff --git a/eslint/babel-eslint-parser/acorn-to-esprima.js b/eslint/babel-eslint-parser/acorn-to-esprima.js new file mode 100644 index 0000000000..6040a3d654 --- /dev/null +++ b/eslint/babel-eslint-parser/acorn-to-esprima.js @@ -0,0 +1,50 @@ +var tokTypes = require("babel").acorn.tokTypes; +var traverse = require("babel").traverse; +var t = require("babel").types; + +exports.toToken = function (token) { + var type = token.type; + + 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) { + token.type = "Punctuator"; + token.value = type.type; + } + + return token; +}; + +exports.toAST = function (ast) { + traverse(ast, astTransformVisitor); +}; + +var astTransformVisitor = { + noScope: true, + enter: function (node) { + if (t.isImportBatchSpecifier(node)) { + node.type = "ImportNamespaceSpecifier"; + node.id = node.name; + delete node.name; + } else if (t.isFunction(node)) { + node.defaults = []; + + node.params = node.params.map(function (param) { + if (t.isAssignmentPattern(param)) { + node.defaults.push(param.right); + return param.left; + } else { + node.defaults.push(null); + return param; + } + }); + + // rest + if (t.isRestElement(node.params[node.params.length - 1])) { + node.rest = node.params.pop(); + } + } else if (t.isClassProperty(node)) { + this.remove(); + } + } +}; diff --git a/eslint/babel-eslint-parser/index.js b/eslint/babel-eslint-parser/index.js new file mode 100644 index 0000000000..ee476e9bfe --- /dev/null +++ b/eslint/babel-eslint-parser/index.js @@ -0,0 +1,77 @@ +var acornToEsprima = require("./acorn-to-esprima"); +var traverse = require("babel").traverse; +var extend = require("lodash/object/extend"); +var Module = require("module"); +var acorn = require("babel").acorn; +var path = require("path"); +var t = require("babel").types; + +var hasPatched = false; + +function createModule(filename) { + var mod = new Module(filename); + mod.filename = filename; + mod.paths = Module._nodeModulePaths(path.dirname(filename)); + return mod; +} + +function monkeypatch() { + if (hasPatched) return; + hasPatched = true; + + var eslintLoc; + try { + eslintLoc = require.resolve("eslint"); + } catch (err) { + throw new ReferenceError("couldn't resolve eslint"); + } + + // get modules relative to what eslint will load + var eslintMod = createModule(eslintLoc); + var escopeLoc = Module._resolveFilename("escope", eslintMod); + var escopeMod = createModule(escopeLoc); + + // monkeypatch estraverse + var estraverse = escopeMod.require("estraverse"); + extend(estraverse.VisitorKeys, t.VISITOR_KEYS); + + // monkeypatch escope + var escope = require(escopeLoc); + var analyze = escope.analyze; + escope.analyze = function (ast, opts) { + opts.ecmaVersion = 6; + opts.sourceType = "module"; + return analyze.call(this, ast, opts) + }; +} + +exports.parse = function (code) { + try { + monkeypatch(); + } catch (err) { + console.error(err.stack); + process.exit(1); + } + + var opts = {}; + opts.ecmaVersion = 7; + opts.playground = true; + opts.locations = true; + opts.ranges = true; + + var comments = opts.onComment = []; + var tokens = opts.onToken = []; + + var ast = acorn.parse(code, opts); + + // convert tokens + ast.tokens = tokens.map(acornToEsprima.toToken); + + // add comments + ast.comments = comments; + + // transform esprima and acorn divergent nodes + acornToEsprima.toAST(ast); + + return ast; +}; diff --git a/eslint/babel-eslint-parser/package.json b/eslint/babel-eslint-parser/package.json new file mode 100644 index 0000000000..be6c731f53 --- /dev/null +++ b/eslint/babel-eslint-parser/package.json @@ -0,0 +1,20 @@ +{ + "name": "babel-eslint", + "version": "1.0.3", + "description": "", + "main": "index.js", + "repository": { + "type": "git", + "url": "https://github.com/babel/babel-eslint.git" + }, + "dependencies": { + "babel": "^4.6.0", + "lodash": "^3.3.1" + }, + "author": "Sebastian McKenzie ", + "license": "MIT", + "bugs": { + "url": "https://github.com/babel/babel-eslint/issues" + }, + "homepage": "https://github.com/babel/babel-eslint" +}