Clean up @babel/eslint-parser (#10753)
* Ensure compilation works for @babel/eslint-parser * Update with review suggestions * Incorporate feedback :)
This commit is contained in:
parent
52f964126d
commit
e81bbd69b3
@ -1,17 +1,13 @@
|
|||||||
# babel-eslint [](https://www.npmjs.com/package/babel-eslint) [](https://travis-ci.org/babel/babel-eslint) [](https://www.npmjs.com/package/babel-eslint)
|
# @babel/eslint-parser [](https://www.npmjs.com/package/@babel/eslint-parser) [](https://travis-ci.org/babel/@babel/eslint-parser) [](https://www.npmjs.com/package/@babel/eslint-parser)
|
||||||
|
|
||||||
**babel-eslint** allows you to lint **ALL** valid Babel code with the fantastic
|
**@babel/eslint-parser** allows you to lint **ALL** valid Babel code with the fantastic
|
||||||
[ESLint](https://github.com/eslint/eslint).
|
[ESLint](https://github.com/eslint/eslint).
|
||||||
|
|
||||||
## Breaking change in v11.x.x
|
## When should I use @babel/eslint-parser?
|
||||||
|
|
||||||
As of the v11.x.x release, babel-eslint now requires Babel as a peer dependency and expects a valid [Babel configuration file](https://babeljs.io/docs/en/configuration) to exist. This ensures that the same Babel configuration is used during both linting and compilation.
|
ESLint's default parser and core rules [only support the latest final ECMAScript standard](https://github.com/eslint/eslint/blob/a675c89573836adaf108a932696b061946abf1e6/README.md#what-about-experimental-features) and do not support experimental (such as new features) and non-standard (such as Flow or TypeScript types) syntax provided by Babel. @babel/eslint-parser is a parser that allows ESLint to run on source code that is transformed by Babel.
|
||||||
|
|
||||||
## When should I use babel-eslint?
|
**Note:** You only need to use @babel/parser-eslint if you are using Babel to transform your code. If this is not the case, please use the relevant parser for your chosen flavor of ECMAScript (note that the default parser supports all non-experimental syntax as well as JSX).
|
||||||
|
|
||||||
ESLint's default parser and core rules [only support the latest final ECMAScript standard](https://github.com/eslint/eslint/blob/a675c89573836adaf108a932696b061946abf1e6/README.md#what-about-experimental-features) and do not support experimental (such as new features) and non-standard (such as Flow or TypeScript types) syntax provided by Babel. babel-eslint is a parser that allows ESLint to run on source code that is transformed by Babel.
|
|
||||||
|
|
||||||
**Note:** You only need to use babel-eslint if you are using Babel to transform your code. If this is not the case, please use the relevant parser for your chosen flavor of ECMAScript (note that the default parser supports all non-experimental syntax as well as JSX).
|
|
||||||
|
|
||||||
## How does it work?
|
## How does it work?
|
||||||
|
|
||||||
@ -19,51 +15,51 @@ ESLint allows for the use of [custom parsers](https://eslint.org/docs/developer-
|
|||||||
transformed into an [ESTree](https://github.com/estree/estree)-compliant structure that ESLint can understand. All location info such as line numbers,
|
transformed into an [ESTree](https://github.com/estree/estree)-compliant structure that ESLint can understand. All location info such as line numbers,
|
||||||
columns is also retained so you can track down errors with ease.
|
columns is also retained so you can track down errors with ease.
|
||||||
|
|
||||||
**Note:** ESLint's core rules do not support experimental syntax and may therefore not work as expected when using babel-eslint. Please use the companion [`eslint-plugin-babel`](https://github.com/babel/eslint-plugin-babel) plugin for core rules that you have issues with.
|
**Note:** ESLint's core rules do not support experimental syntax and may therefore not work as expected when using `@babel/eslint-parser`. Please use the companion [`@babel/eslint-plugin`](https://github.com/babel/babel/tree/master/eslint/babel-eslint-plugin) plugin for core rules that you have issues with.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ npm install eslint babel-eslint --save-dev
|
$ npm install eslint @babel/core @babel/eslint-parser --save-dev
|
||||||
# or
|
# or
|
||||||
$ yarn add eslint babel-eslint -D
|
$ yarn add eslint @babel/core @babel/eslint-parser -D
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** babel-eslint requires `babel/core@>=7.2.0` and a valid Babel configuration file to run. If you do not have this already set up, please see the [Babel Usage Guide](https://babeljs.io/docs/en/usage).
|
**Note:** @babel/eslint-parser requires `@babel/core@>=7.2.0` and a valid Babel configuration file to run. If you do not have this already set up, please see the [Babel Usage Guide](https://babeljs.io/docs/en/usage).
|
||||||
|
|
||||||
### Setup
|
### Setup
|
||||||
|
|
||||||
To use babel-eslint, `"babel-eslint"` must be specified as the `parser` in your ESLint configuration file (see [here](https://eslint.org/docs/user-guide/configuring#specifying-parser) for more detailed information).
|
To use @babel/eslint-parser, `"@babel/eslint-parser"` must be specified as the `parser` in your ESLint configuration file (see [here](https://eslint.org/docs/user-guide/configuring#specifying-parser) for more detailed information).
|
||||||
|
|
||||||
**.eslintrc.js**
|
**.eslintrc.js**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
module.exports = {
|
module.exports = {
|
||||||
parser: "babel-eslint",
|
parser: "@babel/eslint-parser",
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
With the parser set, your configuration can be configured as described in the [Configuring ESLint](https://eslint.org/docs/user-guide/configuring) documentation.
|
With the parser set, your configuration can be configured as described in the [Configuring ESLint](https://eslint.org/docs/user-guide/configuring) documentation.
|
||||||
|
|
||||||
**Note:** The `parserOptions` described in the [official documentation](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) are for the default parser and are not necessarily supported by babel-eslint. Please see the section directly below for supported `parserOptions`.
|
**Note:** The `parserOptions` described in the [official documentation](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) are for the default parser and are not necessarily supported by @babel/eslint-parser. Please see the section directly below for supported `parserOptions`.
|
||||||
|
|
||||||
### Additional parser configuration
|
### Additional parser configuration
|
||||||
|
|
||||||
Additional configuration options can be set in your ESLint configuration under the `parserOptions` key. Please note that the `ecmaFeatures` config property may still be required for ESLint to work properly with features not in ECMAScript 5 by default.
|
Additional configuration options can be set in your ESLint configuration under the `parserOptions` key. Please note that the `ecmaFeatures` config property may still be required for ESLint to work properly with features not in ECMAScript 5 by default.
|
||||||
|
|
||||||
- `requireConfigFile` (default `true`) can be set to `false` to allow babel-eslint to run on files that do not have a Babel configuration associated with them. This can be useful for linting files that are not transformed by Babel (such as tooling configuration files), though we recommend using the default parser via [glob-based configuration](https://eslint.org/docs/user-guide/configuring#configuration-based-on-glob-patterns). Note: babel-eslint will not parse any experimental syntax when no configuration file is found.
|
- `requireConfigFile` (default `true`) can be set to `false` to allow @babel/eslint-parser to run on files that do not have a Babel configuration associated with them. This can be useful for linting files that are not transformed by Babel (such as tooling configuration files), though we recommend using the default parser via [glob-based configuration](https://eslint.org/docs/user-guide/configuring#configuration-based-on-glob-patterns). Note: @babel/eslint-parser will not parse any experimental syntax when no configuration file is found.
|
||||||
- `sourceType` can be set to `"module"`(default) or `"script"` if your code isn't using ECMAScript modules.
|
- `sourceType` can be set to `"module"`(default) or `"script"` if your code isn't using ECMAScript modules.
|
||||||
- `allowImportExportEverywhere` (default `false`) can be set to `true` to allow import and export declarations to appear anywhere a statement is allowed if your build environment supports that. Otherwise import and export declarations can only appear at a program's top level.
|
- `allowImportExportEverywhere` (default `false`) can be set to `true` to allow import and export declarations to appear anywhere a statement is allowed if your build environment supports that. Otherwise import and export declarations can only appear at a program's top level.
|
||||||
- `ecmaFeatures.globalReturn` (default `false`) allow return statements in the global scope when used with `sourceType: "script"`.
|
- `ecmaFeatures.globalReturn` (default `false`) allow return statements in the global scope when used with `sourceType: "script"`.
|
||||||
- `babelOptions` passes through Babel's configuration [loading](https://babeljs.io/docs/en/options#config-loading-options) and [merging](https://babeljs.io/docs/en/options#config-merging-options) options (for instance, in case of a monorepo). When not defined, babel-eslint will use Babel's default configuration file resolution logic.
|
- `babelOptions` passes through Babel's configuration [loading](https://babeljs.io/docs/en/options#config-loading-options) and [merging](https://babeljs.io/docs/en/options#config-merging-options) options (for instance, in case of a monorepo). When not defined, @babel/eslint-parser will use Babel's default configuration file resolution logic.
|
||||||
|
|
||||||
**.eslintrc.js**
|
**.eslintrc.js**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
module.exports = {
|
module.exports = {
|
||||||
parser: "babel-eslint",
|
parser: "@babel/eslint-parser",
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
sourceType: "module",
|
sourceType: "module",
|
||||||
allowImportExportEverywhere: false,
|
allowImportExportEverywhere: false,
|
||||||
@ -89,7 +85,7 @@ module.exports = {
|
|||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: ["files/transformed/by/babel/*.js"],
|
files: ["files/transformed/by/babel/*.js"],
|
||||||
parser: "babel-eslint",
|
parser: "@babel/eslint-parser",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@ -107,13 +103,13 @@ Flow:
|
|||||||
|
|
||||||
> Check out [eslint-plugin-flowtype](https://github.com/gajus/eslint-plugin-flowtype): An `eslint` plugin that makes flow type annotations global variables and marks declarations as used. Solves the problem of false positives with `no-undef` and `no-unused-vars`.
|
> Check out [eslint-plugin-flowtype](https://github.com/gajus/eslint-plugin-flowtype): An `eslint` plugin that makes flow type annotations global variables and marks declarations as used. Solves the problem of false positives with `no-undef` and `no-unused-vars`.
|
||||||
|
|
||||||
- `no-undef` for global flow types: `ReactElement`, `ReactClass` [#130](https://github.com/babel/babel-eslint/issues/130#issuecomment-111215076)
|
- `no-undef` for global flow types: `ReactElement`, `ReactClass` [#130](https://github.com/babel/@babel/eslint-parser/issues/130#issuecomment-111215076)
|
||||||
- Workaround: define types as globals in `.eslintrc` or define types and import them `import type ReactElement from './types'`
|
- Workaround: define types as globals in `.eslintrc` or define types and import them `import type ReactElement from './types'`
|
||||||
- `no-unused-vars/no-undef` with Flow declarations (`declare module A {}`) [#132](https://github.com/babel/babel-eslint/issues/132#issuecomment-112815926)
|
- `no-unused-vars/no-undef` with Flow declarations (`declare module A {}`) [#132](https://github.com/babel/@babel/eslint-parser/issues/132#issuecomment-112815926)
|
||||||
|
|
||||||
Modules/strict mode
|
Modules/strict mode
|
||||||
|
|
||||||
- `no-unused-vars: ["error", { vars: local }]` [#136](https://github.com/babel/babel-eslint/issues/136)
|
- `no-unused-vars: ["error", { vars: local }]` [#136](https://github.com/babel/@babel/eslint-parser/issues/136)
|
||||||
|
|
||||||
Please check out [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) for React/JSX issues.
|
Please check out [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) for React/JSX issues.
|
||||||
|
|
||||||
@ -123,6 +119,6 @@ Please check out [eslint-plugin-babel](https://github.com/babel/eslint-plugin-ba
|
|||||||
|
|
||||||
## Questions and support
|
## Questions and support
|
||||||
|
|
||||||
If you have an issue, please first check if it can be reproduced with the default parser and with the latest versions of `eslint` and `babel-eslint`. If it is not reproducible with the default parser, it is most likely an issue with babel-eslint.
|
If you have an issue, please first check if it can be reproduced with the default parser and with the latest versions of `eslint` and `@babel/eslint-parser`. If it is not reproducible with the default parser, it is most likely an issue with `@babel/eslint-parser`.
|
||||||
|
|
||||||
For questions and support please visit the [`#discussion`](https://babeljs.slack.com/messages/discussion/) Babel Slack channel (sign up [here](https://github.com/babel/notes/issues/38)) or the ESLint [Gitter](https://gitter.im/eslint/eslint).
|
For questions and support please visit the [`#discussion`](https://babeljs.slack.com/messages/discussion/) Babel Slack channel (sign up [here](https://github.com/babel/notes/issues/38)) or the ESLint [Gitter](https://gitter.im/eslint/eslint).
|
||||||
|
|||||||
@ -1,32 +1,30 @@
|
|||||||
{
|
{
|
||||||
"name": "babel-eslint",
|
"name": "@babel/eslint-parser",
|
||||||
"version": "11.0.0-beta.1",
|
"version": "0.0.0",
|
||||||
"description": "Custom parser for ESLint",
|
"description": "ESLint parser that allows for linting of experimental syntax transformed by Babel",
|
||||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/babel/babel-eslint.git"
|
"url": "https://github.com/babel/babel.git",
|
||||||
|
"directory": "eslint/babel-eslint-parser"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/babel/babel-eslint/issues"
|
"url": "https://github.com/babel/babel/issues"
|
||||||
},
|
|
||||||
"homepage": "https://github.com/babel/babel-eslint",
|
|
||||||
"scripts": {
|
|
||||||
"changelog": "git log `git describe --tags --abbrev=0`..HEAD --pretty=format:' * %s (%an)' | grep -v 'Merge pull request'"
|
|
||||||
},
|
},
|
||||||
|
"homepage": "https://github.com/babel/babel/tree/master/eslint/babel-eslint-parser",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=10.9"
|
||||||
},
|
},
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babel/core": ">=7.2.0",
|
"@babel/core": ">=7.2.0",
|
||||||
"eslint": ">= 4.12.1"
|
"eslint": ">= 6.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"eslint-scope": "3.7.1",
|
"eslint-scope": "5.0.0",
|
||||||
"eslint-visitor-keys": "^1.0.0",
|
"eslint-visitor-keys": "^1.1.0",
|
||||||
"semver": "^6.3.0"
|
"semver": "^6.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
"use strict";
|
import { types as t } from "@babel/core";
|
||||||
|
import escope from "eslint-scope";
|
||||||
const t = require("@babel/core").types;
|
import { Definition } from "eslint-scope/lib/definition";
|
||||||
const escope = require("eslint-scope");
|
import OriginalPatternVisitor from "eslint-scope/lib/pattern-visitor";
|
||||||
const Definition = require("eslint-scope/lib/definition").Definition;
|
import OriginalReferencer from "eslint-scope/lib/referencer";
|
||||||
const OriginalPatternVisitor = require("eslint-scope/lib/pattern-visitor");
|
import { getKeys as fallback } from "eslint-visitor-keys";
|
||||||
const OriginalReferencer = require("eslint-scope/lib/referencer");
|
import childVisitorKeys from "./visitor-keys";
|
||||||
const fallback = require("eslint-visitor-keys").getKeys;
|
|
||||||
const childVisitorKeys = require("./visitor-keys");
|
|
||||||
|
|
||||||
const flowFlippedAliasKeys = t.FLIPPED_ALIAS_KEYS.Flow.concat([
|
const flowFlippedAliasKeys = t.FLIPPED_ALIAS_KEYS.Flow.concat([
|
||||||
"ArrayPattern",
|
"ArrayPattern",
|
||||||
@ -18,13 +16,16 @@ const flowFlippedAliasKeys = t.FLIPPED_ALIAS_KEYS.Flow.concat([
|
|||||||
"ObjectPattern",
|
"ObjectPattern",
|
||||||
"RestElement",
|
"RestElement",
|
||||||
]);
|
]);
|
||||||
const visitorKeysMap = Object.keys(t.VISITOR_KEYS).reduce(function(acc, key) {
|
const visitorKeysMap = Object.entries(t.VISITOR_KEYS).reduce(function(
|
||||||
const value = t.VISITOR_KEYS[key];
|
acc,
|
||||||
|
[key, value],
|
||||||
|
) {
|
||||||
if (flowFlippedAliasKeys.indexOf(value) === -1) {
|
if (flowFlippedAliasKeys.indexOf(value) === -1) {
|
||||||
acc[key] = value;
|
acc[key] = value;
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
},
|
||||||
|
{});
|
||||||
|
|
||||||
const propertyTypes = {
|
const propertyTypes = {
|
||||||
// loops
|
// loops
|
||||||
@ -124,7 +125,7 @@ class Referencer extends OriginalReferencer {
|
|||||||
|
|
||||||
// inherits.
|
// inherits.
|
||||||
visitProperty(node) {
|
visitProperty(node) {
|
||||||
if (node.value && node.value.type === "TypeCastExpression") {
|
if (node.value?.type === "TypeCastExpression") {
|
||||||
this._visitTypeAnnotation(node.value);
|
this._visitTypeAnnotation(node.value);
|
||||||
}
|
}
|
||||||
this._visitArray(node.decorators);
|
this._visitArray(node.decorators);
|
||||||
@ -294,9 +295,9 @@ class Referencer extends OriginalReferencer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_checkIdentifierOrVisit(node) {
|
_checkIdentifierOrVisit(node) {
|
||||||
if (node && node.typeAnnotation) {
|
if (node?.typeAnnotation) {
|
||||||
this._visitTypeAnnotation(node.typeAnnotation);
|
this._visitTypeAnnotation(node.typeAnnotation);
|
||||||
} else if (node && node.type === "Identifier") {
|
} else if (node?.type === "Identifier") {
|
||||||
this.visit(node);
|
this.visit(node);
|
||||||
} else {
|
} else {
|
||||||
this._visitTypeAnnotation(node);
|
this._visitTypeAnnotation(node);
|
||||||
@ -312,7 +313,7 @@ class Referencer extends OriginalReferencer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function(ast, parserOptions) {
|
export default function(ast, parserOptions) {
|
||||||
const options = {
|
const options = {
|
||||||
ignoreEval: true,
|
ignoreEval: true,
|
||||||
optimistic: false,
|
optimistic: false,
|
||||||
@ -335,4 +336,4 @@ module.exports = function(ast, parserOptions) {
|
|||||||
referencer.visit(ast);
|
referencer.visit(ast);
|
||||||
|
|
||||||
return scopeManager;
|
return scopeManager;
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
"use strict";
|
import { types as t } from "@babel/core";
|
||||||
|
import convertProgramNode from "./convertProgramNode";
|
||||||
const t = require("@babel/core").types;
|
|
||||||
const convertProgramNode = require("./convertProgramNode");
|
|
||||||
|
|
||||||
module.exports = function(ast, traverse, code) {
|
module.exports = function(ast, traverse, code) {
|
||||||
const state = { source: code };
|
const state = { source: code };
|
||||||
@ -79,8 +77,8 @@ const astTransformVisitor = {
|
|||||||
|
|
||||||
// template string range fixes
|
// template string range fixes
|
||||||
if (path.isTemplateLiteral()) {
|
if (path.isTemplateLiteral()) {
|
||||||
for (let j = 0; j < node.quasis.length; j++) {
|
for (let i = 0; i < node.quasis.length; i++) {
|
||||||
const q = node.quasis[j];
|
const q = node.quasis[i];
|
||||||
q.range[0] -= 1;
|
q.range[0] -= 1;
|
||||||
if (q.tail) {
|
if (q.tail) {
|
||||||
q.range[1] += 1;
|
q.range[1] += 1;
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
"use strict";
|
export default function(comments) {
|
||||||
|
|
||||||
module.exports = function(comments) {
|
|
||||||
for (let i = 0; i < comments.length; i++) {
|
for (let i = 0; i < comments.length; i++) {
|
||||||
const comment = comments[i];
|
const comment = comments[i];
|
||||||
if (comment.type === "CommentBlock") {
|
if (comment.type === "CommentBlock") {
|
||||||
@ -14,4 +12,4 @@ module.exports = function(comments) {
|
|||||||
comment.range = [comment.start, comment.end];
|
comment.range = [comment.start, comment.end];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
"use strict";
|
export default function(ast) {
|
||||||
|
|
||||||
module.exports = function(ast) {
|
|
||||||
ast.type = "Program";
|
ast.type = "Program";
|
||||||
ast.sourceType = ast.program.sourceType;
|
ast.sourceType = ast.program.sourceType;
|
||||||
ast.directives = ast.program.directives;
|
ast.directives = ast.program.directives;
|
||||||
@ -37,4 +35,4 @@ module.exports = function(ast) {
|
|||||||
ast.loc.start.line = ast.body[0].loc.start.line;
|
ast.loc.start.line = ast.body[0].loc.start.line;
|
||||||
ast.range[0] = ast.body[0].start;
|
ast.range[0] = ast.body[0].start;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
"use strict";
|
export default function(tokens, tt) {
|
||||||
|
|
||||||
module.exports = function(tokens, tt) {
|
|
||||||
let curlyBrace = null;
|
let curlyBrace = null;
|
||||||
let templateTokens = [];
|
let templateTokens = [];
|
||||||
const result = [];
|
const result = [];
|
||||||
@ -89,4 +87,4 @@ module.exports = function(tokens, tt) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
"use strict";
|
export default function(token, tt, source) {
|
||||||
|
|
||||||
module.exports = function(token, tt, source) {
|
|
||||||
const type = token.type;
|
const type = token.type;
|
||||||
token.range = [token.start, token.end];
|
token.range = [token.start, token.end];
|
||||||
|
|
||||||
@ -82,4 +80,4 @@ module.exports = function(token, tt, source) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
"use strict";
|
import convertTemplateType from "./convertTemplateType";
|
||||||
|
import convertToken from "./convertToken";
|
||||||
|
|
||||||
const convertTemplateType = require("./convertTemplateType");
|
export default function(tokens, tt, code) {
|
||||||
const convertToken = require("./convertToken");
|
|
||||||
|
|
||||||
module.exports = function(tokens, tt, code) {
|
|
||||||
return convertTemplateType(tokens, tt)
|
return convertTemplateType(tokens, tt)
|
||||||
.filter(t => t.type !== "CommentLine" && t.type !== "CommentBlock")
|
.filter(t => t.type !== "CommentLine" && t.type !== "CommentBlock")
|
||||||
.map(t => convertToken(t, tt, code));
|
.map(t => convertToken(t, tt, code));
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
"use strict";
|
import convertTokens from "./convertTokens";
|
||||||
|
import convertComments from "./convertComments";
|
||||||
|
import convertAST from "./convertAST";
|
||||||
|
|
||||||
const convertTokens = require("./convertTokens");
|
export default function(ast, traverse, tt, code) {
|
||||||
const convertComments = require("./convertComments");
|
|
||||||
const convertAST = require("./convertAST");
|
|
||||||
|
|
||||||
module.exports = function(ast, traverse, tt, code) {
|
|
||||||
ast.tokens = convertTokens(ast.tokens, tt, code);
|
ast.tokens = convertTokens(ast.tokens, tt, code);
|
||||||
convertComments(ast.comments);
|
convertComments(ast.comments);
|
||||||
convertAST(ast, traverse, code);
|
convertAST(ast, traverse, code);
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
"use strict";
|
import semver from "semver";
|
||||||
|
import { version as CURRENT_BABEL_VERSION } from "@babel/core";
|
||||||
|
import parseWithScope from "./parse-with-scope";
|
||||||
|
import packageJson from "../package.json";
|
||||||
|
|
||||||
const semver = require("semver");
|
|
||||||
const babelCore = require("@babel/core");
|
|
||||||
const packageJson = require("../package.json");
|
|
||||||
|
|
||||||
const CURRENT_BABEL_VERSION = babelCore.version;
|
|
||||||
const SUPPORTED_BABEL_VERSION_RANGE =
|
const SUPPORTED_BABEL_VERSION_RANGE =
|
||||||
packageJson.peerDependencies["@babel/core"];
|
packageJson.peerDependencies["@babel/core"];
|
||||||
const IS_RUNNING_SUPPORTED_VERSION = semver.satisfies(
|
const IS_RUNNING_SUPPORTED_VERSION = semver.satisfies(
|
||||||
@ -12,11 +10,11 @@ const IS_RUNNING_SUPPORTED_VERSION = semver.satisfies(
|
|||||||
SUPPORTED_BABEL_VERSION_RANGE,
|
SUPPORTED_BABEL_VERSION_RANGE,
|
||||||
);
|
);
|
||||||
|
|
||||||
exports.parse = function(code, options) {
|
export function parse(code, options) {
|
||||||
return exports.parseForESLint(code, options).ast;
|
return exports.parseForESLint(code, options).ast;
|
||||||
};
|
}
|
||||||
|
|
||||||
exports.parseForESLint = function(code, options = {}) {
|
export function parseForESLint(code, options = {}) {
|
||||||
if (!IS_RUNNING_SUPPORTED_VERSION) {
|
if (!IS_RUNNING_SUPPORTED_VERSION) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`babel-eslint@${packageJson.version} does not support @babel/core@${CURRENT_BABEL_VERSION}. Please downgrade to babel-eslint@^10 or upgrade to @babel/core@${SUPPORTED_BABEL_VERSION_RANGE}`,
|
`babel-eslint@${packageJson.version} does not support @babel/core@${CURRENT_BABEL_VERSION}. Please downgrade to babel-eslint@^10 or upgrade to @babel/core@${SUPPORTED_BABEL_VERSION_RANGE}`,
|
||||||
@ -29,5 +27,5 @@ exports.parseForESLint = function(code, options = {}) {
|
|||||||
options.allowImportExportEverywhere =
|
options.allowImportExportEverywhere =
|
||||||
options.allowImportExportEverywhere || false;
|
options.allowImportExportEverywhere || false;
|
||||||
|
|
||||||
return require("./parse-with-scope")(code, options);
|
return parseWithScope(code, options);
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
"use strict";
|
import visitorKeys from "./visitor-keys";
|
||||||
|
import analyzeScope from "./analyze-scope";
|
||||||
|
import parse from "./parse";
|
||||||
|
|
||||||
const visitorKeys = require("./visitor-keys");
|
export default function(code, options) {
|
||||||
const analyzeScope = require("./analyze-scope");
|
|
||||||
const parse = require("./parse");
|
|
||||||
|
|
||||||
module.exports = function(code, options) {
|
|
||||||
const ast = parse(code, options);
|
const ast = parse(code, options);
|
||||||
const scopeManager = analyzeScope(ast, options);
|
const scopeManager = analyzeScope(ast, options);
|
||||||
|
|
||||||
return { ast, scopeManager, visitorKeys };
|
return { ast, scopeManager, visitorKeys };
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
"use strict";
|
import babylonToEspree from "./babylon-to-espree";
|
||||||
|
import {
|
||||||
const babylonToEspree = require("./babylon-to-espree");
|
parseSync as parse,
|
||||||
const {
|
tokTypes as tt,
|
||||||
parseSync: parse,
|
|
||||||
tokTypes: tt,
|
|
||||||
traverse,
|
traverse,
|
||||||
loadPartialConfig,
|
loadPartialConfig,
|
||||||
} = require("@babel/core");
|
} from "@babel/core";
|
||||||
|
|
||||||
module.exports = function(code, options) {
|
export default function(code, options) {
|
||||||
let opts = {
|
let opts = {
|
||||||
sourceType: options.sourceType,
|
sourceType: options.sourceType,
|
||||||
filename: options.filePath,
|
filename: options.filePath,
|
||||||
@ -70,4 +68,4 @@ module.exports = function(code, options) {
|
|||||||
babylonToEspree(ast, traverse, tt, code);
|
babylonToEspree(ast, traverse, tt, code);
|
||||||
|
|
||||||
return ast;
|
return ast;
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
"use strict";
|
import { types as t } from "@babel/core";
|
||||||
|
import { KEYS as ESLINT_VISITOR_KEYS } from "eslint-visitor-keys";
|
||||||
|
|
||||||
const BABEL_VISITOR_KEYS = require("@babel/core").types.VISITOR_KEYS;
|
const { VISITOR_KEYS: BABEL_VISITOR_KEYS } = t;
|
||||||
const ESLINT_VISITOR_KEYS = require("eslint-visitor-keys").KEYS;
|
|
||||||
|
|
||||||
module.exports = Object.assign(
|
export default Object.assign(
|
||||||
{
|
{
|
||||||
Literal: ESLINT_VISITOR_KEYS.Literal,
|
Literal: ESLINT_VISITOR_KEYS.Literal,
|
||||||
MethodDefinition: ["decorators"].concat(
|
MethodDefinition: ["decorators"].concat(
|
||||||
|
|||||||
@ -1,19 +1,14 @@
|
|||||||
"use strict";
|
import assert from "assert";
|
||||||
|
import path from "path";
|
||||||
const assert = require("assert");
|
import espree from "espree";
|
||||||
const path = require("path");
|
import escope from "eslint-scope";
|
||||||
const babelEslint = require("../");
|
import unpad from "dedent";
|
||||||
const espree = require("espree");
|
import { parseForESLint } from "../src";
|
||||||
const escope = require("eslint-scope");
|
import assertImplementsAST from "./helpers/assert-implements-ast";
|
||||||
const unpad = require("dedent");
|
|
||||||
const assertImplementsAST = require("./helpers/assert-implements-ast");
|
|
||||||
|
|
||||||
const babelOptions = {
|
const babelOptions = {
|
||||||
configFile: path.resolve(
|
configFile: path.resolve(__dirname, "./fixtures/config/babel.config.js"),
|
||||||
__dirname,
|
};
|
||||||
"./fixtures/config/babel.config.js"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseAndAssertSame(code) {
|
function parseAndAssertSame(code) {
|
||||||
code = unpad(code);
|
code = unpad(code);
|
||||||
@ -35,7 +30,7 @@ function parseAndAssertSame(code) {
|
|||||||
ecmaVersion: 2018,
|
ecmaVersion: 2018,
|
||||||
sourceType: "module",
|
sourceType: "module",
|
||||||
});
|
});
|
||||||
const babylonAST = babelEslint.parseForESLint(code, {
|
const babylonAST = parseForESLint(code, {
|
||||||
eslintVisitorKeys: true,
|
eslintVisitorKeys: true,
|
||||||
eslintScopeManager: true,
|
eslintScopeManager: true,
|
||||||
babelOptions,
|
babelOptions,
|
||||||
@ -46,14 +41,14 @@ function parseAndAssertSame(code) {
|
|||||||
describe("babylon-to-espree", () => {
|
describe("babylon-to-espree", () => {
|
||||||
describe("compatibility", () => {
|
describe("compatibility", () => {
|
||||||
it("should allow ast.analyze to be called without options", function() {
|
it("should allow ast.analyze to be called without options", function() {
|
||||||
const esAST = babelEslint.parseForESLint("`test`", {
|
const esAST = parseForESLint("`test`", {
|
||||||
eslintScopeManager: true,
|
eslintScopeManager: true,
|
||||||
eslintVisitorKeys: true,
|
eslintVisitorKeys: true,
|
||||||
babelOptions,
|
babelOptions,
|
||||||
}).ast;
|
}).ast;
|
||||||
expect(() => {
|
expect(() => {
|
||||||
escope.analyze(esAST)
|
escope.analyze(esAST);
|
||||||
}).not.toThrow(new TypeError('Should allow no options argument.'));
|
}).not.toThrow(new TypeError("Should allow no options argument."));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -100,13 +95,13 @@ describe("babylon-to-espree", () => {
|
|||||||
|
|
||||||
it("template with nested function/object", () => {
|
it("template with nested function/object", () => {
|
||||||
parseAndAssertSame(
|
parseAndAssertSame(
|
||||||
"`outer${{x: {y: 10}}}bar${`nested${function(){return 1;}}endnest`}end`"
|
"`outer${{x: {y: 10}}}bar${`nested${function(){return 1;}}endnest`}end`",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("template with braces inside and outside of template string #96", () => {
|
it("template with braces inside and outside of template string #96", () => {
|
||||||
parseAndAssertSame(
|
parseAndAssertSame(
|
||||||
"if (a) { var target = `{}a:${webpackPort}{}}}}`; } else { app.use(); }"
|
"if (a) { var target = `{}a:${webpackPort}{}}}}`; } else { app.use(); }",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -245,7 +240,7 @@ describe("babylon-to-espree", () => {
|
|||||||
// Espree doesn't support the optional chaining operator yet
|
// Espree doesn't support the optional chaining operator yet
|
||||||
it("optional chaining operator (token)", () => {
|
it("optional chaining operator (token)", () => {
|
||||||
const code = "foo?.bar";
|
const code = "foo?.bar";
|
||||||
const babylonAST = babelEslint.parseForESLint(code, {
|
const babylonAST = parseForESLint(code, {
|
||||||
eslintVisitorKeys: true,
|
eslintVisitorKeys: true,
|
||||||
eslintScopeManager: true,
|
eslintScopeManager: true,
|
||||||
babelOptions,
|
babelOptions,
|
||||||
@ -256,7 +251,7 @@ describe("babylon-to-espree", () => {
|
|||||||
// Espree doesn't support the nullish coalescing operator yet
|
// Espree doesn't support the nullish coalescing operator yet
|
||||||
it("nullish coalescing operator (token)", () => {
|
it("nullish coalescing operator (token)", () => {
|
||||||
const code = "foo ?? bar";
|
const code = "foo ?? bar";
|
||||||
const babylonAST = babelEslint.parseForESLint(code, {
|
const babylonAST = parseForESLint(code, {
|
||||||
eslintVisitorKeys: true,
|
eslintVisitorKeys: true,
|
||||||
eslintScopeManager: true,
|
eslintScopeManager: true,
|
||||||
babelOptions,
|
babelOptions,
|
||||||
@ -267,7 +262,7 @@ describe("babylon-to-espree", () => {
|
|||||||
// Espree doesn't support the pipeline operator yet
|
// Espree doesn't support the pipeline operator yet
|
||||||
it("pipeline operator (token)", () => {
|
it("pipeline operator (token)", () => {
|
||||||
const code = "foo |> bar";
|
const code = "foo |> bar";
|
||||||
const babylonAST = babelEslint.parseForESLint(code, {
|
const babylonAST = parseForESLint(code, {
|
||||||
eslintVisitorKeys: true,
|
eslintVisitorKeys: true,
|
||||||
eslintScopeManager: true,
|
eslintScopeManager: true,
|
||||||
babelOptions,
|
babelOptions,
|
||||||
@ -278,7 +273,7 @@ describe("babylon-to-espree", () => {
|
|||||||
// Espree doesn't support the private fields yet
|
// Espree doesn't support the private fields yet
|
||||||
it("hash (token)", () => {
|
it("hash (token)", () => {
|
||||||
const code = "class A { #x }";
|
const code = "class A { #x }";
|
||||||
const babylonAST = babelEslint.parseForESLint(code, {
|
const babylonAST = parseForESLint(code, {
|
||||||
eslintVisitorKeys: true,
|
eslintVisitorKeys: true,
|
||||||
eslintScopeManager: true,
|
eslintScopeManager: true,
|
||||||
babelOptions,
|
babelOptions,
|
||||||
@ -398,7 +393,7 @@ describe("babylon-to-espree", () => {
|
|||||||
|
|
||||||
it("MethodDefinition 2", () => {
|
it("MethodDefinition 2", () => {
|
||||||
parseAndAssertSame(
|
parseAndAssertSame(
|
||||||
"export default class Bar { get bar() { return 42; }}"
|
"export default class Bar { get bar() { return 42; }}",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1,7 +1,5 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
// Checks if the source ast implements the target ast. Ignores extra keys on source ast
|
// Checks if the source ast implements the target ast. Ignores extra keys on source ast
|
||||||
module.exports = function assertImplementsAST(target, source, path) {
|
export default function assertImplementsAST(target, source, path) {
|
||||||
if (!path) {
|
if (!path) {
|
||||||
path = [];
|
path = [];
|
||||||
}
|
}
|
||||||
@ -16,7 +14,7 @@ module.exports = function assertImplementsAST(target, source, path) {
|
|||||||
const typeB = source === null ? "null" : typeof source;
|
const typeB = source === null ? "null" : typeof source;
|
||||||
if (typeA !== typeB) {
|
if (typeA !== typeB) {
|
||||||
error(
|
error(
|
||||||
`have different types (${typeA} !== ${typeB}) (${target} !== ${source})`
|
`have different types (${typeA} !== ${typeB}) (${target} !== ${source})`,
|
||||||
);
|
);
|
||||||
} else if (
|
} else if (
|
||||||
typeA === "object" &&
|
typeA === "object" &&
|
||||||
@ -24,7 +22,7 @@ module.exports = function assertImplementsAST(target, source, path) {
|
|||||||
target.constructor.name !== source.constructor.name
|
target.constructor.name !== source.constructor.name
|
||||||
) {
|
) {
|
||||||
error(
|
error(
|
||||||
`object have different constructors (${target.constructor.name} !== ${source.constructor.name}`
|
`object have different constructors (${target.constructor.name} !== ${source.constructor.name}`,
|
||||||
);
|
);
|
||||||
} else if (typeA === "object") {
|
} else if (typeA === "object") {
|
||||||
const keysTarget = Object.keys(target);
|
const keysTarget = Object.keys(target);
|
||||||
@ -36,7 +34,7 @@ module.exports = function assertImplementsAST(target, source, path) {
|
|||||||
}
|
}
|
||||||
} else if (target !== source) {
|
} else if (target !== source) {
|
||||||
error(
|
error(
|
||||||
`are different (${JSON.stringify(target)} !== ${JSON.stringify(source)})`
|
`are different (${JSON.stringify(target)} !== ${JSON.stringify(source)})`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
"use strict";
|
import eslint from "eslint";
|
||||||
|
import fs from "fs";
|
||||||
const eslint = require("eslint");
|
import path from "path";
|
||||||
const fs = require("fs");
|
import * as parser from "../src";
|
||||||
const path = require("path");
|
|
||||||
|
|
||||||
const parser = require("../");
|
|
||||||
|
|
||||||
eslint.linter.defineParser("current-babel-eslint", parser);
|
eslint.linter.defineParser("current-babel-eslint", parser);
|
||||||
|
|
||||||
@ -72,7 +69,7 @@ function strictSuite() {
|
|||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
expect(report[0].ruleId).toBe(ruleId);
|
expect(report[0].ruleId).toBe(ruleId);
|
||||||
done();
|
done();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// it
|
// it
|
||||||
@ -96,7 +93,7 @@ function strictSuite() {
|
|||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
expect(report.length).toBe(0);
|
expect(report.length).toBe(0);
|
||||||
done();
|
done();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// it
|
// it
|
||||||
@ -113,7 +110,7 @@ function strictSuite() {
|
|||||||
expect(report[0].ruleId).toBe(ruleId);
|
expect(report[0].ruleId).toBe(ruleId);
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// it
|
// it
|
||||||
@ -133,7 +130,7 @@ function strictSuite() {
|
|||||||
// result of the previous assertion.
|
// result of the previous assertion.
|
||||||
expect(report[0].nodeType).not.toBe("Program");
|
expect(report[0].nodeType).not.toBe("Program");
|
||||||
done();
|
done();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// it
|
// it
|
||||||
@ -148,7 +145,7 @@ function strictSuite() {
|
|||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
expect(report[0].ruleId).toBe(ruleId);
|
expect(report[0].ruleId).toBe(ruleId);
|
||||||
done();
|
done();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// it
|
// it
|
||||||
@ -171,7 +168,7 @@ function strictSuite() {
|
|||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
expect(report.length).toBe(0);
|
expect(report.length).toBe(0);
|
||||||
done();
|
done();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// it
|
// it
|
||||||
@ -188,7 +185,7 @@ function strictSuite() {
|
|||||||
expect(report[i].ruleId).toBe(ruleId);
|
expect(report[i].ruleId).toBe(ruleId);
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// it
|
// it
|
||||||
@ -203,7 +200,7 @@ function strictSuite() {
|
|||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
expect(report[0].ruleId).toBe(ruleId);
|
expect(report[0].ruleId).toBe(ruleId);
|
||||||
done();
|
done();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// it
|
// it
|
||||||
@ -219,7 +216,7 @@ function strictSuite() {
|
|||||||
expect(report[0].ruleId).toBe(ruleId);
|
expect(report[0].ruleId).toBe(ruleId);
|
||||||
expect(report[0].nodeType.indexOf("Function")).toBe(-1);
|
expect(report[0].nodeType.indexOf("Function")).toBe(-1);
|
||||||
done();
|
done();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// it
|
// it
|
||||||
@ -229,10 +226,10 @@ function strictSuite() {
|
|||||||
describe("https://github.com/babel/babel-eslint/issues/558", () => {
|
describe("https://github.com/babel/babel-eslint/issues/558", () => {
|
||||||
it("doesn't crash with eslint-plugin-import", () => {
|
it("doesn't crash with eslint-plugin-import", () => {
|
||||||
const engine = new eslint.CLIEngine({ ignore: false });
|
const engine = new eslint.CLIEngine({ ignore: false });
|
||||||
const files = ['a.js', 'b.js', 'c.js'];
|
const files = ["a.js", "b.js", "c.js"];
|
||||||
let fileWithPath = files.map(file =>
|
let fileWithPath = files.map(file =>
|
||||||
path.resolve(__dirname, `./fixtures/eslint-plugin-import/${file}`));
|
path.resolve(__dirname, `./fixtures/eslint-plugin-import/${file}`),
|
||||||
|
);
|
||||||
engine.executeOnFiles(fileWithPath);
|
engine.executeOnFiles(fileWithPath);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
"use strict";
|
import eslint from "eslint";
|
||||||
|
import path from "path";
|
||||||
const eslint = require("eslint");
|
import unpad from "dedent";
|
||||||
const path = require("path");
|
import * as parser from "../src";
|
||||||
const unpad = require("dedent");
|
|
||||||
|
|
||||||
const parser = require("../");
|
|
||||||
|
|
||||||
function verifyAndAssertMessagesWithSpecificESLint(
|
function verifyAndAssertMessagesWithSpecificESLint(
|
||||||
code,
|
code,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user