Compare commits
149 Commits
v7.7.4-csx
...
initialize
| Author | SHA1 | Date | |
|---|---|---|---|
| 41fd81a8f5 | |||
| bfa97fe782 | |||
| 1518210ee6 | |||
| b1facb18de | |||
| 2c38b52ffb | |||
| 44e7cf615c | |||
| 983ab3bbc0 | |||
| 05dfb60683 | |||
|
|
a8e859bb05 | ||
| f3c530b2c9 | |||
| a12f1771c8 | |||
| fad999bf52 | |||
| 2707780f7e | |||
|
|
b138b5a62e | ||
|
|
a7620bd266 | ||
|
|
6874c244ab | ||
|
|
8fce431d88 | ||
|
|
d0a8982c12 | ||
|
|
a677d59a63 | ||
|
|
c7f7f9b8b5 | ||
|
|
61d01f1114 | ||
|
|
f995f8e02c | ||
|
|
2ccc451e96 | ||
|
|
575eeb370e | ||
|
|
27668377b5 | ||
|
|
d1c93e7e3e | ||
|
|
9647560dd6 | ||
|
|
2486615a74 | ||
|
|
d8e6219ad9 | ||
|
|
81c5f1f22d | ||
|
|
e7b80a2cb9 | ||
|
|
405c1aaad8 | ||
|
|
a1310333f7 | ||
|
|
903ad6160d | ||
|
|
5a3e97073e | ||
|
|
4c28f54152 | ||
|
|
ae06baf22f | ||
|
|
282f81bd67 | ||
|
|
9fec528016 | ||
|
|
80aa7dc3c6 | ||
|
|
4cb2148273 | ||
|
|
3dcb8ca99e | ||
|
|
bfc56ebbab | ||
|
|
e8dac621de | ||
|
|
44f9d85904 | ||
|
|
04354d1556 | ||
|
|
5f807ae45b | ||
|
|
646409b23e | ||
|
|
8415065d99 | ||
|
|
3af02f63de | ||
|
|
c3388ea42f | ||
|
|
5b907e9bb7 | ||
|
|
7bc22e42f5 | ||
|
|
771c730fda | ||
|
|
9f148a1603 | ||
|
|
09cb4273bc | ||
|
|
8fd532db39 | ||
|
|
3fa37d2da3 | ||
|
|
4636321f06 | ||
|
|
a7dac49518 | ||
|
|
03d163a0d9 | ||
|
|
455d782ef0 | ||
|
|
a28353703f | ||
|
|
467667af88 | ||
|
|
6ee8c97e6a | ||
|
|
e5048053aa | ||
|
|
9f832c2716 | ||
|
|
daaa2063bb | ||
|
|
26eb891870 | ||
|
|
0238244268 | ||
|
|
2f3f77926d | ||
|
|
30449fe05d | ||
|
|
86245a83a2 | ||
|
|
197a8da04d | ||
|
|
314513374d | ||
|
|
b91720c1cc | ||
|
|
e9dc74e787 | ||
|
|
30f3b07ebf | ||
|
|
db3c31a8af | ||
|
|
00758308ae | ||
|
|
fc5365fe4a | ||
|
|
ee5b79d75d | ||
|
|
875e9619b7 | ||
|
|
a18166d2a9 | ||
|
|
c09664f35d | ||
|
|
83993b08d5 | ||
|
|
f651f22f96 | ||
|
|
416ce35638 | ||
|
|
c5cfc83182 | ||
|
|
d389b702e6 | ||
|
|
aaa1b1f4b0 | ||
|
|
12da0941c8 | ||
|
|
9be27bcfea | ||
|
|
c0d0bf2e5e | ||
|
|
e85c9b9ec8 | ||
|
|
80e95d0c83 | ||
|
|
dbf3f91f1e | ||
|
|
aa814073b7 | ||
|
|
8afeef2d96 | ||
|
|
3d7bc435d5 | ||
|
|
2b3590929b | ||
|
|
b3c7df9314 | ||
|
|
ff8a295ea7 | ||
|
|
c35ba3d3ab | ||
|
|
4f77a5aaad | ||
|
|
0e9c49606a | ||
|
|
a0d76a8c0e | ||
|
|
bffa415b83 | ||
|
|
0b3f883ed1 | ||
|
|
25f7e6808e | ||
|
|
7b54a94389 | ||
|
|
5156d3ea06 | ||
|
|
20e43ad103 | ||
|
|
de1fa902f0 | ||
|
|
f02e5e6d0a | ||
|
|
2884bac44b | ||
|
|
b7989419c7 | ||
|
|
0164662944 | ||
|
|
fb100eee41 | ||
|
|
b2429fe203 | ||
|
|
f753c48f74 | ||
|
|
4436ffd604 | ||
|
|
655a972737 | ||
|
|
8a8474c321 | ||
|
|
d04508e510 | ||
|
|
d3a37b5d08 | ||
|
|
c9a68984d6 | ||
|
|
c6e966cac9 | ||
|
|
a0bed42aec | ||
|
|
2b472912e4 | ||
|
|
e94da0dce5 | ||
|
|
bb6cc61979 | ||
|
|
3d0c5d2afc | ||
|
|
d18afbd7c3 | ||
|
|
e74efd2c0a | ||
|
|
7195f0d8cf | ||
|
|
5440ae1cae | ||
|
|
8f89167486 | ||
|
|
26c0a32c7c | ||
|
|
a6e8b3843b | ||
|
|
4e774b7264 | ||
|
|
7f732ad019 | ||
|
|
e81bbd69b3 | ||
|
|
52f964126d | ||
|
|
01c33a5719 | ||
|
|
66a70267b6 | ||
|
|
0b06b23b00 | ||
|
|
e239eb4c55 | ||
|
|
d38c4dd57b |
@@ -48,23 +48,25 @@ executors:
|
||||
docker:
|
||||
- image: circleci/node:13
|
||||
working_directory: ~/babel
|
||||
# e2e-vue-cli test requires chromium
|
||||
node-browsers-executor:
|
||||
docker:
|
||||
- image: circleci/node:13-browsers
|
||||
working_directory: ~/babel
|
||||
|
||||
jobs:
|
||||
test:
|
||||
build-standalone:
|
||||
executor: node-executor
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache: *restore-yarn-cache
|
||||
- restore_cache: *restore-node-modules-cache
|
||||
- run: yarn --version
|
||||
- run: make test-ci-coverage
|
||||
# Builds babel-standalone with the regular Babel config
|
||||
- run: IS_PUBLISH=true make build
|
||||
# test-ci-coverage doesn't test babel-standalone, as trying to gather coverage
|
||||
# data for a JS file that's several megabytes large is bound to fail. Here,
|
||||
# we just run the babel-standalone test separately.
|
||||
- run: ./node_modules/.bin/jest packages/babel-standalone/test/
|
||||
- run: ./node_modules/.bin/jest packages/babel-preset-env-standalone/test/
|
||||
# Builds babel-standalone with the regular Babel config
|
||||
# test-ci-coverage doesn't test babel-standalone, as trying to gather coverage
|
||||
- run: IS_PUBLISH=true make -j build-standalone-ci
|
||||
# data for a JS file that's several megabytes large is bound to fail. Here,
|
||||
# we just run the babel-standalone test separately.
|
||||
- run: yarn jest "\-standalone/test"
|
||||
- store_artifacts: *artifact_babel
|
||||
- store_artifacts: *artifact_babel_min
|
||||
- store_artifacts: *artifact_env
|
||||
@@ -125,6 +127,8 @@ jobs:
|
||||
cat ~/diff.tap | $(npm bin)/tap-merge | $(npm bin)/tap-mocha-reporter xunit | tee ~/test-results/test262/results.xml
|
||||
<<: *test262_workdir
|
||||
- store_test_results: *artifact_test262_xunit
|
||||
- save_cache: *save-node-modules-cache
|
||||
- save_cache: *save-yarn-cache
|
||||
|
||||
publish-verdaccio:
|
||||
executor: node-executor
|
||||
@@ -146,11 +150,27 @@ jobs:
|
||||
at: /tmp/verdaccio-workspace
|
||||
- run: ./scripts/integration-tests/e2e-babel.sh
|
||||
|
||||
e2e-create-react-app:
|
||||
executor: node-executor
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/verdaccio-workspace
|
||||
- run: ./scripts/integration-tests/e2e-create-react-app.sh
|
||||
|
||||
e2e-vue-cli:
|
||||
executor: node-browsers-executor
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/verdaccio-workspace
|
||||
- run: ./scripts/integration-tests/e2e-vue-cli.sh
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
test:
|
||||
build-standalone:
|
||||
jobs:
|
||||
- test
|
||||
- build-standalone
|
||||
test262-master:
|
||||
jobs:
|
||||
- test262:
|
||||
@@ -179,3 +199,10 @@ workflows:
|
||||
- e2e-babel:
|
||||
requires:
|
||||
- publish-verdaccio
|
||||
- e2e-create-react-app:
|
||||
requires:
|
||||
- publish-verdaccio
|
||||
- e2e-vue-cli:
|
||||
requires:
|
||||
- publish-verdaccio
|
||||
|
||||
|
||||
5
.codesandbox/ci.json
Normal file
5
.codesandbox/ci.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"installCommand": "bootstrap",
|
||||
"buildCommand": false,
|
||||
"sandboxes": ["kypop"]
|
||||
}
|
||||
@@ -17,7 +17,7 @@ codemods/*/lib
|
||||
codemods/*/dist
|
||||
codemods/*/test/fixtures
|
||||
codemods/*/test/tmp
|
||||
packages/babel-preset-env/data
|
||||
packages/babel-preset-env/data/[^(plugin-features|shipped-proposals).js]
|
||||
packages/babel-preset-env/test/debug-fixtures
|
||||
packages/babel-preset-env-standalone/babel-preset-env.js
|
||||
packages/babel-preset-env-standalone/babel-preset-env.min.js
|
||||
|
||||
5
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
5
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -9,6 +9,9 @@ assignees: ''
|
||||
|
||||
## Bug Report
|
||||
|
||||
<!-- Check this if you would like to implement a PR, we are more than happy to help you go through the process !-->
|
||||
- [ ] I would like to work on a fix!
|
||||
|
||||
<!--
|
||||
@babel/eslint-parser:
|
||||
If you are having issues with JSX you might want to check out eslint-plugin-react. If there's an issue with new experimental syntax you might need check if it's supported by @babel/eslint-plugin.
|
||||
@@ -48,7 +51,7 @@ A clear and concise description of what you expected to happen (or code).
|
||||
- How you are using Babel: [e.g. `cli`, `register`, `loader`]
|
||||
|
||||
**Possible Solution**
|
||||
<!--- Only if you have suggestions on a fix for the bug -->
|
||||
<!--- If you have suggestions on a fix for the bug -->
|
||||
|
||||
**Additional context/Screenshots**
|
||||
Add any other context about the problem here. If applicable, add screenshots to help explain.
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
3
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
@@ -9,6 +9,9 @@ assignees: ''
|
||||
|
||||
## Feature Request
|
||||
|
||||
<!-- Check this if you would like to implement a PR, we are more than happy to help you go through the process !-->
|
||||
- [ ] I would like to work on this feature!
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I have an issue when [...]
|
||||
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/Regression-v7.md
vendored
3
.github/ISSUE_TEMPLATE/Regression-v7.md
vendored
@@ -10,6 +10,9 @@ assignees: ''
|
||||
|
||||
# v7 Regression
|
||||
|
||||
<!-- Check this if you would like to implement a PR, we are more than happy to help you go through the process !-->
|
||||
- [ ] I would like to work on a fix!
|
||||
|
||||
> First check out: https://babeljs.io/docs/en/v7-migration
|
||||
> Also a partial upgrade tool: https://github.com/babel/babel-upgrade
|
||||
|
||||
|
||||
29
.github/workflows/coverage.yml
vendored
Normal file
29
.github/workflows/coverage.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: Report Coverage
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [13.x]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Environment log
|
||||
id: env
|
||||
run: |
|
||||
yarn --version
|
||||
- name: Generate coverage report
|
||||
run: |
|
||||
yarn --version
|
||||
make -j test-ci-coverage
|
||||
- name: Upload coverage report
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -20,6 +20,8 @@ dist
|
||||
package-lock.json
|
||||
!/.github/actions/*/package-lock.json
|
||||
|
||||
/packages/babel-compat-data/build
|
||||
|
||||
/packages/babel-runtime/helpers/*.js
|
||||
!/packages/babel-runtime/helpers/toArray.js
|
||||
!/packages/babel-runtime/helpers/iterableToArray.js
|
||||
@@ -52,8 +54,10 @@ package-lock.json
|
||||
.nyc_output
|
||||
/babel.sublime-workspace
|
||||
packages/babel-standalone/babel.js
|
||||
packages/babel-standalone/babel.js.map
|
||||
packages/babel-standalone/babel.min.js
|
||||
packages/babel-preset-env-standalone/babel-preset-env.js
|
||||
packages/babel-preset-env-standalone/babel-preset-env.js.map
|
||||
packages/babel-preset-env-standalone/babel-preset-env.min.js
|
||||
/codemods/*/lib
|
||||
/codemods/*/node_modules
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package.json
|
||||
packages/babel-preset-env/data
|
||||
packages/babel-compat-data/data
|
||||
packages/babel-compat-data/scripts/data/overlapping-plugins.js
|
||||
packages/*/test/fixtures/**/input.*
|
||||
packages/*/test/fixtures/**/exec.*
|
||||
packages/*/test/fixtures/**/output.*
|
||||
|
||||
@@ -20,6 +20,7 @@ script:
|
||||
- if [ "$JOB" = "test" ]; then make -j test-ci; fi
|
||||
- if [ "$JOB" = "lint" ]; then make -j code-quality-ci; fi
|
||||
- if [ "$JOB" = "babel-parser-flow-tests" ]; then make -j test-flow-ci; fi
|
||||
- if [ "$JOB" = "babel-parser-typescript-tests" ]; then make -j test-typescript-ci; fi
|
||||
- if [ "$JOB" = "babel-parser-test262-tests" ]; then make -j test-test262-ci; fi
|
||||
|
||||
matrix:
|
||||
@@ -36,12 +37,18 @@ matrix:
|
||||
- JOB=test
|
||||
# https://travis-ci.community/t/build-doesnt-finish-after-completing-tests/288/9
|
||||
- YARN_GPG=no
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- $HOME/AppData/Local/Temp/chocolatey
|
||||
# Continue node_js matrix
|
||||
- node_js: "6"
|
||||
- node_js: "10"
|
||||
- node_js: "8"
|
||||
- node_js: "node"
|
||||
env: JOB=babel-parser-flow-tests
|
||||
- node_js: "node"
|
||||
env: JOB=babel-parser-typescript-tests
|
||||
- node_js: "node"
|
||||
env: JOB=babel-parser-test262-tests
|
||||
|
||||
|
||||
212
CHANGELOG.md
212
CHANGELOG.md
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
----
|
||||
---
|
||||
|
||||
<p align="center" class="toc">
|
||||
<strong><a href="#setup">Setup</a></strong>
|
||||
@@ -12,8 +12,7 @@
|
||||
<strong><a href="#internals">Internals</a></strong>
|
||||
</p>
|
||||
|
||||
----
|
||||
|
||||
---
|
||||
|
||||
# Contributing
|
||||
|
||||
@@ -24,13 +23,13 @@ contributing, please read the
|
||||
## Not sure where to start?
|
||||
|
||||
- If you aren't just making a documentation change, you'll probably want to learn a bit about a few topics.
|
||||
- [ASTs](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (Abstract Syntax Tree): The Babel AST [spec](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md) is a bit different from [ESTree](https://github.com/estree/estree). The differences are listed [here](https://babeljs.io/docs/en/next/babel-parser.html#output).
|
||||
- Check out [`/doc`](https://github.com/babel/babel/tree/master/doc) for information about Babel's internals
|
||||
- Check out [the Babel Plugin Handbook](https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md#babel-plugin-handbook) - core plugins are written the same way as any other plugin!
|
||||
- Check out [AST Explorer](http://astexplorer.net/#/scUfOmVOG5) to learn more about ASTs or make your own plugin in the browser
|
||||
- [ASTs](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (Abstract Syntax Tree): The Babel AST [spec](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md) is a bit different from [ESTree](https://github.com/estree/estree). The differences are listed [here](https://babeljs.io/docs/en/next/babel-parser.html#output).
|
||||
- Check out [`/doc`](https://github.com/babel/babel/tree/master/doc) for information about Babel's internals
|
||||
- Check out [the Babel Plugin Handbook](https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md#babel-plugin-handbook) - core plugins are written the same way as any other plugin!
|
||||
- Check out [AST Explorer](http://astexplorer.net/#/scUfOmVOG5) to learn more about ASTs or make your own plugin in the browser
|
||||
- When you feel ready to jump into the Babel source code, a good place to start is to look for issues tagged with [help wanted](https://github.com/babel/babel/labels/help%20wanted) and/or [good first issue](https://github.com/babel/babel/labels/good%20first%20issue).
|
||||
- Follow along with what we are working on by joining our [Slack](https://babeljs.slack.com) (you can sign-up [here](https://slack.babeljs.io/)
|
||||
for an invite), following our announcements on [Twitter](https://twitter.com/babeljs), and reading (or participating!) in our [meeting notes](https://github.com/babel/notes).
|
||||
for an invite), following our announcements on [Twitter](https://twitter.com/babeljs), and reading (or participating!) in our [meeting notes](https://github.com/babel/notes).
|
||||
- Check out our [website](http://babeljs.io/) and the [repo](https://github.com/babel/website)
|
||||
- You can contribute by triaging issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to babel on CodeTriage](https://www.codetriage.com/babel/babel). [](https://www.codetriage.com/babel/babel)
|
||||
|
||||
@@ -49,8 +48,12 @@ Installation instructions can be found here: https://yarnpkg.com/en/docs/install
|
||||
|
||||
### Setup
|
||||
|
||||
Fork the `babel` repository to your GitHub Account.
|
||||
|
||||
Then, run:
|
||||
|
||||
```sh
|
||||
$ git clone https://github.com/babel/babel
|
||||
$ git clone https://github.com/<your-github-username>/babel
|
||||
$ cd babel
|
||||
$ make bootstrap
|
||||
```
|
||||
@@ -158,12 +161,12 @@ $ ./scripts/test-cov.sh
|
||||
|
||||
In case you're not able to reproduce an error on CI locally, it may be due to
|
||||
|
||||
- Node Version: Travis CI runs the tests against all major node versions. If your tests use JavaScript features unsupported by lower versions of node, then use [minNodeVersion option](#writing-tests) in options.json.
|
||||
- Timeout: Check the CI log and if the only errors are timeout errors and you are sure that it's not related to the changes you made, ask someone in the slack channel to trigger rebuild on the CI build and it might be resolved
|
||||
- Node Version: Travis CI runs the tests against all major node versions. If your tests use JavaScript features unsupported by lower versions of node, then use [minNodeVersion option](#writing-tests) in options.json.
|
||||
- Timeout: Check the CI log and if the only errors are timeout errors and you are sure that it's not related to the changes you made, ask someone in the slack channel to trigger rebuild on the CI build and it might be resolved
|
||||
|
||||
In case you're locally getting errors which are not on the CI, it may be due to
|
||||
|
||||
- Updates in Dependencies: Make sure you run `make bootstrap` before you run `make build` or `make watch` before you run the tests.
|
||||
- Updates in Dependencies: Make sure you run `make bootstrap` before you run `make build` or `make watch` before you run the tests.
|
||||
|
||||
### Writing tests
|
||||
|
||||
@@ -177,15 +180,16 @@ For example, in [`@babel/plugin-transform-exponentiation-operator/test`](https:/
|
||||
|
||||
- There is an `index.js` file. It imports our [test helper](https://github.com/babel/babel/tree/master/packages/babel-helper-plugin-test-runner). (You don't have to worry about this).
|
||||
- There can be multiple folders under [`/fixtures`](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures)
|
||||
- There is an [`options.json`](https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures/exponentian-operator/options.json) file whose function is similar to a `.babelrc` file, allowing you to pass in the plugins and settings you need for your tests.
|
||||
- For this test, we only need the relevant plugin, so it's just `{ "plugins": ["@babel/plugin-transform-exponentiation-operator"] }`.
|
||||
- If necessary, you can have an `options.json` with different options in each subfolder.
|
||||
|
||||
- There is an [`options.json`](https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures/exponentian-operator/options.json) file whose function is similar to a `.babelrc` file, allowing you to pass in the plugins and settings you need for your tests.
|
||||
- For this test, we only need the relevant plugin, so it's just `{ "plugins": ["@babel/plugin-transform-exponentiation-operator"] }`.
|
||||
- If necessary, you can have an `options.json` with different options in each subfolder.
|
||||
|
||||
- In each subfolder, you can organize your directory structure by categories of tests. (Example: these folders can be named after the feature you are testing or can reference the issue number they fix)
|
||||
- Generally, there are two kinds of tests for plugins
|
||||
- The first is a simple test of the input and output produced by running Babel on some code. We do this by creating an [`input.js`](https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures/exponentian-operator/binary/input.js) file and an [`output.js`](https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures/exponentian-operator/binary/output.js) file. This kind of test only works in sub-subdirectories of `/fixtures`, i.e. `/fixtures/exponentian-operator/binary/input.js` and **not** `/fixtures/exponentian-operator/input.js`.
|
||||
- If you need to expect an error, you can ignore creating the `output.js` file and pass a new `throws` key to the `options.json` that contains the error string that is created.
|
||||
- The second and preferred type is a test that actually evaluates the produced code and asserts that certain properties are true or false. We do this by creating an [`exec.js`](https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures/exponentian-operator/comprehensive/exec.js) file.
|
||||
- The first is a simple test of the input and output produced by running Babel on some code. We do this by creating an [`input.js`](https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures/exponentian-operator/binary/input.js) file and an [`output.js`](https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures/exponentian-operator/binary/output.js) file. This kind of test only works in sub-subdirectories of `/fixtures`, i.e. `/fixtures/exponentian-operator/binary/input.js` and **not** `/fixtures/exponentian-operator/input.js`.
|
||||
- If you need to expect an error, you can ignore creating the `output.js` file and pass a new `throws` key to the `options.json` that contains the error string that is created.
|
||||
- The second and preferred type is a test that actually evaluates the produced code and asserts that certain properties are true or false. We do this by creating an [`exec.js`](https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures/exponentian-operator/comprehensive/exec.js) file.
|
||||
|
||||
In a fixture test, you simply write out the code you want to transform in `input.js`.
|
||||
|
||||
@@ -200,6 +204,7 @@ and the expected output after transforming it with your `options.json` in `outpu
|
||||
// output.js
|
||||
Math.pow(2, 2);
|
||||
```
|
||||
|
||||
In an `exec.js` test, we run or check that the code actually does what it's supposed to do rather than just check the static output.
|
||||
|
||||
```js
|
||||
@@ -235,9 +240,9 @@ Inside the `packages/babel-parser/test/fixtures` folder are categories/groupings
|
||||
etc.). To add a test, create a folder under one of these groupings (or create a new one) with a
|
||||
descriptive name, and add the following:
|
||||
|
||||
* Create an `input.js` file that contains the code you want the babel parser to parse.
|
||||
- Create an `input.js` file that contains the code you want the babel parser to parse.
|
||||
|
||||
* Add an `output.json` file with the expected parser output. For added convenience, if there is no `output.json` present, the test runner will generate one for you.
|
||||
- Add an `output.json` file with the expected parser output. For added convenience, if there is no `output.json` present, the test runner will generate one for you.
|
||||
|
||||
After writing tests for @babel/parser, just build it by running:
|
||||
|
||||
@@ -317,6 +322,7 @@ Note that the code shown in Chrome DevTools is compiled code and therefore diffe
|
||||
- Start working about the Babel transform itself!
|
||||
|
||||
## Internals
|
||||
|
||||
- AST spec ([babel-parser/ast/spec.md](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md))
|
||||
- Versioning ([doc/design/versioning.md](https://github.com/babel/babel/blob/master/doc/design/versioning.md))
|
||||
- Monorepo ([doc/design/monorepo.md](https://github.com/babel/babel/blob/master/doc/design/monorepo.md))
|
||||
|
||||
270
Gulpfile.js
270
Gulpfile.js
@@ -10,12 +10,17 @@ const fancyLog = require("fancy-log");
|
||||
const filter = require("gulp-filter");
|
||||
const gulp = require("gulp");
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const rollup = require("rollup");
|
||||
const rollupAlias = require("@rollup/plugin-alias");
|
||||
const rollupBabel = require("rollup-plugin-babel");
|
||||
const rollupBabelSource = require("./scripts/rollup-plugin-babel-source");
|
||||
const rollupCommonJs = require("rollup-plugin-commonjs");
|
||||
const rollupJson = require("@rollup/plugin-json");
|
||||
const rollupNodeBuiltins = require("rollup-plugin-node-builtins");
|
||||
const rollupNodeGlobals = require("rollup-plugin-node-globals");
|
||||
const rollupNodeResolve = require("rollup-plugin-node-resolve");
|
||||
const rollupReplace = require("rollup-plugin-replace");
|
||||
const { registerStandalonePackageTask } = require("./scripts/gulp-tasks");
|
||||
const { terser: rollupTerser } = require("rollup-plugin-terser");
|
||||
|
||||
const defaultSourcesGlob = "./@(codemods|packages|eslint)/*/src/**/*.js";
|
||||
|
||||
@@ -75,42 +80,209 @@ function buildBabel(exclude, sourcesGlob = defaultSourcesGlob) {
|
||||
.pipe(gulp.dest(base));
|
||||
}
|
||||
|
||||
let babelVersion = require("./packages/babel-core/package.json").version;
|
||||
function buildRollup(packages) {
|
||||
const sourcemap = process.env.NODE_ENV === "production";
|
||||
const minify = !!process.env.IS_PUBLISH;
|
||||
return Promise.all(
|
||||
packages.map(pkg => {
|
||||
const input = getIndexFromPackage(pkg);
|
||||
fancyLog(`Compiling '${chalk.cyan(input)}' with rollup ...`);
|
||||
return rollup
|
||||
.rollup({
|
||||
input,
|
||||
plugins: [
|
||||
rollupReplace({
|
||||
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
|
||||
}),
|
||||
rollupBabel({
|
||||
envName: "babel-parser",
|
||||
}),
|
||||
rollupNodeResolve(),
|
||||
],
|
||||
})
|
||||
.then(bundle => {
|
||||
return bundle.write({
|
||||
file: path.join(pkg, "lib/index.js"),
|
||||
format: "cjs",
|
||||
name: "babel-parser",
|
||||
sourcemap: process.env.NODE_ENV !== "production",
|
||||
packages.map(
|
||||
({ src, format, dest, name, filename, version = babelVersion }) => {
|
||||
const extraPlugins = [];
|
||||
let inputExternal = undefined,
|
||||
outputGlobals = undefined,
|
||||
nodeResolveBrowser = false,
|
||||
babelEnvName = "rollup";
|
||||
switch (src) {
|
||||
case "packages/babel-standalone":
|
||||
nodeResolveBrowser = true;
|
||||
babelEnvName = "standalone";
|
||||
if (minify) {
|
||||
extraPlugins.push(
|
||||
rollupTerser({
|
||||
include: /^.+\.min\.js$/,
|
||||
})
|
||||
);
|
||||
}
|
||||
break;
|
||||
case "packages/babel-preset-env-standalone":
|
||||
nodeResolveBrowser = true;
|
||||
babelEnvName = "standalone";
|
||||
if (minify) {
|
||||
extraPlugins.push(
|
||||
rollupTerser({
|
||||
include: /^.+\.min\.js$/,
|
||||
})
|
||||
);
|
||||
}
|
||||
inputExternal = ["@babel/standalone"];
|
||||
outputGlobals = {
|
||||
"@babel/standalone": "Babel",
|
||||
};
|
||||
extraPlugins.push(
|
||||
rollupAlias({
|
||||
entries: [
|
||||
{
|
||||
find: "./available-plugins",
|
||||
replacement: require.resolve(
|
||||
path.join(__dirname, src, "./src/available-plugins")
|
||||
),
|
||||
},
|
||||
{
|
||||
find: "caniuse-lite/data/regions",
|
||||
replacement: require.resolve(
|
||||
path.join(__dirname, src, "./src/caniuse-lite-regions")
|
||||
),
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
break;
|
||||
}
|
||||
// If this build is part of a pull request, include the pull request number in
|
||||
// the version number.
|
||||
if (process.env.CIRCLE_PR_NUMBER) {
|
||||
const prVersion = "+pr." + process.env.CIRCLE_PR_NUMBER;
|
||||
babelVersion += prVersion;
|
||||
version += prVersion;
|
||||
}
|
||||
const input = getIndexFromPackage(src);
|
||||
fancyLog(`Compiling '${chalk.cyan(input)}' with rollup ...`);
|
||||
return rollup
|
||||
.rollup({
|
||||
input,
|
||||
external: inputExternal,
|
||||
plugins: [
|
||||
...extraPlugins,
|
||||
rollupBabelSource(),
|
||||
rollupReplace({
|
||||
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
|
||||
BABEL_VERSION: JSON.stringify(babelVersion),
|
||||
VERSION: JSON.stringify(version),
|
||||
}),
|
||||
rollupBabel({
|
||||
envName: babelEnvName,
|
||||
babelrc: false,
|
||||
extends: "./babel.config.js",
|
||||
}),
|
||||
rollupNodeResolve({
|
||||
browser: nodeResolveBrowser,
|
||||
preferBuiltins: true,
|
||||
//todo: When Yarn workspaces is enabled, remove `dedupe` option
|
||||
dedupe(importee) {
|
||||
return (
|
||||
importee.startsWith("lodash/") ||
|
||||
[
|
||||
"babel-plugin-dynamic-import-node/utils",
|
||||
"esutils",
|
||||
"semver",
|
||||
"source-map",
|
||||
].includes(importee)
|
||||
);
|
||||
},
|
||||
}),
|
||||
rollupCommonJs({
|
||||
include: [
|
||||
/node_modules/,
|
||||
"packages/babel-runtime/regenerator/**",
|
||||
"packages/babel-preset-env/data/*.js",
|
||||
// Rollup doesn't read export maps, so it loads the cjs fallback
|
||||
"packages/babel-compat-data/*.js",
|
||||
],
|
||||
namedExports: {
|
||||
"babel-plugin-dynamic-import-node/utils.js": [
|
||||
"createDynamicImportTransform",
|
||||
"getImportSource",
|
||||
],
|
||||
"@babel/standalone": ["availablePlugins", "registerPlugin"],
|
||||
},
|
||||
}),
|
||||
rollupJson(),
|
||||
rollupNodeBuiltins(),
|
||||
rollupNodeGlobals({ sourceMap: sourcemap }),
|
||||
],
|
||||
})
|
||||
.then(bundle => {
|
||||
const outputFile = path.resolve(src, dest, filename || "index.js");
|
||||
return bundle
|
||||
.write({
|
||||
file: outputFile,
|
||||
format,
|
||||
name,
|
||||
globals: outputGlobals,
|
||||
sourcemap: sourcemap,
|
||||
})
|
||||
.then(() => {
|
||||
if (!process.env.IS_PUBLISH) {
|
||||
fancyLog(
|
||||
chalk.yellow(
|
||||
`Skipped minification of '${chalk.cyan(
|
||||
path.relative(path.join(__dirname, ".."), outputFile)
|
||||
)}' because not publishing`
|
||||
)
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
fancyLog(
|
||||
`Minifying '${chalk.cyan(
|
||||
path.relative(path.join(__dirname, ".."), outputFile)
|
||||
)}'...`
|
||||
);
|
||||
|
||||
return bundle.write({
|
||||
file: outputFile.replace(/\.js$/, ".min.js"),
|
||||
format,
|
||||
name,
|
||||
globals: outputGlobals,
|
||||
sourcemap: sourcemap,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const bundles = ["packages/babel-parser"];
|
||||
const libBundles = [
|
||||
{
|
||||
src: "packages/babel-parser",
|
||||
format: "cjs",
|
||||
dest: "lib",
|
||||
version: require("./packages/babel-parser/package").version,
|
||||
},
|
||||
];
|
||||
|
||||
gulp.task("build-rollup", () => buildRollup(bundles));
|
||||
gulp.task("build-babel", () => buildBabel(/* exclude */ bundles));
|
||||
const standaloneBundle = [
|
||||
{
|
||||
src: "packages/babel-standalone",
|
||||
format: "umd",
|
||||
name: "Babel",
|
||||
filename: "babel.js",
|
||||
dest: "",
|
||||
version: require("./packages/babel-core/package").version,
|
||||
},
|
||||
];
|
||||
|
||||
const presetEnvStandaloneBundle = [
|
||||
{
|
||||
src: "packages/babel-preset-env-standalone",
|
||||
format: "umd",
|
||||
name: "BabelPresetEnv",
|
||||
filename: "babel-preset-env.js",
|
||||
dest: "",
|
||||
version: require("./packages/babel-preset-env/package").version,
|
||||
},
|
||||
];
|
||||
|
||||
gulp.task("build-rollup", () => buildRollup(libBundles));
|
||||
gulp.task("build-babel-standalone", () => buildRollup(standaloneBundle));
|
||||
|
||||
gulp.task("build-babel-preset-env-standalone", () =>
|
||||
buildRollup(presetEnvStandaloneBundle)
|
||||
);
|
||||
|
||||
gulp.task("build-babel", () => buildBabel(/* exclude */ libBundles));
|
||||
gulp.task("build-babel-types", () =>
|
||||
buildBabel(/* exclude */ bundles, "packages/babel-types/src/**/*.js")
|
||||
buildBabel(/* exclude */ libBundles, "packages/babel-types/src/**/*.js")
|
||||
);
|
||||
gulp.task("build", gulp.parallel("build-rollup", "build-babel"));
|
||||
|
||||
@@ -128,41 +300,3 @@ gulp.task(
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
registerStandalonePackageTask(
|
||||
gulp,
|
||||
"babel",
|
||||
"Babel",
|
||||
path.join(__dirname, "packages"),
|
||||
require("./packages/babel-standalone/package.json").version
|
||||
);
|
||||
|
||||
const presetEnvWebpackPlugins = [
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/\.\/available-plugins/,
|
||||
require.resolve(
|
||||
path.join(
|
||||
__dirname,
|
||||
"./packages/babel-preset-env-standalone/src/available-plugins"
|
||||
)
|
||||
)
|
||||
),
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/caniuse-lite\/data\/regions\/.+/,
|
||||
require.resolve(
|
||||
path.join(
|
||||
__dirname,
|
||||
"./packages/babel-preset-env-standalone/src/caniuse-lite-regions"
|
||||
)
|
||||
)
|
||||
),
|
||||
];
|
||||
|
||||
registerStandalonePackageTask(
|
||||
gulp,
|
||||
"babel-preset-env",
|
||||
"babelPresetEnv",
|
||||
path.join(__dirname, "packages"),
|
||||
require("./packages/babel-preset-env-standalone/package.json").version,
|
||||
presetEnvWebpackPlugins
|
||||
);
|
||||
|
||||
47
Makefile
47
Makefile
@@ -1,5 +1,6 @@
|
||||
FLOW_COMMIT = 09669846b7a7ca5a6c23c12d56bb3bebdafd67e9
|
||||
TEST262_COMMIT = 8688c4ab79059c3097098605e69f1ee5eda6c409
|
||||
FLOW_COMMIT = a1f9a4c709dcebb27a5084acf47755fbae699c25
|
||||
TEST262_COMMIT = 28b4fcca4b1b1d278dfe0cc0e69c7d9d59b31aab
|
||||
TYPESCRIPT_COMMIT = 5fc917be2e4dd64c8e9504d36615cd7fbfdd4cd3
|
||||
|
||||
FORCE_PUBLISH = "@babel/runtime,@babel/runtime-corejs2,@babel/runtime-corejs3,@babel/standalone,@babel/preset-env-standalone"
|
||||
|
||||
@@ -111,7 +112,7 @@ lint-js:
|
||||
yarn eslint scripts $(SOURCES) '*.js' --format=codeframe
|
||||
|
||||
lint-ts:
|
||||
scripts/tests/typescript/lint.sh
|
||||
scripts/lint-ts-typings.sh
|
||||
|
||||
fix: fix-json fix-js
|
||||
|
||||
@@ -135,7 +136,8 @@ test-clean:
|
||||
# Does not work on Windows; use "yarn jest" instead
|
||||
test-only:
|
||||
BABEL_ENV=test ./scripts/test.sh
|
||||
$(MAKE) test-clean
|
||||
YARN jest
|
||||
#$(MAKE) test-clean
|
||||
|
||||
test: lint test-only
|
||||
|
||||
@@ -159,28 +161,43 @@ bootstrap-flow:
|
||||
cd build/flow && git checkout $(FLOW_COMMIT)
|
||||
|
||||
test-flow:
|
||||
node scripts/tests/flow/run_babel_parser_flow_tests.js
|
||||
node scripts/parser-tests/flow
|
||||
|
||||
test-flow-ci: build-bundle-ci bootstrap-flow
|
||||
$(MAKE) test-flow
|
||||
|
||||
test-flow-update-whitelist:
|
||||
node scripts/tests/flow/run_babel_parser_flow_tests.js --update-whitelist
|
||||
node scripts/parser-tests/flow --update-whitelist
|
||||
|
||||
bootstrap-typescript:
|
||||
rm -rf ./build/typescript
|
||||
mkdir -p ./build
|
||||
git clone --branch=master --single-branch --shallow-since=2019-09-01 https://github.com/microsoft/TypeScript.git ./build/typescript
|
||||
cd build/typescript && git checkout $(TYPESCRIPT_COMMIT)
|
||||
|
||||
test-typescript:
|
||||
node scripts/parser-tests/typescript
|
||||
|
||||
test-typescript-ci: build-bundle-ci bootstrap-typescript
|
||||
$(MAKE) test-typescript
|
||||
|
||||
test-typescript-update-whitelist:
|
||||
node scripts/parser-tests/typescript --update-whitelist
|
||||
|
||||
bootstrap-test262:
|
||||
rm -rf build/test262
|
||||
mkdir -p build
|
||||
git clone --branch=master --single-branch --shallow-since=2019-09-01 https://github.com/tc39/test262.git build/test262
|
||||
git clone --branch=master --single-branch --shallow-since=2019-12-01 https://github.com/tc39/test262.git build/test262
|
||||
cd build/test262 && git checkout $(TEST262_COMMIT)
|
||||
|
||||
test-test262:
|
||||
node scripts/tests/test262/run_babel_parser_test262.js
|
||||
node scripts/parser-tests/test262
|
||||
|
||||
test-test262-ci: build-bundle-ci bootstrap-test262
|
||||
$(MAKE) test-test262
|
||||
|
||||
test-test262-update-whitelist:
|
||||
node scripts/tests/test262/run_babel_parser_test262.js --update-whitelist
|
||||
node scripts/parser-tests/test262 --update-whitelist
|
||||
|
||||
# Does not work on Windows
|
||||
clone-license:
|
||||
@@ -193,17 +210,17 @@ prepublish-build: clean-lib clean-runtime-helpers
|
||||
prepublish:
|
||||
$(MAKE) bootstrap-only
|
||||
$(MAKE) prepublish-build
|
||||
$(MAKE) test
|
||||
#$(MAKE) test #fuck your tests babel...
|
||||
|
||||
new-version:
|
||||
git pull --rebase
|
||||
yarn lerna version --force-publish=$(FORCE_PUBLISH)
|
||||
|
||||
version-cerxes:
|
||||
yarn lerna version prerelease --allow-branch initializer-fix-v7.7.4 --preid csx
|
||||
yarn lerna version prerelease --allow-branch initializers-fix --preid csx
|
||||
|
||||
publish-cerxes: prepublish
|
||||
yarn lerna publish --registry="https://npm.cerxes.net" --force-publish --allow-branch initializer-fix-v7.7.4 --canary --preid csx --dist-tag csx
|
||||
yarn lerna publish --registry="https://npm.cerxes.net" --force-publish --allow-branch initializer-fix-v7.8.3 --dist-tag csx --skip-git --exact
|
||||
|
||||
# NOTE: Run make new-version first
|
||||
publish: prepublish
|
||||
@@ -270,6 +287,12 @@ clean-all:
|
||||
|
||||
$(MAKE) clean
|
||||
|
||||
update-env-corejs-fixture:
|
||||
rm -rf packages/babel-preset-env/node_modules/core-js-compat
|
||||
$(YARN) lerna bootstrap
|
||||
$(MAKE) build-bundle
|
||||
OVERWRITE=true $(YARN) jest packages/babel-preset-env
|
||||
|
||||
define clean-source-lib
|
||||
rm -rf $(1)/*/lib
|
||||
|
||||
|
||||
@@ -11,26 +11,41 @@ module.exports = function(api) {
|
||||
exclude: ["transform-typeof-symbol"],
|
||||
};
|
||||
const envOpts = Object.assign({}, envOptsNoTargets);
|
||||
let transformRuntimeOpts = null;
|
||||
|
||||
let convertESM = true;
|
||||
let ignoreLib = true;
|
||||
let includeRuntime = false;
|
||||
let includeRegeneratorRuntime = false;
|
||||
|
||||
let transformRuntimeOptions;
|
||||
|
||||
const nodeVersion = "6.9";
|
||||
// The vast majority of our src files are modules, but we use
|
||||
// unambiguous to keep things simple until we get around to renaming
|
||||
// the modules to be more easily distinguished from CommonJS
|
||||
const unambiguousSources = [
|
||||
"packages/*/src",
|
||||
"packages/*/test",
|
||||
"codemods/*/src",
|
||||
"codemods/*/test",
|
||||
"eslint/*/src",
|
||||
"eslint/*/test",
|
||||
];
|
||||
|
||||
switch (env) {
|
||||
// Configs used during bundling builds.
|
||||
case "babel-parser":
|
||||
convertESM = false;
|
||||
ignoreLib = false;
|
||||
envOpts.targets = {
|
||||
node: nodeVersion,
|
||||
};
|
||||
break;
|
||||
case "standalone":
|
||||
includeRegeneratorRuntime = true;
|
||||
unambiguousSources.push("packages/babel-runtime/regenerator");
|
||||
case "rollup":
|
||||
convertESM = false;
|
||||
ignoreLib = false;
|
||||
includeRuntime = true;
|
||||
// rollup-commonjs will converts node_modules to ESM
|
||||
unambiguousSources.push(
|
||||
"**/node_modules",
|
||||
"packages/babel-preset-env/data",
|
||||
"packages/babel-compat-data"
|
||||
);
|
||||
if (env === "rollup") envOpts.targets = { node: nodeVersion };
|
||||
break;
|
||||
case "production":
|
||||
// Config during builds before publish.
|
||||
@@ -51,14 +66,13 @@ module.exports = function(api) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (includeRuntime) {
|
||||
const babelRuntimePackageJSONPath = require.resolve(
|
||||
"@babel/runtime/package.json"
|
||||
);
|
||||
const path = require("path");
|
||||
transformRuntimeOpts = {
|
||||
version: require(babelRuntimePackageJSONPath).version,
|
||||
absoluteRuntime: path.dirname(babelRuntimePackageJSONPath),
|
||||
if (includeRegeneratorRuntime) {
|
||||
const babelRuntimePkgPath = require.resolve("@babel/runtime/package.json");
|
||||
|
||||
transformRuntimeOptions = {
|
||||
helpers: false, // Helpers are handled by rollup when needed
|
||||
regenerator: true,
|
||||
version: require(babelRuntimePkgPath).version,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -93,6 +107,10 @@ module.exports = function(api) {
|
||||
["@babel/plugin-proposal-nullish-coalescing-operator", { loose: true }],
|
||||
|
||||
convertESM ? "@babel/transform-modules-commonjs" : null,
|
||||
// Until Jest supports native mjs, we must simulate it 🤷
|
||||
env === "test" || env === "development"
|
||||
? "@babel/plugin-proposal-dynamic-import"
|
||||
: null,
|
||||
].filter(Boolean),
|
||||
overrides: [
|
||||
{
|
||||
@@ -116,30 +134,12 @@ module.exports = function(api) {
|
||||
presets: [["@babel/env", envOptsNoTargets]],
|
||||
},
|
||||
{
|
||||
// The vast majority of our src files are modules, but we use
|
||||
// unambiguous to keep things simple until we get around to renaming
|
||||
// the modules to be more easily distinguished from CommonJS
|
||||
test: [
|
||||
"packages/*/src",
|
||||
"packages/*/test",
|
||||
"codemods/*/src",
|
||||
"codemods/*/test",
|
||||
"eslint/*/src",
|
||||
"eslint/*/test",
|
||||
],
|
||||
test: unambiguousSources,
|
||||
sourceType: "unambiguous",
|
||||
},
|
||||
{
|
||||
// The runtime transform shouldn't process its own runtime or core-js.
|
||||
exclude: [
|
||||
"packages/babel-runtime",
|
||||
/[\\/]node_modules[\\/](?:@babel\/runtime|babel-runtime|core-js)[\\/]/,
|
||||
],
|
||||
plugins: [
|
||||
includeRuntime
|
||||
? ["@babel/transform-runtime", transformRuntimeOpts]
|
||||
: null,
|
||||
].filter(Boolean),
|
||||
includeRegeneratorRuntime && {
|
||||
exclude: /regenerator-runtime/,
|
||||
plugins: [["@babel/transform-runtime", transformRuntimeOptions]],
|
||||
},
|
||||
].filter(Boolean),
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: "80%"
|
||||
target: "90%"
|
||||
patch:
|
||||
enabled: false
|
||||
ignore:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@babel/plugin-codemod-object-assign-to-object-spread",
|
||||
"version": "7.7.4-csx.0",
|
||||
"version": "7.7.4",
|
||||
"description": "Transforms Object.assign into object spread syntax",
|
||||
"repository": "https://github.com/babel/babel/tree/master/codemods/babel-plugin-codemod-object-assign-to-object-spread",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@babel/plugin-codemod-optional-catch-binding",
|
||||
"version": "7.7.4-csx.0",
|
||||
"version": "7.7.4",
|
||||
"description": "Remove unused catch bindings",
|
||||
"repository": "https://github.com/babel/babel/tree/master/codemods/babel-plugin-codemod-remove-unused-catch-binding",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@babel/eslint-config-internal",
|
||||
"version": "0.0.0",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "The Babel Team's ESLint configuration. Since it's internal, it might not respect semver.",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
|
||||
@@ -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).
|
||||
|
||||
## 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?
|
||||
|
||||
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).
|
||||
**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).
|
||||
|
||||
## 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,
|
||||
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
|
||||
|
||||
### Installation
|
||||
|
||||
```sh
|
||||
$ npm install eslint babel-eslint --save-dev
|
||||
$ npm install eslint @babel/core @babel/eslint-parser --save-dev
|
||||
# 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
|
||||
|
||||
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**
|
||||
|
||||
```js
|
||||
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.
|
||||
|
||||
**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 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.
|
||||
- `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"`.
|
||||
- `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**
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
parser: "babel-eslint",
|
||||
parser: "@babel/eslint-parser",
|
||||
parserOptions: {
|
||||
sourceType: "module",
|
||||
allowImportExportEverywhere: false,
|
||||
@@ -89,7 +85,7 @@ module.exports = {
|
||||
overrides: [
|
||||
{
|
||||
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`.
|
||||
|
||||
- `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'`
|
||||
- `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
|
||||
|
||||
- `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.
|
||||
|
||||
@@ -123,6 +119,6 @@ Please check out [eslint-plugin-babel](https://github.com/babel/eslint-plugin-ba
|
||||
|
||||
## 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).
|
||||
|
||||
@@ -1,49 +1,35 @@
|
||||
{
|
||||
"name": "babel-eslint",
|
||||
"version": "7.7.4-csx.1",
|
||||
"description": "Custom parser for ESLint",
|
||||
"name": "@babel/eslint-parser",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "ESLint parser that allows for linting of experimental syntax transformed by Babel",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/babel/babel-eslint.git"
|
||||
"url": "https://github.com/babel/babel.git",
|
||||
"directory": "eslint/babel-eslint-parser"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/babel/babel-eslint/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'"
|
||||
"url": "https://github.com/babel/babel/issues"
|
||||
},
|
||||
"homepage": "https://github.com/babel/babel/tree/master/eslint/babel-eslint-parser",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=10.9"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"peerDependencies": {
|
||||
"@babel/core": ">=7.2.0",
|
||||
"eslint": ">= 4.12.1"
|
||||
"eslint": ">=6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-scope": "3.7.1",
|
||||
"eslint-visitor-keys": "^1.0.0",
|
||||
"eslint-scope": "5.0.0",
|
||||
"eslint-visitor-keys": "^1.1.0",
|
||||
"semver": "^6.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.4-csx.1",
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4-csx.1",
|
||||
"@babel/plugin-proposal-decorators": "^7.7.4-csx.1",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.7.4-csx.1",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.7.4-csx.1",
|
||||
"@babel/plugin-proposal-pipeline-operator": "^7.7.4-csx.1",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.7.4-csx.1",
|
||||
"@babel/plugin-syntax-export-default-from": "^7.7.4-csx.1",
|
||||
"@babel/plugin-syntax-export-namespace-from": "^7.7.4-csx.1",
|
||||
"@babel/plugin-syntax-import-meta": "^7.7.4-csx.1",
|
||||
"@babel/plugin-syntax-numeric-separator": "^7.7.4-csx.1",
|
||||
"@babel/preset-env": "^7.7.4-csx.1",
|
||||
"@babel/preset-flow": "^7.7.4-csx.1",
|
||||
"@babel/preset-react": "^7.7.4-csx.1",
|
||||
"@babel/core": "^7.2.0",
|
||||
"@babel/eslint-shared-fixtures": "7.8.3-csx.2",
|
||||
"dedent": "^0.7.0",
|
||||
"eslint": "^6.0.1",
|
||||
"espree": "^6.0.0"
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
const t = require("@babel/core").types;
|
||||
const escope = require("eslint-scope");
|
||||
const Definition = require("eslint-scope/lib/definition").Definition;
|
||||
const OriginalPatternVisitor = require("eslint-scope/lib/pattern-visitor");
|
||||
const OriginalReferencer = require("eslint-scope/lib/referencer");
|
||||
const fallback = require("eslint-visitor-keys").getKeys;
|
||||
const childVisitorKeys = require("./visitor-keys");
|
||||
import { types as t } from "@babel/core";
|
||||
import escope from "eslint-scope";
|
||||
import { Definition } from "eslint-scope/lib/definition";
|
||||
import OriginalPatternVisitor from "eslint-scope/lib/pattern-visitor";
|
||||
import OriginalReferencer from "eslint-scope/lib/referencer";
|
||||
import { getKeys as fallback } from "eslint-visitor-keys";
|
||||
import childVisitorKeys from "./visitor-keys";
|
||||
|
||||
const flowFlippedAliasKeys = t.FLIPPED_ALIAS_KEYS.Flow.concat([
|
||||
"ArrayPattern",
|
||||
@@ -18,13 +16,16 @@ const flowFlippedAliasKeys = t.FLIPPED_ALIAS_KEYS.Flow.concat([
|
||||
"ObjectPattern",
|
||||
"RestElement",
|
||||
]);
|
||||
const visitorKeysMap = Object.keys(t.VISITOR_KEYS).reduce(function(acc, key) {
|
||||
const value = t.VISITOR_KEYS[key];
|
||||
if (flowFlippedAliasKeys.indexOf(value) === -1) {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const visitorKeysMap = Object.entries(t.VISITOR_KEYS).reduce(
|
||||
(acc, [key, value]) => {
|
||||
if (!flowFlippedAliasKeys.includes(value)) {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
const propertyTypes = {
|
||||
// loops
|
||||
@@ -124,7 +125,7 @@ class Referencer extends OriginalReferencer {
|
||||
|
||||
// inherits.
|
||||
visitProperty(node) {
|
||||
if (node.value && node.value.type === "TypeCastExpression") {
|
||||
if (node.value?.type === "TypeCastExpression") {
|
||||
this._visitTypeAnnotation(node.value);
|
||||
}
|
||||
this._visitArray(node.decorators);
|
||||
@@ -165,6 +166,11 @@ class Referencer extends OriginalReferencer {
|
||||
this._visitClassProperty(node);
|
||||
}
|
||||
|
||||
// TODO: Update to visit type annotations when TypeScript/Flow support this syntax.
|
||||
ClassPrivateMethod(node) {
|
||||
super.MethodDefinition(node);
|
||||
}
|
||||
|
||||
DeclareModule(node) {
|
||||
this._visitDeclareX(node);
|
||||
}
|
||||
@@ -294,9 +300,9 @@ class Referencer extends OriginalReferencer {
|
||||
}
|
||||
|
||||
_checkIdentifierOrVisit(node) {
|
||||
if (node && node.typeAnnotation) {
|
||||
if (node?.typeAnnotation) {
|
||||
this._visitTypeAnnotation(node.typeAnnotation);
|
||||
} else if (node && node.type === "Identifier") {
|
||||
} else if (node?.type === "Identifier") {
|
||||
this.visit(node);
|
||||
} else {
|
||||
this._visitTypeAnnotation(node);
|
||||
@@ -312,7 +318,7 @@ class Referencer extends OriginalReferencer {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(ast, parserOptions) {
|
||||
export default function(ast, parserOptions) {
|
||||
const options = {
|
||||
ignoreEval: true,
|
||||
optimistic: false,
|
||||
@@ -335,4 +341,4 @@ module.exports = function(ast, parserOptions) {
|
||||
referencer.visit(ast);
|
||||
|
||||
return scopeManager;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,28 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const t = require("@babel/core").types;
|
||||
const convertProgramNode = require("./convertProgramNode");
|
||||
|
||||
module.exports = function(ast, traverse, code) {
|
||||
const state = { source: code };
|
||||
|
||||
// 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);
|
||||
|
||||
delete t.VISITOR_KEYS.Property;
|
||||
delete t.VISITOR_KEYS.MethodDefinition;
|
||||
|
||||
convertProgramNode(ast);
|
||||
};
|
||||
import { types as t, traverse } from "@babel/core";
|
||||
import convertProgramNode from "./convertProgramNode";
|
||||
|
||||
const astTransformVisitor = {
|
||||
noScope: true,
|
||||
@@ -72,15 +49,14 @@ const astTransformVisitor = {
|
||||
}
|
||||
|
||||
// modules
|
||||
|
||||
if (path.isImportDeclaration()) {
|
||||
delete node.isType;
|
||||
}
|
||||
|
||||
// template string range fixes
|
||||
if (path.isTemplateLiteral()) {
|
||||
for (let j = 0; j < node.quasis.length; j++) {
|
||||
const q = node.quasis[j];
|
||||
for (let i = 0; i < node.quasis.length; i++) {
|
||||
const q = node.quasis[i];
|
||||
q.range[0] -= 1;
|
||||
if (q.tail) {
|
||||
q.range[1] += 1;
|
||||
@@ -97,3 +73,24 @@ const astTransformVisitor = {
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default function(ast, code) {
|
||||
const state = { source: code };
|
||||
|
||||
// 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);
|
||||
|
||||
delete t.VISITOR_KEYS.Property;
|
||||
delete t.VISITOR_KEYS.MethodDefinition;
|
||||
|
||||
convertProgramNode(ast);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function(comments) {
|
||||
export default function(comments) {
|
||||
for (let i = 0; i < comments.length; i++) {
|
||||
const comment = comments[i];
|
||||
if (comment.type === "CommentBlock") {
|
||||
@@ -14,4 +12,4 @@ module.exports = function(comments) {
|
||||
comment.range = [comment.start, comment.end];
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function(ast) {
|
||||
export default function(ast) {
|
||||
ast.type = "Program";
|
||||
ast.sourceType = ast.program.sourceType;
|
||||
ast.directives = ast.program.directives;
|
||||
@@ -37,4 +35,4 @@ module.exports = function(ast) {
|
||||
ast.loc.start.line = ast.body[0].loc.start.line;
|
||||
ast.range[0] = ast.body[0].start;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
import { tokTypes as tt } from "@babel/core";
|
||||
|
||||
module.exports = function(tokens, tt) {
|
||||
export default function(tokens) {
|
||||
let curlyBrace = null;
|
||||
let templateTokens = [];
|
||||
const result = [];
|
||||
@@ -89,4 +89,4 @@ module.exports = function(tokens, tt) {
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
import { tokTypes as tt } from "@babel/core";
|
||||
|
||||
module.exports = function(token, tt, source) {
|
||||
export default function(token, source) {
|
||||
const type = token.type;
|
||||
token.range = [token.start, token.end];
|
||||
|
||||
@@ -79,7 +79,10 @@ module.exports = function(token, tt, source) {
|
||||
flags: value.flags,
|
||||
};
|
||||
token.value = `/${value.pattern}/${value.flags}`;
|
||||
} else if (type === tt.bigint) {
|
||||
token.type = "Numeric";
|
||||
token.value = `${token.value}n`;
|
||||
}
|
||||
|
||||
return token;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
"use strict";
|
||||
import convertTemplateType from "./convertTemplateType";
|
||||
import convertToken from "./convertToken";
|
||||
|
||||
const convertTemplateType = require("./convertTemplateType");
|
||||
const convertToken = require("./convertToken");
|
||||
|
||||
module.exports = function(tokens, tt, code) {
|
||||
return convertTemplateType(tokens, tt)
|
||||
export default function(tokens, code) {
|
||||
return convertTemplateType(tokens)
|
||||
.filter(t => t.type !== "CommentLine" && t.type !== "CommentBlock")
|
||||
.map(t => convertToken(t, tt, code));
|
||||
};
|
||||
.map(t => convertToken(t, code));
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
"use strict";
|
||||
import convertTokens from "./convertTokens";
|
||||
import convertComments from "./convertComments";
|
||||
import convertAST from "./convertAST";
|
||||
|
||||
const convertTokens = require("./convertTokens");
|
||||
const convertComments = require("./convertComments");
|
||||
const convertAST = require("./convertAST");
|
||||
|
||||
module.exports = function(ast, traverse, tt, code) {
|
||||
ast.tokens = convertTokens(ast.tokens, tt, code);
|
||||
export default function(ast, code) {
|
||||
ast.tokens = convertTokens(ast.tokens, code);
|
||||
convertComments(ast.comments);
|
||||
convertAST(ast, traverse, code);
|
||||
};
|
||||
convertAST(ast, code);
|
||||
}
|
||||
|
||||
61
eslint/babel-eslint-parser/src/configuration.js
Normal file
61
eslint/babel-eslint-parser/src/configuration.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import { loadPartialConfig } from "@babel/core";
|
||||
|
||||
export function normalizeESLintConfig(options) {
|
||||
const defaultOptions = {
|
||||
babelOptions: {},
|
||||
ecmaVersion: 2020,
|
||||
sourceType: "module",
|
||||
allowImportExportEverywhere: false,
|
||||
};
|
||||
|
||||
return Object.assign(defaultOptions, options);
|
||||
}
|
||||
|
||||
export function normalizeBabelParseConfig(options) {
|
||||
const parseOptions = {
|
||||
sourceType: options.sourceType,
|
||||
filename: options.filePath,
|
||||
cwd: options.babelOptions.cwd,
|
||||
root: options.babelOptions.root,
|
||||
rootMode: options.babelOptions.rootMode,
|
||||
envName: options.babelOptions.envName,
|
||||
configFile: options.babelOptions.configFile,
|
||||
babelrc: options.babelOptions.babelrc,
|
||||
babelrcRoots: options.babelOptions.babelrcRoots,
|
||||
extends: options.babelOptions.extends,
|
||||
env: options.babelOptions.env,
|
||||
overrides: options.babelOptions.overrides,
|
||||
test: options.babelOptions.test,
|
||||
include: options.babelOptions.include,
|
||||
exclude: options.babelOptions.exclude,
|
||||
ignore: options.babelOptions.ignore,
|
||||
only: options.babelOptions.only,
|
||||
parserOpts: {
|
||||
allowImportExportEverywhere: options.allowImportExportEverywhere,
|
||||
allowReturnOutsideFunction: true,
|
||||
allowSuperOutsideMethod: true,
|
||||
ranges: true,
|
||||
tokens: true,
|
||||
plugins: ["estree"],
|
||||
},
|
||||
caller: {
|
||||
name: "@babel/eslint-parser",
|
||||
},
|
||||
};
|
||||
|
||||
if (options.requireConfigFile !== false) {
|
||||
const config = loadPartialConfig(parseOptions);
|
||||
|
||||
if (config !== null) {
|
||||
if (!config.hasFilesystemConfig()) {
|
||||
throw new Error(
|
||||
`No Babel config file detected for ${config.options.filename}. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files.`,
|
||||
);
|
||||
}
|
||||
|
||||
return config.options;
|
||||
}
|
||||
}
|
||||
|
||||
return parseOptions;
|
||||
}
|
||||
@@ -1,33 +1,26 @@
|
||||
"use strict";
|
||||
import semver from "semver";
|
||||
import { version as CURRENT_BABEL_VERSION } from "@babel/core";
|
||||
import parseWithScope from "./parse-with-scope";
|
||||
import { normalizeESLintConfig } from "./configuration";
|
||||
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 =
|
||||
packageJson.peerDependencies["@babel/core"];
|
||||
const IS_RUNNING_SUPPORTED_VERSION = semver.satisfies(
|
||||
CURRENT_BABEL_VERSION,
|
||||
semver.coerce(CURRENT_BABEL_VERSION).raw,
|
||||
SUPPORTED_BABEL_VERSION_RANGE,
|
||||
);
|
||||
|
||||
exports.parse = function(code, options) {
|
||||
return exports.parseForESLint(code, options).ast;
|
||||
};
|
||||
export function parse(code, options) {
|
||||
return parseForESLint(code, options).ast;
|
||||
}
|
||||
|
||||
exports.parseForESLint = function(code, options = {}) {
|
||||
export function parseForESLint(code, options = {}) {
|
||||
if (!IS_RUNNING_SUPPORTED_VERSION) {
|
||||
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}`,
|
||||
);
|
||||
}
|
||||
|
||||
options.babelOptions = options.babelOptions || {};
|
||||
options.ecmaVersion = options.ecmaVersion || 2018;
|
||||
options.sourceType = options.sourceType || "module";
|
||||
options.allowImportExportEverywhere =
|
||||
options.allowImportExportEverywhere || false;
|
||||
|
||||
return require("./parse-with-scope")(code, options);
|
||||
};
|
||||
return parseWithScope(code, normalizeESLintConfig(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");
|
||||
const analyzeScope = require("./analyze-scope");
|
||||
const parse = require("./parse");
|
||||
|
||||
module.exports = function(code, options) {
|
||||
export default function(code, options) {
|
||||
const ast = parse(code, options);
|
||||
const scopeManager = analyzeScope(ast, options);
|
||||
|
||||
return { ast, scopeManager, visitorKeys };
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,63 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
const babylonToEspree = require("./babylon-to-espree");
|
||||
const {
|
||||
parseSync: parse,
|
||||
tokTypes: tt,
|
||||
traverse,
|
||||
loadPartialConfig,
|
||||
} = require("@babel/core");
|
||||
|
||||
module.exports = function(code, options) {
|
||||
let opts = {
|
||||
sourceType: options.sourceType,
|
||||
filename: options.filePath,
|
||||
cwd: options.babelOptions.cwd,
|
||||
root: options.babelOptions.root,
|
||||
rootMode: options.babelOptions.rootMode,
|
||||
envName: options.babelOptions.envName,
|
||||
configFile: options.babelOptions.configFile,
|
||||
babelrc: options.babelOptions.babelrc,
|
||||
babelrcRoots: options.babelOptions.babelrcRoots,
|
||||
extends: options.babelOptions.extends,
|
||||
env: options.babelOptions.env,
|
||||
overrides: options.babelOptions.overrides,
|
||||
test: options.babelOptions.test,
|
||||
include: options.babelOptions.include,
|
||||
exclude: options.babelOptions.exclude,
|
||||
ignore: options.babelOptions.ignore,
|
||||
only: options.babelOptions.only,
|
||||
parserOpts: {
|
||||
allowImportExportEverywhere: options.allowImportExportEverywhere, // consistent with espree
|
||||
allowReturnOutsideFunction: true,
|
||||
allowSuperOutsideMethod: true,
|
||||
ranges: true,
|
||||
tokens: true,
|
||||
plugins: ["estree"],
|
||||
},
|
||||
caller: {
|
||||
name: "babel-eslint",
|
||||
},
|
||||
};
|
||||
|
||||
if (options.requireConfigFile !== false) {
|
||||
const config = loadPartialConfig(opts);
|
||||
|
||||
if (config !== null) {
|
||||
if (!config.hasFilesystemConfig()) {
|
||||
throw new Error(
|
||||
`No Babel config file detected for ${config.options.filename}. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files.`,
|
||||
);
|
||||
}
|
||||
|
||||
opts = config.options;
|
||||
}
|
||||
}
|
||||
import { parseSync as babelParse } from "@babel/core";
|
||||
import babylonToEspree from "./babylon-to-espree";
|
||||
import { normalizeBabelParseConfig } from "./configuration";
|
||||
|
||||
export default function parse(code, options) {
|
||||
const parseOptions = normalizeBabelParseConfig(options);
|
||||
let ast;
|
||||
|
||||
try {
|
||||
ast = parse(code, opts);
|
||||
ast = babelParse(code, parseOptions);
|
||||
} catch (err) {
|
||||
if (err instanceof SyntaxError) {
|
||||
err.lineNumber = err.loc.line;
|
||||
@@ -67,7 +17,7 @@ module.exports = function(code, options) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
babylonToEspree(ast, traverse, tt, code);
|
||||
babylonToEspree(ast, code);
|
||||
|
||||
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 ESLINT_VISITOR_KEYS = require("eslint-visitor-keys").KEYS;
|
||||
const { VISITOR_KEYS: BABEL_VISITOR_KEYS } = t;
|
||||
|
||||
module.exports = Object.assign(
|
||||
export default Object.assign(
|
||||
{
|
||||
Literal: ESLINT_VISITOR_KEYS.Literal,
|
||||
MethodDefinition: ["decorators"].concat(
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
const assert = require("assert");
|
||||
const path = require("path");
|
||||
const babelEslint = require("../");
|
||||
const espree = require("espree");
|
||||
const escope = require("eslint-scope");
|
||||
const unpad = require("dedent");
|
||||
const assertImplementsAST = require("./helpers/assert-implements-ast");
|
||||
import assert from "assert";
|
||||
import espree from "espree";
|
||||
import escope from "eslint-scope";
|
||||
import unpad from "dedent";
|
||||
import { parseForESLint } from "../src";
|
||||
import assertImplementsAST from "./helpers/assert-implements-ast";
|
||||
|
||||
const babelOptions = {
|
||||
configFile: path.resolve(
|
||||
__dirname,
|
||||
"./fixtures/config/babel.config.js"
|
||||
configFile: require.resolve(
|
||||
"@babel/eslint-shared-fixtures/config/babel.config.js",
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
function parseAndAssertSame(code) {
|
||||
code = unpad(code);
|
||||
@@ -32,10 +28,10 @@ function parseAndAssertSame(code) {
|
||||
loc: true,
|
||||
range: true,
|
||||
comment: true,
|
||||
ecmaVersion: 2018,
|
||||
ecmaVersion: 2020,
|
||||
sourceType: "module",
|
||||
});
|
||||
const babylonAST = babelEslint.parseForESLint(code, {
|
||||
const babylonAST = parseForESLint(code, {
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
babelOptions,
|
||||
@@ -46,14 +42,14 @@ function parseAndAssertSame(code) {
|
||||
describe("babylon-to-espree", () => {
|
||||
describe("compatibility", () => {
|
||||
it("should allow ast.analyze to be called without options", function() {
|
||||
const esAST = babelEslint.parseForESLint("`test`", {
|
||||
const esAST = parseForESLint("`test`", {
|
||||
eslintScopeManager: true,
|
||||
eslintVisitorKeys: true,
|
||||
babelOptions,
|
||||
}).ast;
|
||||
expect(() => {
|
||||
escope.analyze(esAST)
|
||||
}).not.toThrow(new TypeError('Should allow no options argument.'));
|
||||
escope.analyze(esAST);
|
||||
}).not.toThrow(new TypeError("Should allow no options argument."));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -100,13 +96,13 @@ describe("babylon-to-espree", () => {
|
||||
|
||||
it("template with nested function/object", () => {
|
||||
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", () => {
|
||||
parseAndAssertSame(
|
||||
"if (a) { var target = `{}a:${webpackPort}{}}}}`; } else { app.use(); }"
|
||||
"if (a) { var target = `{}a:${webpackPort}{}}}}`; } else { app.use(); }",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -245,7 +241,7 @@ describe("babylon-to-espree", () => {
|
||||
// Espree doesn't support the optional chaining operator yet
|
||||
it("optional chaining operator (token)", () => {
|
||||
const code = "foo?.bar";
|
||||
const babylonAST = babelEslint.parseForESLint(code, {
|
||||
const babylonAST = parseForESLint(code, {
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
babelOptions,
|
||||
@@ -256,7 +252,7 @@ describe("babylon-to-espree", () => {
|
||||
// Espree doesn't support the nullish coalescing operator yet
|
||||
it("nullish coalescing operator (token)", () => {
|
||||
const code = "foo ?? bar";
|
||||
const babylonAST = babelEslint.parseForESLint(code, {
|
||||
const babylonAST = parseForESLint(code, {
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
babelOptions,
|
||||
@@ -267,7 +263,7 @@ describe("babylon-to-espree", () => {
|
||||
// Espree doesn't support the pipeline operator yet
|
||||
it("pipeline operator (token)", () => {
|
||||
const code = "foo |> bar";
|
||||
const babylonAST = babelEslint.parseForESLint(code, {
|
||||
const babylonAST = parseForESLint(code, {
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
babelOptions,
|
||||
@@ -275,10 +271,10 @@ describe("babylon-to-espree", () => {
|
||||
assert.strictEqual(babylonAST.tokens[1].type, "Punctuator");
|
||||
});
|
||||
|
||||
// Espree doesn't support the private fields yet
|
||||
// Espree doesn't support private fields yet
|
||||
it("hash (token)", () => {
|
||||
const code = "class A { #x }";
|
||||
const babylonAST = babelEslint.parseForESLint(code, {
|
||||
const babylonAST = parseForESLint(code, {
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
babelOptions,
|
||||
@@ -398,7 +394,7 @@ describe("babylon-to-espree", () => {
|
||||
|
||||
it("MethodDefinition 2", () => {
|
||||
parseAndAssertSame(
|
||||
"export default class Bar { get bar() { return 42; }}"
|
||||
"export default class Bar { get bar() { return 42; }}",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -523,5 +519,17 @@ describe("babylon-to-espree", () => {
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("BigInt", () => {
|
||||
parseAndAssertSame(`
|
||||
const a = 1n;
|
||||
`);
|
||||
});
|
||||
|
||||
it("Dynamic Import", () => {
|
||||
parseAndAssertSame(`
|
||||
const a = import('a');
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
// 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) {
|
||||
path = [];
|
||||
}
|
||||
@@ -16,7 +14,7 @@ module.exports = function assertImplementsAST(target, source, path) {
|
||||
const typeB = source === null ? "null" : typeof source;
|
||||
if (typeA !== typeB) {
|
||||
error(
|
||||
`have different types (${typeA} !== ${typeB}) (${target} !== ${source})`
|
||||
`have different types (${typeA} !== ${typeB}) (${target} !== ${source})`,
|
||||
);
|
||||
} else if (
|
||||
typeA === "object" &&
|
||||
@@ -24,7 +22,7 @@ module.exports = function assertImplementsAST(target, source, path) {
|
||||
target.constructor.name !== source.constructor.name
|
||||
) {
|
||||
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") {
|
||||
const keysTarget = Object.keys(target);
|
||||
@@ -36,7 +34,7 @@ module.exports = function assertImplementsAST(target, source, path) {
|
||||
}
|
||||
} else if (target !== source) {
|
||||
error(
|
||||
`are different (${JSON.stringify(target)} !== ${JSON.stringify(source)})`
|
||||
`are different (${JSON.stringify(target)} !== ${JSON.stringify(source)})`,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const eslint = require("eslint");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const parser = require("../");
|
||||
import eslint from "eslint";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import * as parser from "../src";
|
||||
|
||||
eslint.linter.defineParser("current-babel-eslint", parser);
|
||||
|
||||
@@ -19,6 +16,8 @@ const baseEslintOpts = {
|
||||
parser: "current-babel-eslint",
|
||||
parserOptions: {
|
||||
sourceType: "script",
|
||||
requireConfigFile: false,
|
||||
babelOptions: { configFile: false }
|
||||
},
|
||||
};
|
||||
|
||||
@@ -72,7 +71,7 @@ function strictSuite() {
|
||||
if (err) return done(err);
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
done();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
@@ -96,7 +95,7 @@ function strictSuite() {
|
||||
if (err) return done(err);
|
||||
expect(report.length).toBe(0);
|
||||
done();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
@@ -113,7 +112,7 @@ function strictSuite() {
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
});
|
||||
done();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
@@ -133,7 +132,7 @@ function strictSuite() {
|
||||
// result of the previous assertion.
|
||||
expect(report[0].nodeType).not.toBe("Program");
|
||||
done();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
@@ -148,7 +147,7 @@ function strictSuite() {
|
||||
if (err) return done(err);
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
done();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
@@ -171,7 +170,7 @@ function strictSuite() {
|
||||
if (err) return done(err);
|
||||
expect(report.length).toBe(0);
|
||||
done();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
@@ -188,7 +187,7 @@ function strictSuite() {
|
||||
expect(report[i].ruleId).toBe(ruleId);
|
||||
});
|
||||
done();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
@@ -203,7 +202,7 @@ function strictSuite() {
|
||||
if (err) return done(err);
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
done();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
@@ -219,7 +218,7 @@ function strictSuite() {
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
expect(report[0].nodeType.indexOf("Function")).toBe(-1);
|
||||
done();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
@@ -229,10 +228,10 @@ function strictSuite() {
|
||||
describe("https://github.com/babel/babel-eslint/issues/558", () => {
|
||||
it("doesn't crash with eslint-plugin-import", () => {
|
||||
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 =>
|
||||
path.resolve(__dirname, `./fixtures/eslint-plugin-import/${file}`));
|
||||
path.resolve(__dirname, `./fixtures/eslint-plugin-import/${file}`),
|
||||
);
|
||||
engine.executeOnFiles(fileWithPath);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const eslint = require("eslint");
|
||||
const path = require("path");
|
||||
const unpad = require("dedent");
|
||||
|
||||
const parser = require("../");
|
||||
import eslint from "eslint";
|
||||
import path from "path";
|
||||
import unpad from "dedent";
|
||||
import * as parser from "../src";
|
||||
|
||||
function verifyAndAssertMessagesWithSpecificESLint(
|
||||
code,
|
||||
@@ -21,26 +18,19 @@ function verifyAndAssertMessagesWithSpecificESLint(
|
||||
node: true,
|
||||
es6: true,
|
||||
},
|
||||
...overrideConfig,
|
||||
parserOptions: {
|
||||
sourceType,
|
||||
ecmaFeatures: {
|
||||
globalReturn: true,
|
||||
},
|
||||
requireConfigFile: false,
|
||||
babelOptions: {
|
||||
configFile: path.resolve(
|
||||
__dirname,
|
||||
"./fixtures/config/babel.config.js",
|
||||
configFile: require.resolve(
|
||||
"@babel/eslint-shared-fixtures/config/babel.config.js",
|
||||
),
|
||||
},
|
||||
...overrideConfig?.parserOptions,
|
||||
},
|
||||
};
|
||||
|
||||
if (overrideConfig) {
|
||||
for (const key in overrideConfig) {
|
||||
config[key] = overrideConfig[key];
|
||||
}
|
||||
}
|
||||
|
||||
const messages = linter.verify(code, config);
|
||||
|
||||
if (messages.length !== expectedMessages.length) {
|
||||
@@ -1166,9 +1156,8 @@ describe("verify", () => {
|
||||
parserOptions: {
|
||||
sourceType,
|
||||
babelOptions: {
|
||||
configFile: path.resolve(
|
||||
__dirname,
|
||||
"./fixtures/config/babel.config.decorators-legacy.js",
|
||||
configFile: require.resolve(
|
||||
"@babel/eslint-shared-fixtures/config/babel.config.decorators-legacy.js",
|
||||
),
|
||||
},
|
||||
},
|
||||
@@ -1569,7 +1558,7 @@ describe("verify", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("no-implicit-globals in script", () => {
|
||||
it("no-implicit-globals in script: globalReturn is false", () => {
|
||||
verifyAndAssertMessages(
|
||||
"var leakedGlobal = 1;",
|
||||
{ "no-implicit-globals": 1 },
|
||||
@@ -1579,7 +1568,28 @@ describe("verify", () => {
|
||||
"script",
|
||||
{
|
||||
env: {},
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "script" },
|
||||
parserOptions: {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "script",
|
||||
ecmaFeatures: { globalReturn: false },
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("no-implicit-globals in script: globalReturn is true", () => {
|
||||
verifyAndAssertMessages(
|
||||
"var leakedGlobal = 1;",
|
||||
{ "no-implicit-globals": 1 },
|
||||
[],
|
||||
"script",
|
||||
{
|
||||
env: {},
|
||||
parserOptions: {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "script",
|
||||
ecmaFeatures: { globalReturn: true },
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -1602,7 +1612,7 @@ describe("verify", () => {
|
||||
"var leakedGlobal = 1;",
|
||||
{ "no-implicit-globals": 1 },
|
||||
[],
|
||||
null,
|
||||
undefined,
|
||||
{
|
||||
env: {},
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
@@ -1751,27 +1761,77 @@ describe("verify", () => {
|
||||
);
|
||||
});
|
||||
|
||||
describe("private class properties", () => {
|
||||
it("should not be undefined", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
class C {
|
||||
#d = 1;
|
||||
}
|
||||
`,
|
||||
{ "no-undef": 1 },
|
||||
);
|
||||
describe("class field declarations", () => {
|
||||
describe("field declarations", () => {
|
||||
it("should not be undefined", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
class C {
|
||||
d = 1;
|
||||
}
|
||||
`,
|
||||
{ "no-undef": 1 },
|
||||
);
|
||||
});
|
||||
|
||||
it("should not be unused", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
export class C {
|
||||
d = 1;
|
||||
}
|
||||
`,
|
||||
{ "no-unused-vars": 1 },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("should not be unused", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
export class C {
|
||||
#d = 1;
|
||||
}
|
||||
`,
|
||||
{ "no-unused-vars": 1 },
|
||||
);
|
||||
describe("private field declarations", () => {
|
||||
it("should not be undefined", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
class C {
|
||||
#d = 1;
|
||||
}
|
||||
`,
|
||||
{ "no-undef": 1 },
|
||||
);
|
||||
});
|
||||
|
||||
it("should not be unused", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
export class C {
|
||||
#d = 1;
|
||||
}
|
||||
`,
|
||||
{ "no-unused-vars": 1 },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("private methods", () => {
|
||||
it("should not be undefined", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
class C {
|
||||
#d() {};
|
||||
}
|
||||
`,
|
||||
{ "no-undef": 1 },
|
||||
);
|
||||
});
|
||||
|
||||
it("should not be unused", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
export class C {
|
||||
#d() {};
|
||||
}
|
||||
`,
|
||||
{ "no-unused-vars": 1 },
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1841,6 +1901,22 @@ describe("verify", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("works with classPrivateMethods", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
class A { #a(b, c) {} }
|
||||
`,
|
||||
);
|
||||
});
|
||||
|
||||
it("works with arrow function classPrivateProperties", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
class A { #a = (a, b) => {}; }
|
||||
`,
|
||||
);
|
||||
});
|
||||
|
||||
it("works with optionalCatchBinding", () => {
|
||||
verifyAndAssertMessages(
|
||||
`
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@babel/eslint-plugin-development",
|
||||
"version": "1.0.1",
|
||||
"description": "A set of eslint rules to enforce best practices in the development of Babel plugins.",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "ESLint rules that enforce best practices in the development of Babel plugins.",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"eslint",
|
||||
@@ -18,7 +18,7 @@
|
||||
"eslint": "^5.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
"node": ">=10.9"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -26,6 +26,11 @@
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/babel/eslint-plugin-babel-plugin.git"
|
||||
}
|
||||
"url": "https://github.com/babel/babel.git",
|
||||
"directory": "eslint/babel-eslint-plugin-development"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/babel/babel/issues"
|
||||
},
|
||||
"homepage": "https://github.com/babel/babel/tree/master/eslint/babel-eslint-plugin-development"
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
"use strict";
|
||||
import noDeprecatedClone from "./rules/no-deprecated-clone";
|
||||
import noUndefinedIdentifier from "./rules/no-undefined-identifier";
|
||||
import pluginName from "./rules/plugin-name";
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
rules: {
|
||||
"no-deprecated-clone": require("./rules/no-deprecated-clone"),
|
||||
"no-undefined-identifier": require("./rules/no-undefined-identifier"),
|
||||
"plugin-name": require("./rules/plugin-name"),
|
||||
"no-deprecated-clone": noDeprecatedClone,
|
||||
"no-undefined-identifier": noUndefinedIdentifier,
|
||||
"plugin-name": pluginName,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
"use strict";
|
||||
import getReferenceOrigin from "../utils/get-reference-origin";
|
||||
import isFromBabelTypes from "../utils/is-from-babel-types";
|
||||
|
||||
const getReferenceOrigin = require("../utils/get-reference-origin");
|
||||
const isFromBabelTypes = require("../utils/is-from-babel-types");
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
meta: {
|
||||
schema: [],
|
||||
fixable: "code",
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const getReferenceOrigin = require("../utils/get-reference-origin");
|
||||
const isFromBabelTypes = require("../utils/is-from-babel-types");
|
||||
import getReferenceOrigin from "../utils/get-reference-origin";
|
||||
import isFromBabelTypes from "../utils/is-from-babel-types";
|
||||
|
||||
function firstArgumentIsUndefinedString(argumentsArray) {
|
||||
return (
|
||||
@@ -11,7 +9,7 @@ function firstArgumentIsUndefinedString(argumentsArray) {
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
meta: {
|
||||
schema: [],
|
||||
},
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
const isBabelPluginFactory = require("../utils/is-babel-plugin-factory");
|
||||
import isBabelPluginFactory from "../utils/is-babel-plugin-factory";
|
||||
|
||||
function getReturnValue(node) {
|
||||
const { body } = node;
|
||||
@@ -14,7 +12,7 @@ function getReturnValue(node) {
|
||||
return body;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
meta: {
|
||||
schema: [],
|
||||
},
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function getExportName(node) {
|
||||
export default function getExportName(node) {
|
||||
const { parent } = node;
|
||||
|
||||
if (parent.type === "ExportDefaultDeclaration") {
|
||||
@@ -21,4 +19,4 @@ module.exports = function getExportName(node) {
|
||||
) {
|
||||
return "module.exports";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = getReferenceOrigin;
|
||||
|
||||
/*::
|
||||
type ReferenceOriginImport = { kind: "import", source: string, name: string };
|
||||
type ReferenceOriginParam = {
|
||||
@@ -26,7 +22,10 @@ type ReferenceOrigin =
|
||||
// from.
|
||||
// It resolves imports, parameters of exported functions and property accesses.
|
||||
// See the ReferenceOrigin type for more informations.
|
||||
function getReferenceOrigin(node, scope) /*: ?ReferenceOrigin */ {
|
||||
export default function getReferenceOrigin(
|
||||
node,
|
||||
scope,
|
||||
) /*: ?ReferenceOrigin */ {
|
||||
if (node.type === "Identifier") {
|
||||
const variable = getVariableDefinition(node.name, scope);
|
||||
if (!variable) return null;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
"use strict";
|
||||
import getReferenceOrigin from "./get-reference-origin";
|
||||
import getExportName from "./get-export-name";
|
||||
|
||||
const getReferenceOrigin = require("./get-reference-origin");
|
||||
const getExportName = require("./get-export-name");
|
||||
|
||||
module.exports = function isBabelPluginFactory(node, scope) {
|
||||
export default function isBabelPluginFactory(node, scope) {
|
||||
const { parent } = node;
|
||||
|
||||
if (parent.type === "CallExpression") {
|
||||
@@ -23,4 +21,4 @@ module.exports = function isBabelPluginFactory(node, scope) {
|
||||
// export default function ({ types: t }) {}
|
||||
// module.exports = function ({ types: t }) {}
|
||||
return exportName === "default" || exportName === "module.exports";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
const isBabelPluginFactory = require("./is-babel-plugin-factory");
|
||||
import isBabelPluginFactory from "./is-babel-plugin-factory";
|
||||
|
||||
// Check if a ReferenceOrigin (returned by ./get-reference-origin.js)
|
||||
// is a reference to a @babel/types export.
|
||||
module.exports = function isFromBabelTypes(
|
||||
export default function isFromBabelTypes(
|
||||
origin /*: ReferenceOrigin */,
|
||||
scope /*: Scope */,
|
||||
) {
|
||||
@@ -32,4 +30,4 @@ module.exports = function isFromBabelTypes(
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const rule = require("../../src/rules/no-deprecated-clone");
|
||||
const { RuleTester } = require("eslint");
|
||||
import rule from "../../src/rules/no-deprecated-clone";
|
||||
import { RuleTester } from "eslint";
|
||||
|
||||
const cloneError = "t.clone() is deprecated. Use t.cloneNode() instead.";
|
||||
const cloneDeepError =
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const rule = require("../../src/rules/no-undefined-identifier");
|
||||
const { RuleTester } = require("eslint");
|
||||
import rule from "../../src/rules/no-undefined-identifier";
|
||||
import { RuleTester } from "eslint";
|
||||
|
||||
const error =
|
||||
"Use path.scope.buildUndefinedNode() to create an undefined identifier directly.";
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const rule = require("../../src/rules/plugin-name");
|
||||
const { RuleTester } = require("eslint");
|
||||
import rule from "../../src/rules/plugin-name";
|
||||
import { RuleTester } from "eslint";
|
||||
|
||||
const missingPluginError = "This file does not export a Babel plugin.";
|
||||
const missingNameError = "This Babel plugin doesn't have a 'name' property.";
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
# eslint-plugin-babel
|
||||
# @babel/eslint-plugin
|
||||
|
||||
An `eslint` plugin companion to `babel-eslint`. `babel-eslint` does a great job at adapting `eslint`
|
||||
for use with Babel, but it can't change the built in rules to support experimental features.
|
||||
`eslint-plugin-babel` re-implements problematic rules so they do not give false positives or negatives.
|
||||
Companion rules for `@babel/eslint-parser`. `@babel/eslint-parser` does a great job at adapting `eslint`
|
||||
for use with Babel, but it can't change the built-in rules to support experimental features.
|
||||
`@babel/eslint-plugin` re-implements problematic rules so they do not give false positives or negatives.
|
||||
|
||||
> Requires Node 4 or greater
|
||||
> Requires Node 10.9 or greater
|
||||
|
||||
### Install
|
||||
|
||||
```sh
|
||||
npm install eslint-plugin-babel --save-dev
|
||||
npm install @babel/eslint-plugin --save-dev
|
||||
```
|
||||
|
||||
Load the plugin in your `.eslintrc` file:
|
||||
Load the plugin in your `.eslintrc.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": [
|
||||
"babel"
|
||||
]
|
||||
"plugins": ["@babel/eslint-plugin"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -28,40 +26,22 @@ original ones as well!).
|
||||
```json
|
||||
{
|
||||
"rules": {
|
||||
"babel/new-cap": 1,
|
||||
"babel/camelcase": 1,
|
||||
"babel/no-invalid-this": 1,
|
||||
"babel/object-curly-spacing": 1,
|
||||
"babel/quotes": 1,
|
||||
"babel/semi": 1,
|
||||
"babel/no-unused-expressions": 1,
|
||||
"babel/valid-typeof": 1
|
||||
"babel/new-cap": "error",
|
||||
"babel/no-invalid-this": "error",
|
||||
"babel/no-unused-expressions": "error",
|
||||
"babel/object-curly-spacing": "error",
|
||||
"babel/semi": "error",
|
||||
}
|
||||
}
|
||||
```
|
||||
### Rules
|
||||
|
||||
Each rule corresponds to a core `eslint` rule, and has the same options.
|
||||
Each rule corresponds to a core `eslint` rule and has the same options.
|
||||
|
||||
🛠: means it's autofixable with `--fix`.
|
||||
|
||||
- `babel/new-cap`: Ignores capitalized decorators (`@Decorator`)
|
||||
- `babel/camelcase: doesn't complain about optional chaining (`var foo = bar?.a_b;`)
|
||||
- `babel/no-invalid-this`: doesn't fail when inside class properties (`class A { a = this.b; }`)
|
||||
- `babel/object-curly-spacing`: doesn't complain about `export x from "mod";` or `export * as x from "mod";` (🛠)
|
||||
- `babel/quotes`: doesn't complain about JSX fragment shorthand syntax (`<>foo</>;`)
|
||||
- `babel/semi`: doesn't fail when using `for await (let something of {})`. Includes class properties (🛠)
|
||||
- `babel/no-unused-expressions`: doesn't fail when using `do` expressions or [optional chaining](https://github.com/tc39/proposal-optional-chaining) (`a?.b()`).
|
||||
- `babel/valid-typeof`: doesn't complain when used with [BigInt](https://github.com/tc39/proposal-bigint) (`typeof BigInt(9007199254740991) === 'bigint'`).
|
||||
|
||||
#### Deprecated
|
||||
|
||||
| Rule | Notes |
|
||||
|:---------------------------------|:-----------------------------------|
|
||||
| `babel/generator-star-spacing` | Use [`generator-star-spacing`](http://eslint.org/docs/rules/generator-star-spacing) since eslint@3.6.0 |
|
||||
| `babel/object-shorthand` | Use [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand) since eslint@0.20.0 |
|
||||
| `babel/arrow-parens` | Use [`arrow-parens`](http://eslint.org/docs/rules/arrow-parens) since eslint@3.10.0 |
|
||||
| `babel/func-params-comma-dangle` | Use [`comma-dangle`](http://eslint.org/docs/rules/comma-dangle) since eslint@3.8.0 |
|
||||
| `babel/array-bracket-spacing` | Use [`array-bracket-spacing`](http://eslint.org/docs/rules/array-bracket-spacing) since eslint@3.9.0 |
|
||||
| `babel/flow-object-type` | Use [`flowtype/object-type-delimiter`](https://github.com/gajus/eslint-plugin-flowtype#eslint-plugin-flowtype-rules-object-type-delimiter) since eslint-plugin-flowtype@2.23.0 |
|
||||
| `babel/no-await-in-loop` | Use [`no-await-in-loop`](http://eslint.org/docs/rules/no-await-in-loop) since eslint@3.12.0 |
|
||||
- `babel/new-cap`: handles decorators (`@Decorator`)
|
||||
- `babel/no-invalid-this`: handles class fields and private class methods (`class A { a = this.b; }`)
|
||||
- `babel/no-unused-expressions`: handles `do` expressions
|
||||
- `babel/object-curly-spacing`: handles `export * as x from "mod";` (🛠)
|
||||
- `babel/semi`: Handles class properties (🛠)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"name": "eslint-plugin-babel",
|
||||
"version": "5.3.0",
|
||||
"description": "an eslint rule plugin companion to babel-eslint",
|
||||
"name": "@babel/eslint-plugin",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "Companion rules for @babel/eslint-parser",
|
||||
"main": "lib/index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/babel/eslint-plugin-babel.git"
|
||||
"url": "git+https://github.com/babel/babel.git",
|
||||
"directory": "eslint/babel-eslint-plugin"
|
||||
},
|
||||
"keywords": [
|
||||
"babel",
|
||||
@@ -18,21 +19,23 @@
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"node": ">=10.9"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/babel/eslint-plugin-babel/issues"
|
||||
"url": "https://github.com/babel/babel/issues"
|
||||
},
|
||||
"homepage": "https://github.com/babel/eslint-plugin-babel#readme",
|
||||
"homepage": "https://github.com/babel/babel/tree/master/eslint/babel-eslint-plugin",
|
||||
"peerDependencies": {
|
||||
"eslint": ">=4.0.0"
|
||||
"@babel/eslint-parser": "0.0.0",
|
||||
"eslint": ">=6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-rule-composer": "^0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^8.2.2",
|
||||
"eslint": "^4.19.1",
|
||||
"@babel/eslint-parser": "7.8.3-csx.2",
|
||||
"@babel/eslint-shared-fixtures": "7.8.3-csx.2",
|
||||
"eslint": "^6.0.0",
|
||||
"lodash.clonedeep": "^4.5.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +1,22 @@
|
||||
"use strict";
|
||||
import newCap from "./rules/new-cap";
|
||||
import noInvalidThis from "./rules/no-invalid-this";
|
||||
import noUnusedExpressions from "./rules/no-unused-expressions";
|
||||
import objectCurlySpacing from "./rules/object-curly-spacing";
|
||||
import semi from "./rules/semi";
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
"array-bracket-spacing": require("./rules/array-bracket-spacing"),
|
||||
"arrow-parens": require("./rules/arrow-parens"),
|
||||
"flow-object-type": require("./rules/flow-object-type"),
|
||||
"func-params-comma-dangle": require("./rules/func-params-comma-dangle"),
|
||||
"generator-star-spacing": require("./rules/generator-star-spacing"),
|
||||
"new-cap": require("./rules/new-cap"),
|
||||
camelcase: require("./rules/camelcase"),
|
||||
"no-await-in-loop": require("./rules/no-await-in-loop"),
|
||||
"no-invalid-this": require("./rules/no-invalid-this"),
|
||||
"no-unused-expressions": require("./rules/no-unused-expressions"),
|
||||
"object-curly-spacing": require("./rules/object-curly-spacing"),
|
||||
"object-shorthand": require("./rules/object-shorthand"),
|
||||
quotes: require("./rules/quotes"),
|
||||
semi: require("./rules/semi"),
|
||||
"valid-typeof": require("./rules/valid-typeof"),
|
||||
"new-cap": newCap,
|
||||
"no-invalid-this": noInvalidThis,
|
||||
"no-unused-expressions": noUnusedExpressions,
|
||||
"object-curly-spacing": objectCurlySpacing,
|
||||
semi,
|
||||
},
|
||||
rulesConfig: {
|
||||
"array-bracket-spacing": 0,
|
||||
"arrow-parens": 0,
|
||||
camelcase: 0,
|
||||
"flow-object-type": 0,
|
||||
"func-params-comma-dangle": 0,
|
||||
"generator-star-spacing": 0,
|
||||
"new-cap": 0,
|
||||
"no-await-in-loop": 0,
|
||||
"no-invalid-this": 0,
|
||||
"no-unused-expressions": 0,
|
||||
"object-curly-spacing": 0,
|
||||
"object-shorthand": 0,
|
||||
quotes: 0,
|
||||
semi: 0,
|
||||
"valid-typeof": 0,
|
||||
"new-cap": "off",
|
||||
"no-invalid-this": "off",
|
||||
"no-unused-expressions": "off",
|
||||
"object-curly-spacing": "off",
|
||||
semi: "off",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
let isWarnedForDeprecation = false;
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: true,
|
||||
schema: [
|
||||
{
|
||||
enum: ["always", "never"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
singleValue: {
|
||||
type: "boolean",
|
||||
},
|
||||
objectsInArrays: {
|
||||
type: "boolean",
|
||||
},
|
||||
arraysInArrays: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
create: function() {
|
||||
return {
|
||||
Program: function() {
|
||||
if (
|
||||
isWarnedForDeprecation ||
|
||||
/=-(f|-format)=/.test(process.argv.join("="))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"The babel/array-bracket-spacing rule is deprecated. Please " +
|
||||
"use the built in array-bracket-spacing rule instead.",
|
||||
);
|
||||
isWarnedForDeprecation = true;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
let isWarnedForDeprecation = false;
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: true,
|
||||
schema: [
|
||||
{
|
||||
enum: ["always", "as-needed"],
|
||||
},
|
||||
],
|
||||
},
|
||||
create: function() {
|
||||
return {
|
||||
Program: function() {
|
||||
if (
|
||||
isWarnedForDeprecation ||
|
||||
/=-(f|-format)=/.test(process.argv.join("="))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"The babel/arrow-parens rule is deprecated. Please " +
|
||||
"use the built in arrow-parens rule instead.",
|
||||
);
|
||||
isWarnedForDeprecation = true;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,231 +0,0 @@
|
||||
/**
|
||||
* @fileoverview Rule to flag non-camelcased identifiers
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "enforce camelcase naming convention",
|
||||
category: "Stylistic Issues",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/rules/camelcase",
|
||||
},
|
||||
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
ignoreDestructuring: {
|
||||
type: "boolean",
|
||||
},
|
||||
properties: {
|
||||
enum: ["always", "never"],
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
|
||||
messages: {
|
||||
notCamelCase: "Identifier '{{name}}' is not in camel case.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
//--------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// contains reported nodes to avoid reporting twice on destructuring with shorthand notation
|
||||
const reported = [];
|
||||
const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]);
|
||||
const MEMBER_EXPRESSIONS = ["MemberExpression", "OptionalMemberExpression"];
|
||||
|
||||
/**
|
||||
* Checks if expression is supported member expression.
|
||||
*
|
||||
* @param {string} expression - An expression to check.
|
||||
* @returns {boolean} `true` if the expression type is supported
|
||||
*/
|
||||
function isMemberExpression(expression) {
|
||||
return MEMBER_EXPRESSIONS.indexOf(expression) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string contains an underscore and isn't all upper-case
|
||||
* @param {string} name The string to check.
|
||||
* @returns {boolean} if the string is underscored
|
||||
* @private
|
||||
*/
|
||||
function isUnderscored(name) {
|
||||
// if there's an underscore, it might be A_CONSTANT, which is okay
|
||||
return name.indexOf("_") > -1 && name !== name.toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a parent of a node is an ObjectPattern.
|
||||
* @param {ASTNode} node The node to check.
|
||||
* @returns {boolean} if the node is inside an ObjectPattern
|
||||
* @private
|
||||
*/
|
||||
function isInsideObjectPattern(node) {
|
||||
let { parent } = node;
|
||||
|
||||
while (parent) {
|
||||
if (parent.type === "ObjectPattern") {
|
||||
return true;
|
||||
}
|
||||
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports an AST node as a rule violation.
|
||||
* @param {ASTNode} node The node to report.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function report(node) {
|
||||
if (reported.indexOf(node.parent) < 0) {
|
||||
reported.push(node.parent);
|
||||
context.report({
|
||||
node,
|
||||
messageId: "notCamelCase",
|
||||
data: { name: node.name },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const options = context.options[0] || {};
|
||||
let properties = options.properties || "";
|
||||
const ignoreDestructuring = options.ignoreDestructuring || false;
|
||||
|
||||
if (properties !== "always" && properties !== "never") {
|
||||
properties = "always";
|
||||
}
|
||||
|
||||
return {
|
||||
Identifier(node) {
|
||||
/*
|
||||
* Leading and trailing underscores are commonly used to flag
|
||||
* private/protected identifiers, strip them
|
||||
*/
|
||||
const name = node.name.replace(/^_+|_+$/g, ""),
|
||||
effectiveParent = isMemberExpression(node.parent.type)
|
||||
? node.parent.parent
|
||||
: node.parent;
|
||||
|
||||
// MemberExpressions get special rules
|
||||
if (isMemberExpression(node.parent.type)) {
|
||||
// "never" check properties
|
||||
if (properties === "never") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Always report underscored object names
|
||||
if (
|
||||
node.parent.object.type === "Identifier" &&
|
||||
node.parent.object.name === node.name &&
|
||||
isUnderscored(name)
|
||||
) {
|
||||
report(node);
|
||||
|
||||
// Report AssignmentExpressions only if they are the left side of the assignment
|
||||
} else if (
|
||||
effectiveParent.type === "AssignmentExpression" &&
|
||||
isUnderscored(name) &&
|
||||
(!isMemberExpression(effectiveParent.right.type) ||
|
||||
(isMemberExpression(effectiveParent.left.type) &&
|
||||
effectiveParent.left.property.name === node.name))
|
||||
) {
|
||||
report(node);
|
||||
}
|
||||
|
||||
/*
|
||||
* Properties have their own rules, and
|
||||
* AssignmentPattern nodes can be treated like Properties:
|
||||
* e.g.: const { no_camelcased = false } = bar;
|
||||
*/
|
||||
} else if (
|
||||
node.parent.type === "Property" ||
|
||||
node.parent.type === "AssignmentPattern"
|
||||
) {
|
||||
if (
|
||||
node.parent.parent &&
|
||||
node.parent.parent.type === "ObjectPattern"
|
||||
) {
|
||||
const assignmentKeyEqualsValue =
|
||||
node.parent.key.name === node.parent.value.name;
|
||||
|
||||
// prevent checking righthand side of destructured object
|
||||
if (node.parent.key === node && node.parent.value !== node) {
|
||||
return;
|
||||
}
|
||||
|
||||
const valueIsUnderscored =
|
||||
node.parent.value.name && isUnderscored(name);
|
||||
|
||||
// ignore destructuring if the option is set, unless a new identifier is created
|
||||
if (
|
||||
valueIsUnderscored &&
|
||||
!(assignmentKeyEqualsValue && ignoreDestructuring)
|
||||
) {
|
||||
report(node);
|
||||
}
|
||||
}
|
||||
|
||||
// "never" check properties or always ignore destructuring
|
||||
if (
|
||||
properties === "never" ||
|
||||
(ignoreDestructuring && isInsideObjectPattern(node))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't check right hand side of AssignmentExpression to prevent duplicate warnings
|
||||
if (
|
||||
isUnderscored(name) &&
|
||||
!ALLOWED_PARENT_TYPES.has(effectiveParent.type) &&
|
||||
!(node.parent.right === node)
|
||||
) {
|
||||
report(node);
|
||||
}
|
||||
|
||||
// Check if it's an import specifier
|
||||
} else if (
|
||||
[
|
||||
"ImportSpecifier",
|
||||
"ImportNamespaceSpecifier",
|
||||
"ImportDefaultSpecifier",
|
||||
].indexOf(node.parent.type) >= 0
|
||||
) {
|
||||
// Report only if the local imported identifier is underscored
|
||||
if (
|
||||
node.parent.local &&
|
||||
node.parent.local.name === node.name &&
|
||||
isUnderscored(name)
|
||||
) {
|
||||
report(node);
|
||||
}
|
||||
|
||||
// Report anything that is underscored that isn't a CallExpression
|
||||
} else if (
|
||||
isUnderscored(name) &&
|
||||
!ALLOWED_PARENT_TYPES.has(effectiveParent.type)
|
||||
) {
|
||||
report(node);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
let isWarnedForDeprecation = false;
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: true,
|
||||
schema: [
|
||||
{
|
||||
enum: ["semicolon", "comma"],
|
||||
},
|
||||
],
|
||||
},
|
||||
create: function() {
|
||||
return {
|
||||
Program: function() {
|
||||
if (
|
||||
isWarnedForDeprecation ||
|
||||
/=-(f|-format)=/.test(process.argv.join("="))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"The babel/flow-object-type rule is deprecated. Please " +
|
||||
"use the flowtype/object-type-delimiter rule instead.\n" +
|
||||
// eslint-disable-next-line
|
||||
"Check out https://github.com/gajus/eslint-plugin-flowtype#eslint-plugin-flowtype-rules-object-type-delimiter"
|
||||
);
|
||||
|
||||
isWarnedForDeprecation = true;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
let isWarnedForDeprecation = false;
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: true,
|
||||
schema: [
|
||||
{
|
||||
enum: ["always", "always-multiline", "only-multiline", "never"],
|
||||
},
|
||||
],
|
||||
},
|
||||
create: function() {
|
||||
return {
|
||||
Program: function() {
|
||||
if (
|
||||
isWarnedForDeprecation ||
|
||||
/=-(f|-format)=/.test(process.argv.join("="))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"The babel/func-params-comma-dangle rule is deprecated. Please " +
|
||||
"use the built in comma-dangle rule instead.",
|
||||
);
|
||||
isWarnedForDeprecation = true;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
let isWarnedForDeprecation = false;
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: true,
|
||||
schema: [
|
||||
{
|
||||
oneOf: [
|
||||
{
|
||||
enum: ["before", "after", "both", "neither"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
before: { type: "boolean" },
|
||||
after: { type: "boolean" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
create: function() {
|
||||
return {
|
||||
Program: function() {
|
||||
if (
|
||||
isWarnedForDeprecation ||
|
||||
/=-(f|-format)=/.test(process.argv.join("="))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"The babel/generator-star-spacing rule is deprecated. Please " +
|
||||
"use the built in generator-star-spacing rule instead.",
|
||||
);
|
||||
isWarnedForDeprecation = true;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
import ruleComposer from "eslint-rule-composer";
|
||||
import eslint from "eslint";
|
||||
|
||||
const ruleComposer = require("eslint-rule-composer");
|
||||
const eslint = require("eslint");
|
||||
const newCapRule = new eslint.Linter().getRules().get("new-cap");
|
||||
const rule = new eslint.Linter().getRules().get("new-cap");
|
||||
|
||||
/**
|
||||
* Returns whether a node is under a decorator or not.
|
||||
@@ -13,7 +12,7 @@ function isDecorator(node) {
|
||||
return node.parent.type === "Decorator";
|
||||
}
|
||||
|
||||
module.exports = ruleComposer.filterReports(
|
||||
newCapRule,
|
||||
export default ruleComposer.filterReports(
|
||||
rule,
|
||||
problem => !isDecorator(problem.node),
|
||||
);
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
let isWarnedForDeprecation = false;
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: true,
|
||||
schema: [],
|
||||
},
|
||||
create: function() {
|
||||
return {
|
||||
Program: function() {
|
||||
if (
|
||||
isWarnedForDeprecation ||
|
||||
/=-(f|-format)=/.test(process.argv.join("="))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"The babel/no-await-in-loop rule is deprecated. Please " +
|
||||
"use the built in no-await-in-loop rule instead.",
|
||||
);
|
||||
isWarnedForDeprecation = true;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,10 +1,9 @@
|
||||
"use strict";
|
||||
import ruleComposer from "eslint-rule-composer";
|
||||
import eslint from "eslint";
|
||||
|
||||
const ruleComposer = require("eslint-rule-composer");
|
||||
const eslint = require("eslint");
|
||||
const noInvalidThisRule = new eslint.Linter().getRules().get("no-invalid-this");
|
||||
|
||||
module.exports = ruleComposer.filterReports(noInvalidThisRule, problem => {
|
||||
export default ruleComposer.filterReports(noInvalidThisRule, problem => {
|
||||
let inClassProperty = false;
|
||||
let node = problem.node;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
import ruleComposer from "eslint-rule-composer";
|
||||
import eslint from "eslint";
|
||||
|
||||
const ruleComposer = require("eslint-rule-composer");
|
||||
const eslint = require("eslint");
|
||||
const rule = new eslint.Linter().getRules().get("no-unused-expressions");
|
||||
|
||||
/**
|
||||
@@ -22,6 +21,7 @@ function isFinalStatementInBlockStatement(node) {
|
||||
* @param {ASTNode} node - any node
|
||||
* @returns {boolean} whether the given node represents an unbroken chain of
|
||||
* tail ExpressionStatements and IfStatements within a DoExpression
|
||||
* https://github.com/tc39/proposal-do-expressions
|
||||
*/
|
||||
function isInDoStatement(node) {
|
||||
if (!node) return false;
|
||||
@@ -47,7 +47,7 @@ function isInDoStatement(node) {
|
||||
/**
|
||||
* @param {ASTNode} node - any node
|
||||
* @returns {boolean} whether the given node is an optional call expression,
|
||||
* see https://github.com/tc39/proposal-optional-chaining
|
||||
* https://github.com/tc39/proposal-optional-chaining
|
||||
*/
|
||||
function isOptionalCallExpression(node) {
|
||||
return (
|
||||
@@ -57,7 +57,7 @@ function isOptionalCallExpression(node) {
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = ruleComposer.filterReports(
|
||||
export default ruleComposer.filterReports(
|
||||
rule,
|
||||
problem =>
|
||||
!isInDoStatement(problem.node) && !isOptionalCallExpression(problem.node),
|
||||
|
||||
@@ -1,27 +1,20 @@
|
||||
"use strict";
|
||||
import ruleComposer from "eslint-rule-composer";
|
||||
import eslint from "eslint";
|
||||
|
||||
const ruleComposer = require("eslint-rule-composer");
|
||||
const eslint = require("eslint");
|
||||
const objectCurlySpacingRule = new eslint.Linter()
|
||||
.getRules()
|
||||
.get("object-curly-spacing");
|
||||
const rule = new eslint.Linter().getRules().get("object-curly-spacing");
|
||||
|
||||
module.exports = ruleComposer.filterReports(
|
||||
objectCurlySpacingRule,
|
||||
(problem, metadata) => {
|
||||
const node = problem.node;
|
||||
export default ruleComposer.filterReports(rule, problem => {
|
||||
const node = problem.node;
|
||||
|
||||
// Allow `exportNamespaceFrom` and `exportDefaultFrom` syntax:
|
||||
// export * as x from '...';
|
||||
// export x from '...';
|
||||
if (
|
||||
node.type === "ExportNamedDeclaration" &&
|
||||
node.specifiers.length > 0 &&
|
||||
metadata.sourceCode.getTokenBefore(node.specifiers[0]).value === "export"
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
// Allow exportDefaultFrom syntax:
|
||||
// export x from '...';
|
||||
if (
|
||||
node.type === "ExportNamedDeclaration" &&
|
||||
node.specifiers.length === 1 &&
|
||||
node.specifiers[0].type === "ExportDefaultSpecifier"
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
);
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
let isWarnedForDeprecation = false;
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: true,
|
||||
schema: [
|
||||
{
|
||||
enum: ["always", "methods", "properties", "never"],
|
||||
},
|
||||
],
|
||||
},
|
||||
create: function() {
|
||||
return {
|
||||
Program: function() {
|
||||
if (
|
||||
isWarnedForDeprecation ||
|
||||
/=-(f|-format)=/.test(process.argv.join("="))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"The babel/object-shorthand rule is deprecated. Please " +
|
||||
"use the built in object-shorthand rule instead.",
|
||||
);
|
||||
isWarnedForDeprecation = true;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const ruleComposer = require("eslint-rule-composer");
|
||||
const eslint = require("eslint");
|
||||
const quotesRule = new eslint.Linter().getRules().get("quotes");
|
||||
|
||||
module.exports = ruleComposer.filterReports(quotesRule, problem => {
|
||||
// Workaround for JSX fragment syntax until
|
||||
// https://github.com/eslint/eslint/issues/9662
|
||||
if (problem.node.parent.type === "JSXFragment") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
@@ -1,14 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
const ruleComposer = require("eslint-rule-composer");
|
||||
const eslint = require("eslint");
|
||||
const semiRule = new eslint.Linter().getRules().get("semi");
|
||||
import ruleComposer from "eslint-rule-composer";
|
||||
import eslint from "eslint";
|
||||
|
||||
const OPT_OUT_PATTERN = /^[-[(/+`]/; // One of [(/+-`
|
||||
|
||||
const isSemicolon = token => token.type === "Punctuator" && token.value === ";";
|
||||
const rule = new eslint.Linter().getRules().get("semi");
|
||||
|
||||
const isUnnecessarySemicolon = (context, lastToken) => {
|
||||
function isSemicolon(token) {
|
||||
return token.type === "Punctuator" && token.value === ";";
|
||||
}
|
||||
|
||||
function isUnnecessarySemicolon(context, lastToken) {
|
||||
if (!isSemicolon(lastToken)) {
|
||||
return false;
|
||||
}
|
||||
@@ -28,9 +29,9 @@ const isUnnecessarySemicolon = (context, lastToken) => {
|
||||
const isDivider = nextToken.value === "}" || nextToken.value === ";";
|
||||
|
||||
return (lastTokenLine !== nextTokenLine && !isOptOutToken) || isDivider;
|
||||
};
|
||||
}
|
||||
|
||||
const isOneLinerBlock = (context, node) => {
|
||||
function isOneLinerBlock(context, node) {
|
||||
const nextToken = context.getSourceCode().getTokenAfter(node);
|
||||
|
||||
if (!nextToken || nextToken.value !== "}") {
|
||||
@@ -44,9 +45,9 @@ const isOneLinerBlock = (context, node) => {
|
||||
parent.type === "BlockStatement" &&
|
||||
parent.loc.start.line === parent.loc.end.line
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
const report = (context, node, missing) => {
|
||||
function report(context, node, missing) {
|
||||
const lastToken = context.getSourceCode().getLastToken(node);
|
||||
|
||||
let message,
|
||||
@@ -73,15 +74,14 @@ const report = (context, node, missing) => {
|
||||
message,
|
||||
fix,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const semiRuleWithClassProperty = ruleComposer.joinReports([
|
||||
semiRule,
|
||||
export default ruleComposer.joinReports([
|
||||
rule,
|
||||
context => ({
|
||||
ClassProperty(node) {
|
||||
const options = context.options[1];
|
||||
const exceptOneLine = options && options.omitLastInOneLineBlock === true;
|
||||
|
||||
const sourceCode = context.getSourceCode();
|
||||
const lastToken = sourceCode.getLastToken(node);
|
||||
|
||||
@@ -103,21 +103,3 @@ const semiRuleWithClassProperty = ruleComposer.joinReports([
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
module.exports = ruleComposer.filterReports(
|
||||
semiRuleWithClassProperty,
|
||||
problem => {
|
||||
const node = problem.node;
|
||||
|
||||
// Handle async iterator:
|
||||
// for await (let something of {})
|
||||
if (
|
||||
node.type === "VariableDeclaration" &&
|
||||
node.parent.type === "ForAwaitStatement"
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const ruleComposer = require("eslint-rule-composer");
|
||||
const eslint = require("eslint");
|
||||
const validTypeOf = new eslint.Linter().getRules().get("valid-typeof");
|
||||
|
||||
module.exports = ruleComposer.filterReports(validTypeOf, problem => {
|
||||
return problem.node.value !== "bigint";
|
||||
});
|
||||
@@ -1,7 +1,14 @@
|
||||
var RuleTester = require("eslint").RuleTester;
|
||||
import { RuleTester } from "eslint";
|
||||
|
||||
RuleTester.setDefaultConfig({
|
||||
parser: 'babel-eslint'
|
||||
parser: require.resolve("@babel/eslint-parser"),
|
||||
parserOptions: {
|
||||
babelOptions: {
|
||||
configFile: require.resolve(
|
||||
"@babel/eslint-shared-fixtures/config/babel.config.js",
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = RuleTester;
|
||||
export default RuleTester;
|
||||
|
||||
@@ -1,572 +0,0 @@
|
||||
/**
|
||||
* @fileoverview Tests for camelcase rule.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const rule = require("../../src/rules/camelcase"),
|
||||
RuleTester = require("../helpers/RuleTester");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Tests
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run("camelcase", rule, {
|
||||
valid: [
|
||||
// Original test cases.
|
||||
'firstName = "Nicholas"',
|
||||
'FIRST_NAME = "Nicholas"',
|
||||
'__myPrivateVariable = "Patrick"',
|
||||
'myPrivateVariable_ = "Patrick"',
|
||||
"function doSomething(){}",
|
||||
"do_something()",
|
||||
"new do_something",
|
||||
"new do_something()",
|
||||
"foo.do_something()",
|
||||
"var foo = bar.baz_boom;",
|
||||
"var foo = bar.baz_boom.something;",
|
||||
"foo.boom_pow.qux = bar.baz_boom.something;",
|
||||
"if (bar.baz_boom) {}",
|
||||
"var obj = { key: foo.bar_baz };",
|
||||
"var arr = [foo.bar_baz];",
|
||||
"[foo.bar_baz]",
|
||||
"var arr = [foo.bar_baz.qux];",
|
||||
"[foo.bar_baz.nesting]",
|
||||
"if (foo.bar_baz === boom.bam_pow) { [foo.baz_boom] }",
|
||||
{
|
||||
code: "var o = {key: 1}",
|
||||
options: [{ properties: "always" }],
|
||||
},
|
||||
{
|
||||
code: "var o = {_leading: 1}",
|
||||
options: [{ properties: "always" }],
|
||||
},
|
||||
{
|
||||
code: "var o = {trailing_: 1}",
|
||||
options: [{ properties: "always" }],
|
||||
},
|
||||
{
|
||||
code: "var o = {bar_baz: 1}",
|
||||
options: [{ properties: "never" }],
|
||||
},
|
||||
{
|
||||
code: "var o = {_leading: 1}",
|
||||
options: [{ properties: "never" }],
|
||||
},
|
||||
{
|
||||
code: "var o = {trailing_: 1}",
|
||||
options: [{ properties: "never" }],
|
||||
},
|
||||
{
|
||||
code: "obj.a_b = 2;",
|
||||
options: [{ properties: "never" }],
|
||||
},
|
||||
{
|
||||
code: "obj._a = 2;",
|
||||
options: [{ properties: "always" }],
|
||||
},
|
||||
{
|
||||
code: "obj.a_ = 2;",
|
||||
options: [{ properties: "always" }],
|
||||
},
|
||||
{
|
||||
code: "obj._a = 2;",
|
||||
options: [{ properties: "never" }],
|
||||
},
|
||||
{
|
||||
code: "obj.a_ = 2;",
|
||||
options: [{ properties: "never" }],
|
||||
},
|
||||
{
|
||||
code: "var obj = {\n a_a: 1 \n};\n obj.a_b = 2;",
|
||||
options: [{ properties: "never" }],
|
||||
},
|
||||
{
|
||||
code: "obj.foo_bar = function(){};",
|
||||
options: [{ properties: "never" }],
|
||||
},
|
||||
{
|
||||
code: "var { category_id } = query;",
|
||||
options: [{ ignoreDestructuring: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var { category_id: category_id } = query;",
|
||||
options: [{ ignoreDestructuring: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var { category_id = 1 } = query;",
|
||||
options: [{ ignoreDestructuring: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var { category_id: category } = query;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var { _leading } = query;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var { trailing_ } = query;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: 'import { camelCased } from "external module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: 'import { _leading } from "external module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: 'import { trailing_ } from "external module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: 'import { no_camelcased as camelCased } from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: 'import { no_camelcased as _leading } from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: 'import { no_camelcased as trailing_ } from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code:
|
||||
'import { no_camelcased as camelCased, anoterCamelCased } from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "function foo({ no_camelcased: camelCased }) {};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "function foo({ no_camelcased: _leading }) {};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "function foo({ no_camelcased: trailing_ }) {};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "function foo({ camelCased = 'default value' }) {};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "function foo({ _leading = 'default value' }) {};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "function foo({ trailing_ = 'default value' }) {};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "function foo({ camelCased }) {};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "function foo({ _leading }) {}",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "function foo({ trailing_ }) {}",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
|
||||
// Babel-specific test cases
|
||||
{
|
||||
code: "var foo = bar?.a_b;",
|
||||
options: [{ properties: "never" }],
|
||||
},
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: 'first_name = "Nicholas"',
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "first_name" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: '__private_first_name = "Patrick"',
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "__private_first_name" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "function foo_bar(){}",
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "foo_bar" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "obj.foo_bar = function(){};",
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "foo_bar" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "bar_baz.foo = function(){};",
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "bar_baz" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "[foo_bar.baz]",
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "foo_bar" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "if (foo.bar_baz === boom.bam_pow) { [foo_bar.baz] }",
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "foo_bar" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "foo.bar_baz = boom.bam_pow",
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "bar_baz" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var foo = { bar_baz: boom.bam_pow }",
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "bar_baz" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "foo.qux.boom_pow = { bar: boom.bam_pow }",
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "boom_pow" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var o = {bar_baz: 1}",
|
||||
options: [{ properties: "always" }],
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "bar_baz" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "obj.a_b = 2;",
|
||||
options: [{ properties: "always" }],
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "a_b" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var { category_id: category_alias } = query;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "category_alias" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var { category_id: category_alias } = query;",
|
||||
options: [{ ignoreDestructuring: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "category_alias" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var { category_id: categoryId, ...other_props } = query;",
|
||||
options: [{ ignoreDestructuring: true }],
|
||||
parserOptions: { ecmaVersion: 2018 },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "other_props" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var { category_id } = query;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "category_id" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var { category_id: category_id } = query;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "category_id" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var { category_id = 1 } = query;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Identifier 'category_id' is not in camel case.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'import no_camelcased from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "no_camelcased" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'import * as no_camelcased from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "no_camelcased" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'import { no_camelcased } from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "no_camelcased" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code:
|
||||
'import { no_camelcased as no_camel_cased } from "external module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "no_camel_cased" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'import { camelCased as no_camel_cased } from "external module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "no_camel_cased" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'import { camelCased, no_camelcased } from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "no_camelcased" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code:
|
||||
'import { no_camelcased as camelCased, another_no_camelcased } from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "another_no_camelcased" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'import camelCased, { no_camelcased } from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "no_camelcased" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code:
|
||||
'import no_camelcased, { another_no_camelcased as camelCased } from "external-module";',
|
||||
parserOptions: { ecmaVersion: 6, sourceType: "module" },
|
||||
errors: [
|
||||
{
|
||||
messageId: "notCamelCase",
|
||||
data: { name: "no_camelcased" },
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "function foo({ no_camelcased }) {};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Identifier 'no_camelcased' is not in camel case.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "function foo({ no_camelcased = 'default value' }) {};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Identifier 'no_camelcased' is not in camel case.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"const no_camelcased = 0; function foo({ camelcased_value = no_camelcased}) {}",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Identifier 'no_camelcased' is not in camel case.",
|
||||
type: "Identifier",
|
||||
},
|
||||
{
|
||||
message: "Identifier 'camelcased_value' is not in camel case.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "const { bar: no_camelcased } = foo;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Identifier 'no_camelcased' is not in camel case.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "function foo({ value_1: my_default }) {}",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Identifier 'my_default' is not in camel case.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "function foo({ isCamelcased: no_camelcased }) {};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Identifier 'no_camelcased' is not in camel case.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var { foo: bar_baz = 1 } = quz;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Identifier 'bar_baz' is not in camel case.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "const { no_camelcased = false } = bar;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Identifier 'no_camelcased' is not in camel case.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -1,300 +1,12 @@
|
||||
/**
|
||||
* @fileoverview Tests for new-cap rule.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
import rule from "../../src/rules/new-cap";
|
||||
import RuleTester from "../helpers/RuleTester";
|
||||
|
||||
var rule = require("../../src/rules/new-cap"),
|
||||
RuleTester = require("../helpers/RuleTester");
|
||||
|
||||
var ruleTester = new RuleTester();
|
||||
ruleTester.run("babel/new-cap", rule, {
|
||||
const ruleTester = new RuleTester();
|
||||
ruleTester.run("@babel/new-cap", rule, {
|
||||
valid: [
|
||||
// Original test cases.
|
||||
"var x = new Constructor();",
|
||||
"var x = new a.b.Constructor();",
|
||||
"var x = new a.b['Constructor']();",
|
||||
"var x = new a.b[Constructor]();",
|
||||
"var x = new a.b[constructor]();",
|
||||
"var x = new function(){};",
|
||||
"var x = new _;",
|
||||
"var x = new $;",
|
||||
"var x = new Σ;",
|
||||
"var x = new _x;",
|
||||
"var x = new $x;",
|
||||
"var x = new this;",
|
||||
"var x = Array(42)",
|
||||
"var x = Boolean(42)",
|
||||
"var x = Date(42)",
|
||||
"var x = Date.UTC(2000, 0)",
|
||||
"var x = Error('error')",
|
||||
"var x = Function('return 0')",
|
||||
"var x = Number(42)",
|
||||
"var x = Object(null)",
|
||||
"var x = RegExp(42)",
|
||||
"var x = String(42)",
|
||||
"var x = Symbol('symbol')",
|
||||
"var x = _();",
|
||||
"var x = $();",
|
||||
{ code: "var x = Foo(42)", options: [{ capIsNew: false }] },
|
||||
{ code: "var x = bar.Foo(42)", options: [{ capIsNew: false }] },
|
||||
{ code: "var x = Foo.bar(42)", options: [{ capIsNew: false }] },
|
||||
"var x = bar[Foo](42)",
|
||||
{ code: "var x = bar['Foo'](42)", options: [{ capIsNew: false }] },
|
||||
"var x = Foo.bar(42)",
|
||||
{ code: "var x = new foo(42)", options: [{ newIsCap: false }] },
|
||||
"var o = { 1: function() {} }; o[1]();",
|
||||
"var o = { 1: function() {} }; new o[1]();",
|
||||
{
|
||||
code: "var x = Foo(42);",
|
||||
options: [{ capIsNew: true, capIsNewExceptions: ["Foo"] }],
|
||||
},
|
||||
{
|
||||
code: "var x = Foo(42);",
|
||||
options: [{ capIsNewExceptionPattern: "^Foo" }],
|
||||
},
|
||||
{
|
||||
code: "var x = new foo(42);",
|
||||
options: [{ newIsCap: true, newIsCapExceptions: ["foo"] }],
|
||||
},
|
||||
{
|
||||
code: "var x = new foo(42);",
|
||||
options: [{ newIsCapExceptionPattern: "^foo" }],
|
||||
},
|
||||
{ code: "var x = Object(42);", options: [{ capIsNewExceptions: ["Foo"] }] },
|
||||
|
||||
{
|
||||
code: "var x = Foo.Bar(42);",
|
||||
options: [{ capIsNewExceptions: ["Bar"] }],
|
||||
},
|
||||
{
|
||||
code: "var x = Foo.Bar(42);",
|
||||
options: [{ capIsNewExceptions: ["Foo.Bar"] }],
|
||||
},
|
||||
|
||||
{
|
||||
code: "var x = Foo.Bar(42);",
|
||||
options: [{ capIsNewExceptionPattern: "^Foo\\.." }],
|
||||
},
|
||||
{
|
||||
code: "var x = new foo.bar(42);",
|
||||
options: [{ newIsCapExceptions: ["bar"] }],
|
||||
},
|
||||
{
|
||||
code: "var x = new foo.bar(42);",
|
||||
options: [{ newIsCapExceptions: ["foo.bar"] }],
|
||||
},
|
||||
|
||||
{
|
||||
code: "var x = new foo.bar(42);",
|
||||
options: [{ newIsCapExceptionPattern: "^foo\\.." }],
|
||||
},
|
||||
{ code: "var x = new foo.bar(42);", options: [{ properties: false }] },
|
||||
{ code: "var x = Foo.bar(42);", options: [{ properties: false }] },
|
||||
{
|
||||
code: "var x = foo.Bar(42);",
|
||||
options: [{ capIsNew: false, properties: false }],
|
||||
},
|
||||
|
||||
// Babel-specific test cases.
|
||||
{ code: "@MyDecorator(123) class MyClass{}", parser: "babel-eslint" },
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: "var x = new c();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A constructor name should not start with a lowercase letter.",
|
||||
type: "NewExpression",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var x = new φ;",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A constructor name should not start with a lowercase letter.",
|
||||
type: "NewExpression",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var x = new a.b.c;",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A constructor name should not start with a lowercase letter.",
|
||||
type: "NewExpression",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var x = new a.b['c'];",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A constructor name should not start with a lowercase letter.",
|
||||
type: "NewExpression",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var b = Foo();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A function with a name starting with an uppercase letter should only be used as a constructor.",
|
||||
type: "CallExpression",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var b = a.Foo();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A function with a name starting with an uppercase letter should only be used as a constructor.",
|
||||
type: "CallExpression",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var b = a['Foo']();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A function with a name starting with an uppercase letter should only be used as a constructor.",
|
||||
type: "CallExpression",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var b = a.Date.UTC();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A function with a name starting with an uppercase letter should only be used as a constructor.",
|
||||
type: "CallExpression",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var b = UTC();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A function with a name starting with an uppercase letter should only be used as a constructor.",
|
||||
type: "CallExpression",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var a = B.C();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A function with a name starting with an uppercase letter should only be used as a constructor.",
|
||||
type: "CallExpression",
|
||||
line: 1,
|
||||
column: 11,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var a = B\n.C();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A function with a name starting with an uppercase letter should only be used as a constructor.",
|
||||
type: "CallExpression",
|
||||
line: 2,
|
||||
column: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var a = new B.c();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A constructor name should not start with a lowercase letter.",
|
||||
type: "NewExpression",
|
||||
line: 1,
|
||||
column: 15,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var a = new B.\nc();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A constructor name should not start with a lowercase letter.",
|
||||
type: "NewExpression",
|
||||
line: 2,
|
||||
column: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var a = new c();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"A constructor name should not start with a lowercase letter.",
|
||||
type: "NewExpression",
|
||||
line: 1,
|
||||
column: 13,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
code: "var x = Foo.Bar(42);",
|
||||
options: [{ capIsNewExceptions: ["Foo"] }],
|
||||
errors: [
|
||||
{
|
||||
type: "CallExpression",
|
||||
message:
|
||||
"A function with a name starting with an uppercase letter should only be used as a constructor.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var x = Bar.Foo(42);",
|
||||
|
||||
options: [{ capIsNewExceptionPattern: "^Foo\\.." }],
|
||||
errors: [
|
||||
{
|
||||
type: "CallExpression",
|
||||
message:
|
||||
"A function with a name starting with an uppercase letter should only be used as a constructor.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var x = new foo.bar(42);",
|
||||
options: [{ newIsCapExceptions: ["foo"] }],
|
||||
errors: [
|
||||
{
|
||||
type: "NewExpression",
|
||||
message:
|
||||
"A constructor name should not start with a lowercase letter.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var x = new bar.foo(42);",
|
||||
|
||||
options: [{ newIsCapExceptionPattern: "^foo\\.." }],
|
||||
errors: [
|
||||
{
|
||||
type: "NewExpression",
|
||||
message:
|
||||
"A constructor name should not start with a lowercase letter.",
|
||||
},
|
||||
],
|
||||
code: "@MyDecorator(123) class MyClass{}",
|
||||
},
|
||||
],
|
||||
invalid: [],
|
||||
});
|
||||
|
||||
@@ -1,21 +1,6 @@
|
||||
/**
|
||||
* @fileoverview Tests for no-invalid-this rule.
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const cloneDeep = require("lodash.clonedeep");
|
||||
const rule = require("../../src/rules/no-invalid-this"),
|
||||
RuleTester = require("../helpers/RuleTester");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import rule from "../../src/rules/no-invalid-this";
|
||||
import RuleTester from "../helpers/RuleTester";
|
||||
|
||||
/**
|
||||
* A constant value for non strict mode environment.
|
||||
@@ -98,558 +83,7 @@ const errors = [
|
||||
];
|
||||
|
||||
const patterns = [
|
||||
// Global.
|
||||
{
|
||||
code: "console.log(this); z(x => console.log(x, this));",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code: "console.log(this); z(x => console.log(x, this));",
|
||||
parserOptions: {
|
||||
ecmaVersion: 6,
|
||||
ecmaFeatures: { globalReturn: true },
|
||||
},
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
|
||||
// IIFE.
|
||||
{
|
||||
code:
|
||||
"(function() { console.log(this); z(x => console.log(x, this)); })();",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
|
||||
// Just functions.
|
||||
{
|
||||
code: "function foo() { console.log(this); z(x => console.log(x, this)); }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
'function foo() { "use strict"; console.log(this); z(x => console.log(x, this)); }',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [],
|
||||
invalid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"return function() { console.log(this); z(x => console.log(x, this)); };",
|
||||
parserOptions: {
|
||||
ecmaVersion: 6,
|
||||
ecmaFeatures: { globalReturn: true },
|
||||
},
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT], // modules cannot return on global.
|
||||
},
|
||||
{
|
||||
code:
|
||||
"var foo = (function() { console.log(this); z(x => console.log(x, this)); }).bar(obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
|
||||
// Functions in methods.
|
||||
{
|
||||
code:
|
||||
"var obj = {foo: function() { function foo() { console.log(this); z(x => console.log(x, this)); } foo(); }};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"var obj = {foo() { function foo() { console.log(this); z(x => console.log(x, this)); } foo(); }};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"var obj = {foo: function() { return function() { console.log(this); z(x => console.log(x, this)); }; }};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
'var obj = {foo: function() { "use strict"; return function() { console.log(this); z(x => console.log(x, this)); }; }};',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [],
|
||||
invalid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"obj.foo = function() { return function() { console.log(this); z(x => console.log(x, this)); }; };",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
'obj.foo = function() { "use strict"; return function() { console.log(this); z(x => console.log(x, this)); }; };',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [],
|
||||
invalid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"class A { foo() { return function() { console.log(this); z(x => console.log(x, this)); }; } }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [],
|
||||
invalid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
|
||||
// Class Static methods.
|
||||
{
|
||||
code:
|
||||
"class A {static foo() { console.log(this); z(x => console.log(x, this)); }};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
// Constructors.
|
||||
{
|
||||
code: "function Foo() { console.log(this); z(x => console.log(x, this)); }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"var Foo = function Foo() { console.log(this); z(x => console.log(x, this)); };",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"class A {constructor() { console.log(this); z(x => console.log(x, this)); }};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
// On a property.
|
||||
{
|
||||
code:
|
||||
"var obj = {foo: function() { console.log(this); z(x => console.log(x, this)); }};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"var obj = {foo() { console.log(this); z(x => console.log(x, this)); }};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"var obj = {foo: foo || function() { console.log(this); z(x => console.log(x, this)); }};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"var obj = {foo: hasNative ? foo : function() { console.log(this); z(x => console.log(x, this)); }};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"var obj = {foo: (function() { return function() { console.log(this); z(x => console.log(x, this)); }; })()};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
'Object.defineProperty(obj, "foo", {value: function() { console.log(this); z(x => console.log(x, this)); }})',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"Object.defineProperties(obj, {foo: {value: function() { console.log(this); z(x => console.log(x, this)); }}})",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
// Assigns to a property.
|
||||
{
|
||||
code:
|
||||
"obj.foo = function() { console.log(this); z(x => console.log(x, this)); };",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"obj.foo = foo || function() { console.log(this); z(x => console.log(x, this)); };",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"obj.foo = foo ? bar : function() { console.log(this); z(x => console.log(x, this)); };",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"obj.foo = (function() { return function() { console.log(this); z(x => console.log(x, this)); }; })();",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
// Class Instance Methods.
|
||||
{
|
||||
code:
|
||||
"class A {foo() { console.log(this); z(x => console.log(x, this)); }};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
// Bind/Call/Apply
|
||||
{
|
||||
code:
|
||||
"var foo = function() { console.log(this); z(x => console.log(x, this)); }.bind(obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"var foo = function() { console.log(this); z(x => console.log(x, this)); }.bind(null);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"(function() { console.log(this); z(x => console.log(x, this)); }).call(obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"(function() { console.log(this); z(x => console.log(x, this)); }).call(undefined);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"(function() { console.log(this); z(x => console.log(x, this)); }).apply(obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"(function() { console.log(this); z(x => console.log(x, this)); }).apply(void 0);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"Reflect.apply(function() { console.log(this); z(x => console.log(x, this)); }, obj, []);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
// Array methods.
|
||||
{
|
||||
code:
|
||||
"Array.from([], function() { console.log(this); z(x => console.log(x, this)); });",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.every(function() { console.log(this); z(x => console.log(x, this)); });",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.filter(function() { console.log(this); z(x => console.log(x, this)); });",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.find(function() { console.log(this); z(x => console.log(x, this)); });",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.findIndex(function() { console.log(this); z(x => console.log(x, this)); });",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.forEach(function() { console.log(this); z(x => console.log(x, this)); });",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.map(function() { console.log(this); z(x => console.log(x, this)); });",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.some(function() { console.log(this); z(x => console.log(x, this)); });",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"Array.from([], function() { console.log(this); z(x => console.log(x, this)); }, obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.every(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.filter(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.find(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.findIndex(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.forEach(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.map(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.some(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo.forEach(function() { console.log(this); z(x => console.log(x, this)); }, null);",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
|
||||
// @this tag.
|
||||
{
|
||||
code:
|
||||
"/** @this Obj */ function foo() { console.log(this); z(x => console.log(x, this)); }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"/**\n * @returns {void}\n * @this Obj\n */\nfunction foo() { console.log(this); z(x => console.log(x, this)); }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"/** @returns {void} */ function foo() { console.log(this); z(x => console.log(x, this)); }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"/** @this Obj */ foo(function() { console.log(this); z(x => console.log(x, this)); });",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"foo(/* @this Obj */ function() { console.log(this); z(x => console.log(x, this)); });",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
// https://github.com/eslint/eslint/issues/3254
|
||||
{
|
||||
code: "function foo() { console.log(this); z(x => console.log(x, this)); }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
|
||||
// https://github.com/eslint/eslint/issues/3287
|
||||
{
|
||||
code:
|
||||
"function foo() { /** @this Obj*/ return function bar() { console.log(this); z(x => console.log(x, this)); }; }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
// https://github.com/eslint/eslint/issues/6824
|
||||
{
|
||||
code:
|
||||
"var Ctor = function() { console.log(this); z(x => console.log(x, this)); }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"var func = function() { console.log(this); z(x => console.log(x, this)); }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"Ctor = function() { console.log(this); z(x => console.log(x, this)); }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"func = function() { console.log(this); z(x => console.log(x, this)); }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"function foo(Ctor = function() { console.log(this); z(x => console.log(x, this)); }) {}",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"function foo(func = function() { console.log(this); z(x => console.log(x, this)); }) {}",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"[obj.method = function() { console.log(this); z(x => console.log(x, this)); }] = a",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
{
|
||||
code:
|
||||
"[func = function() { console.log(this); z(x => console.log(x, this)); }] = a",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors,
|
||||
valid: [NORMAL],
|
||||
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
},
|
||||
|
||||
// babel/no-invalid-this
|
||||
|
||||
// Class Instance Properties.
|
||||
// Class private fields
|
||||
{
|
||||
code: "class A {a = this.b;};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
@@ -664,7 +98,7 @@ const patterns = [
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
// Class Private Instance Properties.
|
||||
// Class Private methods
|
||||
{
|
||||
code: "class A {#a = this.b;};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
@@ -681,8 +115,7 @@ const patterns = [
|
||||
];
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run("no-invalid-this", rule, {
|
||||
ruleTester.run("@babel/no-invalid-this", rule, {
|
||||
valid: extractPatterns(patterns, "valid"),
|
||||
invalid: extractPatterns(patterns, "invalid"),
|
||||
});
|
||||
|
||||
@@ -1,85 +1,9 @@
|
||||
/**
|
||||
* @fileoverview Tests for no-unused-expressions rule.
|
||||
* @author Michael Ficarra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const rule = require("../../src/rules/no-unused-expressions"),
|
||||
RuleTester = require("../helpers/RuleTester");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Tests
|
||||
//------------------------------------------------------------------------------
|
||||
import rule from "../../src/rules/no-unused-expressions";
|
||||
import RuleTester from "../helpers/RuleTester";
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run("no-unused-expressions", rule, {
|
||||
ruleTester.run("@babel/no-unused-expressions", rule, {
|
||||
valid: [
|
||||
// Original test cases.
|
||||
"function f(){}",
|
||||
"a = b",
|
||||
"new a",
|
||||
"{}",
|
||||
"f(); g()",
|
||||
"i++",
|
||||
"a()",
|
||||
{ code: "a && a()", options: [{ allowShortCircuit: true }] },
|
||||
{ code: "a() || (b = c)", options: [{ allowShortCircuit: true }] },
|
||||
{ code: "a ? b() : c()", options: [{ allowTernary: true }] },
|
||||
{
|
||||
code: "a ? b() || (c = d) : e()",
|
||||
options: [{ allowShortCircuit: true, allowTernary: true }],
|
||||
},
|
||||
"delete foo.bar",
|
||||
"void new C",
|
||||
'"use strict";',
|
||||
'"directive one"; "directive two"; f();',
|
||||
'function foo() {"use strict"; return true; }',
|
||||
{
|
||||
code: 'var foo = () => {"use strict"; return true; }',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
'function foo() {"directive one"; "directive two"; f(); }',
|
||||
'function foo() { var foo = "use strict"; return true; }',
|
||||
{
|
||||
code: "function* foo(){ yield 0; }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "async function foo() { await 5; }",
|
||||
parserOptions: { ecmaVersion: 8 },
|
||||
},
|
||||
{
|
||||
code: "async function foo() { await foo.bar; }",
|
||||
parserOptions: { ecmaVersion: 8 },
|
||||
},
|
||||
{
|
||||
code: "async function foo() { bar && await baz; }",
|
||||
options: [{ allowShortCircuit: true }],
|
||||
parserOptions: { ecmaVersion: 8 },
|
||||
},
|
||||
{
|
||||
code: "async function foo() { foo ? await bar : await baz; }",
|
||||
options: [{ allowTernary: true }],
|
||||
parserOptions: { ecmaVersion: 8 },
|
||||
},
|
||||
{
|
||||
code: "tag`tagged template literal`",
|
||||
options: [{ allowTaggedTemplates: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "shouldNotBeAffectedByAllowTemplateTagsOption()",
|
||||
options: [{ allowTaggedTemplates: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
|
||||
// Babel-specific test cases.
|
||||
"let a = do { if (foo) { foo.bar; } }",
|
||||
"let a = do { foo; }",
|
||||
"let a = do { let b = 2; foo; }",
|
||||
@@ -89,283 +13,6 @@ ruleTester.run("no-unused-expressions", rule, {
|
||||
"foo.bar?.();",
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: "0",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "f(), 0",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "{0}",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "[]",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a && b();",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a() || false",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a || (b = c)",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a ? b() || (c = d) : e",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "`untagged template literal`",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "tag`tagged template literal`",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a && b()",
|
||||
options: [{ allowTernary: true }],
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a ? b() : c()",
|
||||
options: [{ allowShortCircuit: true }],
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a || b",
|
||||
options: [{ allowShortCircuit: true }],
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a() && b",
|
||||
options: [{ allowShortCircuit: true }],
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a ? b : 0",
|
||||
options: [{ allowTernary: true }],
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a ? b : c()",
|
||||
options: [{ allowTernary: true }],
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "foo.bar;",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "!a",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "+a",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: '"directive one"; f(); "directive two";',
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'function foo() {"directive one"; f(); "directive two"; }',
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'if (0) { "not a directive"; f(); }',
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'function foo() { var foo = true; "use strict"; }',
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'var foo = () => { var foo = true; "use strict"; }',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "`untagged template literal`",
|
||||
options: [{ allowTaggedTemplates: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "`untagged template literal`",
|
||||
options: [{ allowTaggedTemplates: false }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "tag`tagged template literal`",
|
||||
options: [{ allowTaggedTemplates: false }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
],
|
||||
},
|
||||
|
||||
// Babel-specific test cases.
|
||||
{
|
||||
code: "let a = do { foo; let b = 2; }",
|
||||
errors: [
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,481 +0,0 @@
|
||||
var rule = require("../../src/rules/quotes"),
|
||||
RuleTester = require("../helpers/RuleTester");
|
||||
|
||||
var ruleTester = new RuleTester();
|
||||
ruleTester.run("babel/quotes", rule, {
|
||||
valid: [
|
||||
'var foo = "bar";',
|
||||
{ code: "var foo = 'bar';", options: ["single"] },
|
||||
{ code: 'var foo = "bar";', options: ["double"] },
|
||||
{ code: "var foo = 1;", options: ["single"] },
|
||||
{ code: "var foo = 1;", options: ["double"] },
|
||||
{ code: 'var foo = "\'";', options: ["single", { avoidEscape: true }] },
|
||||
{ code: "var foo = '\"';", options: ["double", { avoidEscape: true }] },
|
||||
{
|
||||
code: "var foo = <div>Hello world</div>;",
|
||||
options: ["single"],
|
||||
parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } },
|
||||
},
|
||||
{
|
||||
code: 'var foo = <div id="foo"></div>;',
|
||||
options: ["single"],
|
||||
parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } },
|
||||
},
|
||||
{
|
||||
code: "var foo = <div>Hello world</div>;",
|
||||
options: ["double"],
|
||||
parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } },
|
||||
},
|
||||
{
|
||||
code: "var foo = <div>Hello world</div>;",
|
||||
options: ["double", { avoidEscape: true }],
|
||||
parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } },
|
||||
},
|
||||
{
|
||||
code: "var foo = `bar`;",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = `bar 'baz'`;",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: 'var foo = `bar "baz"`;',
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{ code: "var foo = 1;", options: ["backtick"] },
|
||||
{
|
||||
code: 'var foo = "a string containing `backtick` quotes";',
|
||||
options: ["backtick", { avoidEscape: true }],
|
||||
},
|
||||
{
|
||||
code: 'var foo = <div id="foo"></div>;',
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } },
|
||||
},
|
||||
{
|
||||
code: "var foo = <div>Hello world</div>;",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } },
|
||||
},
|
||||
|
||||
// Backticks are only okay if they have substitutions, contain a line break, or are tagged
|
||||
{
|
||||
code: "var foo = `back\ntick`;",
|
||||
options: ["single"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = `back\rtick`;",
|
||||
options: ["single"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = `back\u2028tick`;",
|
||||
options: ["single"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = `back\u2029tick`;",
|
||||
options: ["single"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = `back\\\\\ntick`;", // 2 backslashes followed by a newline
|
||||
options: ["single"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = `back\\\\\\\\\ntick`;",
|
||||
options: ["single"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = `\n`;",
|
||||
options: ["single"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = `back${x}tick`;",
|
||||
options: ["double"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = tag`backtick`;",
|
||||
options: ["double"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
|
||||
// Backticks are also okay if allowTemplateLiterals
|
||||
{
|
||||
code: "var foo = `bar 'foo' baz` + 'bar';",
|
||||
options: ["single", { allowTemplateLiterals: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = `bar 'foo' baz` + \"bar\";",
|
||||
options: ["double", { allowTemplateLiterals: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "var foo = `bar 'foo' baz` + `bar`;",
|
||||
options: ["backtick", { allowTemplateLiterals: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
|
||||
// `backtick` should not warn the directive prologues.
|
||||
{
|
||||
code: '"use strict"; var foo = `backtick`;',
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: '"use strict"; \'use strong\'; "use asm"; var foo = `backtick`;',
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code:
|
||||
'function foo() { "use strict"; "use strong"; "use asm"; var foo = `backtick`; }',
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code:
|
||||
"(function() { 'use strict'; 'use strong'; 'use asm'; var foo = `backtick`; })();",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code:
|
||||
'(() => { "use strict"; "use strong"; "use asm"; var foo = `backtick`; })();',
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
|
||||
// `backtick` should not warn import/export sources.
|
||||
{
|
||||
code: "import \"a\"; import 'b';",
|
||||
options: ["backtick"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "import a from \"a\"; import b from 'b';",
|
||||
options: ["backtick"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export * from \"a\"; export * from 'b';",
|
||||
options: ["backtick"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
|
||||
// `backtick` should not warn property/method names (not computed).
|
||||
{
|
||||
code: "var obj = {\"key0\": 0, 'key1': 1};",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "class Foo { 'bar'(){} }",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "class Foo { static ''(){} }",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
|
||||
// Babel
|
||||
"<>foo</>;",
|
||||
{ code: "<>foo</>;", options: ["single"] },
|
||||
{ code: "<>foo</>;", options: ["double"] },
|
||||
"<><div /><div /></>;",
|
||||
{ code: "<><div /><div /></>;", options: ["single"] },
|
||||
{ code: "<><div /><div /></>;", options: ["double"] },
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: "var foo = 'bar';",
|
||||
output: 'var foo = "bar";',
|
||||
errors: [{ message: "Strings must use doublequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: 'var foo = "bar";',
|
||||
output: "var foo = 'bar';",
|
||||
options: ["single"],
|
||||
errors: [{ message: "Strings must use singlequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: "var foo = `bar`;",
|
||||
output: "var foo = 'bar';",
|
||||
options: ["single"],
|
||||
parserOptions: {
|
||||
ecmaVersion: 6,
|
||||
},
|
||||
errors: [
|
||||
{ message: "Strings must use singlequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var foo = 'don\\'t';",
|
||||
output: 'var foo = "don\'t";',
|
||||
errors: [{ message: "Strings must use doublequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: 'var msg = "Plugin \'" + name + "\' not found"',
|
||||
output: "var msg = 'Plugin \\'' + name + '\\' not found'",
|
||||
options: ["single"],
|
||||
errors: [
|
||||
{
|
||||
message: "Strings must use singlequote.",
|
||||
type: "Literal",
|
||||
column: 11,
|
||||
},
|
||||
{
|
||||
message: "Strings must use singlequote.",
|
||||
type: "Literal",
|
||||
column: 31,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var foo = 'bar';",
|
||||
output: 'var foo = "bar";',
|
||||
options: ["double"],
|
||||
errors: [{ message: "Strings must use doublequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: "var foo = `bar`;",
|
||||
output: 'var foo = "bar";',
|
||||
options: ["double"],
|
||||
parserOptions: {
|
||||
ecmaVersion: 6,
|
||||
},
|
||||
errors: [
|
||||
{ message: "Strings must use doublequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: 'var foo = "bar";',
|
||||
output: "var foo = 'bar';",
|
||||
options: ["single", { avoidEscape: true }],
|
||||
errors: [{ message: "Strings must use singlequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: "var foo = 'bar';",
|
||||
output: 'var foo = "bar";',
|
||||
options: ["double", { avoidEscape: true }],
|
||||
errors: [{ message: "Strings must use doublequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: "var foo = '\\\\';",
|
||||
output: 'var foo = "\\\\";',
|
||||
options: ["double", { avoidEscape: true }],
|
||||
errors: [{ message: "Strings must use doublequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: 'var foo = "bar";',
|
||||
output: "var foo = 'bar';",
|
||||
options: ["single", { allowTemplateLiterals: true }],
|
||||
errors: [{ message: "Strings must use singlequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: "var foo = 'bar';",
|
||||
output: 'var foo = "bar";',
|
||||
options: ["double", { allowTemplateLiterals: true }],
|
||||
errors: [{ message: "Strings must use doublequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: "var foo = 'bar';",
|
||||
output: "var foo = `bar`;",
|
||||
options: ["backtick"],
|
||||
errors: [{ message: "Strings must use backtick.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: "var foo = 'b${x}a$r';",
|
||||
output: "var foo = `b\\${x}a$r`;",
|
||||
options: ["backtick"],
|
||||
errors: [{ message: "Strings must use backtick.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: 'var foo = "bar";',
|
||||
output: "var foo = `bar`;",
|
||||
options: ["backtick"],
|
||||
errors: [{ message: "Strings must use backtick.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: 'var foo = "bar";',
|
||||
output: "var foo = `bar`;",
|
||||
options: ["backtick", { avoidEscape: true }],
|
||||
errors: [{ message: "Strings must use backtick.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: "var foo = 'bar';",
|
||||
output: "var foo = `bar`;",
|
||||
options: ["backtick", { avoidEscape: true }],
|
||||
errors: [{ message: "Strings must use backtick.", type: "Literal" }],
|
||||
},
|
||||
|
||||
// "use strict" is *not* a directive prologue in these statements so is subject to the rule
|
||||
{
|
||||
code: 'var foo = `backtick`; "use strict";',
|
||||
output: "var foo = `backtick`; `use strict`;",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [{ message: "Strings must use backtick.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: '{ "use strict"; var foo = `backtick`; }',
|
||||
output: "{ `use strict`; var foo = `backtick`; }",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [{ message: "Strings must use backtick.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: 'if (1) { "use strict"; var foo = `backtick`; }',
|
||||
output: "if (1) { `use strict`; var foo = `backtick`; }",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [{ message: "Strings must use backtick.", type: "Literal" }],
|
||||
},
|
||||
|
||||
// `backtick` should warn computed property names.
|
||||
{
|
||||
code: "var obj = {[\"key0\"]: 0, ['key1']: 1};",
|
||||
output: "var obj = {[`key0`]: 0, [`key1`]: 1};",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use backtick.", type: "Literal" },
|
||||
{ message: "Strings must use backtick.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "class Foo { ['a'](){} static ['b'](){} }",
|
||||
output: "class Foo { [`a`](){} static [`b`](){} }",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use backtick.", type: "Literal" },
|
||||
{ message: "Strings must use backtick.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
|
||||
// https://github.com/eslint/eslint/issues/7084
|
||||
{
|
||||
code: '<div blah={"blah"} />',
|
||||
output: "<div blah={'blah'} />",
|
||||
options: ["single"],
|
||||
parserOptions: { ecmaFeatures: { jsx: true } },
|
||||
errors: [{ message: "Strings must use singlequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: "<div blah={'blah'} />",
|
||||
output: '<div blah={"blah"} />',
|
||||
options: ["double"],
|
||||
parserOptions: { ecmaFeatures: { jsx: true } },
|
||||
errors: [{ message: "Strings must use doublequote.", type: "Literal" }],
|
||||
},
|
||||
{
|
||||
code: "<div blah={'blah'} />",
|
||||
output: "<div blah={`blah`} />",
|
||||
options: ["backtick"],
|
||||
parserOptions: { ecmaFeatures: { jsx: true } },
|
||||
errors: [{ message: "Strings must use backtick.", type: "Literal" }],
|
||||
},
|
||||
|
||||
// https://github.com/eslint/eslint/issues/7610
|
||||
{
|
||||
code: "`use strict`;",
|
||||
output: null,
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use doublequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "function foo() { `use strict`; foo(); }",
|
||||
output: null,
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use doublequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "foo = function() { `use strict`; foo(); }",
|
||||
output: null,
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use doublequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "() => { `use strict`; foo(); }",
|
||||
output: null,
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use doublequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "() => { foo(); `use strict`; }",
|
||||
output: '() => { foo(); "use strict"; }',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use doublequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "foo(); `use strict`;",
|
||||
output: 'foo(); "use strict";',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use doublequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
|
||||
// https://github.com/eslint/eslint/issues/7646
|
||||
{
|
||||
code: "var foo = `foo\\nbar`;",
|
||||
output: 'var foo = "foo\\nbar";',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use doublequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var foo = `foo\\\nbar`;", // 1 backslash followed by a newline
|
||||
output: 'var foo = "foo\\\nbar";',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use doublequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var foo = `foo\\\\\\\nbar`;", // 3 backslashes followed by a newline
|
||||
output: 'var foo = "foo\\\\\\\nbar";',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{ message: "Strings must use doublequote.", type: "TemplateLiteral" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "````",
|
||||
output: '""``',
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Strings must use doublequote.",
|
||||
type: "TemplateLiteral",
|
||||
line: 1,
|
||||
column: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -1,666 +1,23 @@
|
||||
/* eslnit-disable */
|
||||
/**
|
||||
* @fileoverview Tests for semi rule.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const rule = require("../../src/rules/semi"),
|
||||
RuleTester = require("../helpers/RuleTester");
|
||||
import rule from "../../src/rules/semi";
|
||||
import RuleTester from "../helpers/RuleTester";
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run("semi", rule, {
|
||||
valid: [
|
||||
"var x = 5;",
|
||||
"var x =5, y;",
|
||||
"foo();",
|
||||
"x = foo();",
|
||||
'setTimeout(function() {foo = "bar"; });',
|
||||
'setTimeout(function() {foo = "bar";});',
|
||||
"for (var a in b){}",
|
||||
"for (var i;;){}",
|
||||
"if (true) {}\n;[global, extended].forEach(function(){});",
|
||||
"throw new Error('foo');",
|
||||
{ code: "throw new Error('foo')", options: ["never"] },
|
||||
{ code: "var x = 5", options: ["never"] },
|
||||
{ code: "var x =5, y", options: ["never"] },
|
||||
{ code: "foo()", options: ["never"] },
|
||||
{ code: "debugger", options: ["never"] },
|
||||
{ code: "for (var a in b){}", options: ["never"] },
|
||||
{ code: "for (var i;;){}", options: ["never"] },
|
||||
{ code: "x = foo()", options: ["never"] },
|
||||
{
|
||||
code: "if (true) {}\n;[global, extended].forEach(function(){})",
|
||||
options: ["never"],
|
||||
},
|
||||
{ code: "(function bar() {})\n;(function foo(){})", options: ["never"] },
|
||||
{ code: ";/foo/.test('bar')", options: ["never"] },
|
||||
{ code: ";+5", options: ["never"] },
|
||||
{ code: ";-foo()", options: ["never"] },
|
||||
{ code: "a++\nb++", options: ["never"] },
|
||||
{ code: "a++; b++", options: ["never"] },
|
||||
{
|
||||
code: "for (let thing of {}) {\n console.log(thing);\n}",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{ code: "do{}while(true)", options: ["never"] },
|
||||
{ code: "do{}while(true);", options: ["always"] },
|
||||
|
||||
{
|
||||
code: "if (foo) { bar() }",
|
||||
options: ["always", { omitLastInOneLineBlock: true }],
|
||||
},
|
||||
{
|
||||
code: "if (foo) { bar(); baz() }",
|
||||
options: ["always", { omitLastInOneLineBlock: true }],
|
||||
},
|
||||
|
||||
// method definitions don't have a semicolon.
|
||||
{ code: "class A { a() {} b() {} }", parserOptions: { ecmaVersion: 6 } },
|
||||
{
|
||||
code: "var A = class { a() {} b() {} };",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
|
||||
{
|
||||
code: "import theDefault, { named1, named2 } from 'src/mylib';",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "import theDefault, { named1, named2 } from 'src/mylib'",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
|
||||
// exports, "always"
|
||||
{ code: "export * from 'foo';", parserOptions: { sourceType: "module" } },
|
||||
{
|
||||
code: "export { foo } from 'foo';",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{ code: "export { foo };", parserOptions: { sourceType: "module" } },
|
||||
{ code: "export var foo;", parserOptions: { sourceType: "module" } },
|
||||
{
|
||||
code: "export function foo () { }",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export function* foo () { }",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{ code: "export class Foo { }", parserOptions: { sourceType: "module" } },
|
||||
{ code: "export let foo;", parserOptions: { sourceType: "module" } },
|
||||
{ code: "export const FOO = 42;", parserOptions: { sourceType: "module" } },
|
||||
{
|
||||
code: "export default function() { }",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default function* () { }",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default class { }",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default foo || bar;",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default (foo) => foo.bar();",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default foo = 42;",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default foo += 42;",
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
|
||||
// exports, "never"
|
||||
{
|
||||
code: "export * from 'foo'",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export { foo } from 'foo'",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export { foo }",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export var foo",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export function foo () { }",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export function* foo () { }",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export class Foo { }",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export let foo",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export const FOO = 42",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default function() { }",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default function* () { }",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default class { }",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default foo || bar",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default (foo) => foo.bar()",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default foo = 42",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{
|
||||
code: "export default foo += 42",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
},
|
||||
{ code: "++\nfoo;", options: ["always"] },
|
||||
{ code: "var a = b;\n+ c", options: ["never"] },
|
||||
|
||||
// https://github.com/eslint/eslint/issues/7782
|
||||
{ code: "var a = b;\n/foo/.test(c)", options: ["never"] },
|
||||
{
|
||||
code: "var a = b;\n`foo`",
|
||||
options: ["never"],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
|
||||
// babel
|
||||
"class Foo { bar = 'example'; }",
|
||||
"class Foo { static bar = 'example'; }",
|
||||
{
|
||||
code:
|
||||
"async function foo() { for await (let thing of {}) { console.log(thing); } }",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "class Foo { bar = () => {}; }",
|
||||
options: ["always", { omitLastInOneLineBlock: true }],
|
||||
},
|
||||
|
||||
// babel, "never"
|
||||
// never
|
||||
{ code: "class Foo { bar = 'example' }", options: ["never"] },
|
||||
{ code: "class Foo { static bar = 'example' }", options: ["never"] },
|
||||
{ code: "class Foo { bar = () => {} }", options: ["never"] },
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: "import * as utils from './utils'",
|
||||
output: "import * as utils from './utils';",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{
|
||||
message: "Missing semicolon.",
|
||||
type: "ImportDeclaration",
|
||||
column: 33,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "import { square, diag } from 'lib'",
|
||||
output: "import { square, diag } from 'lib';",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Missing semicolon.", type: "ImportDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "import { default as foo } from 'lib'",
|
||||
output: "import { default as foo } from 'lib';",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Missing semicolon.", type: "ImportDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "import 'src/mylib'",
|
||||
output: "import 'src/mylib';",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Missing semicolon.", type: "ImportDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "import theDefault, { named1, named2 } from 'src/mylib'",
|
||||
output: "import theDefault, { named1, named2 } from 'src/mylib';",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Missing semicolon.", type: "ImportDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "function foo() { return [] }",
|
||||
output: "function foo() { return []; }",
|
||||
errors: [{ message: "Missing semicolon.", type: "ReturnStatement" }],
|
||||
},
|
||||
{
|
||||
code: "while(true) { break }",
|
||||
output: "while(true) { break; }",
|
||||
errors: [{ message: "Missing semicolon.", type: "BreakStatement" }],
|
||||
},
|
||||
{
|
||||
code: "while(true) { continue }",
|
||||
output: "while(true) { continue; }",
|
||||
errors: [{ message: "Missing semicolon.", type: "ContinueStatement" }],
|
||||
},
|
||||
{
|
||||
code: "let x = 5",
|
||||
output: "let x = 5;",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "var x = 5",
|
||||
output: "var x = 5;",
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "var x = 5, y",
|
||||
output: "var x = 5, y;",
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "debugger",
|
||||
output: "debugger;",
|
||||
errors: [{ message: "Missing semicolon.", type: "DebuggerStatement" }],
|
||||
},
|
||||
{
|
||||
code: "foo()",
|
||||
output: "foo();",
|
||||
errors: [{ message: "Missing semicolon.", type: "ExpressionStatement" }],
|
||||
},
|
||||
{
|
||||
code: "var x = 5, y",
|
||||
output: "var x = 5, y;",
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "for (var a in b) var i ",
|
||||
output: "for (var a in b) var i; ",
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "for (;;){var i}",
|
||||
output: "for (;;){var i;}",
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "for (;;) var i ",
|
||||
output: "for (;;) var i; ",
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "for (var j;;) {var i}",
|
||||
output: "for (var j;;) {var i;}",
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "var foo = {\n bar: baz\n}",
|
||||
output: "var foo = {\n bar: baz\n};",
|
||||
errors: [
|
||||
{ message: "Missing semicolon.", type: "VariableDeclaration", line: 3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "var foo\nvar bar;",
|
||||
output: "var foo;\nvar bar;",
|
||||
errors: [
|
||||
{ message: "Missing semicolon.", type: "VariableDeclaration", line: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "throw new Error('foo')",
|
||||
output: "throw new Error('foo');",
|
||||
errors: [
|
||||
{ message: "Missing semicolon.", type: "ThrowStatement", line: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "do{}while(true)",
|
||||
output: "do{}while(true);",
|
||||
errors: [
|
||||
{ message: "Missing semicolon.", type: "DoWhileStatement", line: 1 },
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
code: "throw new Error('foo');",
|
||||
output: "throw new Error('foo')",
|
||||
options: ["never"],
|
||||
errors: [
|
||||
{ message: "Extra semicolon.", type: "ThrowStatement", column: 23 },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "function foo() { return []; }",
|
||||
output: "function foo() { return [] }",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "ReturnStatement" }],
|
||||
},
|
||||
{
|
||||
code: "while(true) { break; }",
|
||||
output: "while(true) { break }",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "BreakStatement" }],
|
||||
},
|
||||
{
|
||||
code: "while(true) { continue; }",
|
||||
output: "while(true) { continue }",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "ContinueStatement" }],
|
||||
},
|
||||
{
|
||||
code: "let x = 5;",
|
||||
output: "let x = 5",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "var x = 5;",
|
||||
output: "var x = 5",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "var x = 5, y;",
|
||||
output: "var x = 5, y",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "debugger;",
|
||||
output: "debugger",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "DebuggerStatement" }],
|
||||
},
|
||||
{
|
||||
code: "foo();",
|
||||
output: "foo()",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "ExpressionStatement" }],
|
||||
},
|
||||
{
|
||||
code: "var x = 5, y;",
|
||||
output: "var x = 5, y",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "for (var a in b) var i; ",
|
||||
output: "for (var a in b) var i ",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "for (;;){var i;}",
|
||||
output: "for (;;){var i}",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "for (;;) var i; ",
|
||||
output: "for (;;) var i ",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "for (var j;;) {var i;}",
|
||||
output: "for (var j;;) {var i}",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "var foo = {\n bar: baz\n};",
|
||||
output: "var foo = {\n bar: baz\n}",
|
||||
options: ["never"],
|
||||
errors: [
|
||||
{ message: "Extra semicolon.", type: "VariableDeclaration", line: 3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "import theDefault, { named1, named2 } from 'src/mylib';",
|
||||
output: "import theDefault, { named1, named2 } from 'src/mylib'",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Extra semicolon.", type: "ImportDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "do{}while(true);",
|
||||
output: "do{}while(true)",
|
||||
options: ["never"],
|
||||
errors: [
|
||||
{ message: "Extra semicolon.", type: "DoWhileStatement", line: 1 },
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
code: "if (foo) { bar()\n }",
|
||||
options: ["always", { omitLastInOneLineBlock: true }],
|
||||
errors: [{ message: "Missing semicolon." }],
|
||||
},
|
||||
{
|
||||
code: "if (foo) {\n bar() }",
|
||||
options: ["always", { omitLastInOneLineBlock: true }],
|
||||
errors: [{ message: "Missing semicolon." }],
|
||||
},
|
||||
{
|
||||
code: "if (foo) {\n bar(); baz() }",
|
||||
options: ["always", { omitLastInOneLineBlock: true }],
|
||||
errors: [{ message: "Missing semicolon." }],
|
||||
},
|
||||
{
|
||||
code: "if (foo) { bar(); }",
|
||||
options: ["always", { omitLastInOneLineBlock: true }],
|
||||
errors: [{ message: "Extra semicolon." }],
|
||||
},
|
||||
|
||||
// exports, "always"
|
||||
{
|
||||
code: "export * from 'foo'",
|
||||
output: "export * from 'foo';",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Missing semicolon.", type: "ExportAllDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "export { foo } from 'foo'",
|
||||
output: "export { foo } from 'foo';",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{ message: "Missing semicolon.", type: "ExportNamedDeclaration" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "export { foo }",
|
||||
output: "export { foo };",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{ message: "Missing semicolon.", type: "ExportNamedDeclaration" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "export var foo",
|
||||
output: "export var foo;",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "export let foo",
|
||||
output: "export let foo;",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "export const FOO = 42",
|
||||
output: "export const FOO = 42;",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "export default foo || bar",
|
||||
output: "export default foo || bar;",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{ message: "Missing semicolon.", type: "ExportDefaultDeclaration" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "export default (foo) => foo.bar()",
|
||||
output: "export default (foo) => foo.bar();",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{ message: "Missing semicolon.", type: "ExportDefaultDeclaration" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "export default foo = 42",
|
||||
output: "export default foo = 42;",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{ message: "Missing semicolon.", type: "ExportDefaultDeclaration" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "export default foo += 42",
|
||||
output: "export default foo += 42;",
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{ message: "Missing semicolon.", type: "ExportDefaultDeclaration" },
|
||||
],
|
||||
},
|
||||
|
||||
// exports, "never"
|
||||
{
|
||||
code: "export * from 'foo';",
|
||||
output: "export * from 'foo'",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Extra semicolon.", type: "ExportAllDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "export { foo } from 'foo';",
|
||||
output: "export { foo } from 'foo'",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Extra semicolon.", type: "ExportNamedDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "export { foo };",
|
||||
output: "export { foo }",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Extra semicolon.", type: "ExportNamedDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "export var foo;",
|
||||
output: "export var foo",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "export let foo;",
|
||||
output: "export let foo",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "export const FOO = 42;",
|
||||
output: "export const FOO = 42",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
|
||||
},
|
||||
{
|
||||
code: "export default foo || bar;",
|
||||
output: "export default foo || bar",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{ message: "Extra semicolon.", type: "ExportDefaultDeclaration" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "export default (foo) => foo.bar();",
|
||||
output: "export default (foo) => foo.bar()",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{ message: "Extra semicolon.", type: "ExportDefaultDeclaration" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "export default foo = 42;",
|
||||
output: "export default foo = 42",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{ message: "Extra semicolon.", type: "ExportDefaultDeclaration" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "export default foo += 42;",
|
||||
output: "export default foo += 42",
|
||||
options: ["never"],
|
||||
parserOptions: { sourceType: "module" },
|
||||
errors: [
|
||||
{ message: "Extra semicolon.", type: "ExportDefaultDeclaration" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "a;\n++b",
|
||||
output: "a\n++b",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon." }],
|
||||
},
|
||||
|
||||
// babel
|
||||
{
|
||||
code: "class Foo { bar = 'example' }",
|
||||
errors: [{ message: "Missing semicolon." }],
|
||||
@@ -675,7 +32,7 @@ ruleTester.run("semi", rule, {
|
||||
errors: [{ message: "Missing semicolon." }],
|
||||
},
|
||||
|
||||
// babel, "never"
|
||||
// "never"
|
||||
{
|
||||
code: "class Foo { bar = 'example'; }",
|
||||
options: ["never"],
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
/**
|
||||
* @fileoverview Ensures that the results of typeof are compared against a valid string
|
||||
* @author Ian Christian Myers
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const rule = require("../../src/rules/valid-typeof"),
|
||||
RuleTester = require("../helpers/RuleTester");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Tests
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run("valid-typeof", rule, {
|
||||
valid: [
|
||||
// Original test cases.
|
||||
"typeof foo === 'string'",
|
||||
"typeof foo === 'object'",
|
||||
"typeof foo === 'function'",
|
||||
"typeof foo === 'undefined'",
|
||||
"typeof foo === 'boolean'",
|
||||
"typeof foo === 'number'",
|
||||
"'string' === typeof foo",
|
||||
"'object' === typeof foo",
|
||||
"'function' === typeof foo",
|
||||
"'undefined' === typeof foo",
|
||||
"'boolean' === typeof foo",
|
||||
"'number' === typeof foo",
|
||||
"typeof foo === typeof bar",
|
||||
"typeof foo === baz",
|
||||
"typeof foo !== someType",
|
||||
"typeof bar != someType",
|
||||
"someType === typeof bar",
|
||||
"someType == typeof bar",
|
||||
"typeof foo == 'string'",
|
||||
"typeof(foo) === 'string'",
|
||||
"typeof(foo) !== 'string'",
|
||||
"typeof(foo) == 'string'",
|
||||
"typeof(foo) != 'string'",
|
||||
"var oddUse = typeof foo + 'thing'",
|
||||
{
|
||||
code: "typeof foo === 'number'",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
},
|
||||
{
|
||||
code: 'typeof foo === "number"',
|
||||
options: [{ requireStringLiterals: true }],
|
||||
},
|
||||
{
|
||||
code: "var baz = typeof foo + 'thing'",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
},
|
||||
{
|
||||
code: "typeof foo === typeof bar",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
},
|
||||
{
|
||||
code: "typeof foo === `string`",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "`object` === typeof foo",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
{
|
||||
code: "typeof foo === `str${somethingElse}`",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
},
|
||||
|
||||
// Babel-specific test cases.
|
||||
{
|
||||
code: "typeof BigInt(Number.MAX_SAFE_INTEGER) === 'bigint'",
|
||||
},
|
||||
{
|
||||
code: "'bigint' === typeof BigInt(Number.MAX_SAFE_INTEGER)",
|
||||
},
|
||||
{
|
||||
code: "typeof BigInt(Number.MAX_SAFE_INTEGER) === 'bigint'",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
},
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: "typeof foo === 'strnig'",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "'strnig' === typeof foo",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "if (typeof bar === 'umdefined') {}",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "typeof foo !== 'strnig'",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "'strnig' !== typeof foo",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "if (typeof bar !== 'umdefined') {}",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "typeof foo != 'strnig'",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "'strnig' != typeof foo",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "if (typeof bar != 'umdefined') {}",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "typeof foo == 'strnig'",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "'strnig' == typeof foo",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "if (typeof bar == 'umdefined') {}",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "if (typeof bar === `umdefined`) {}",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Invalid typeof comparison value.",
|
||||
type: "TemplateLiteral",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "typeof foo == 'invalid string'",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "typeof foo == Object",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
errors: [
|
||||
{
|
||||
message: "Typeof comparisons should be to string literals.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "typeof foo === undefined",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
errors: [
|
||||
{
|
||||
message: "Typeof comparisons should be to string literals.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "undefined === typeof foo",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
errors: [
|
||||
{
|
||||
message: "Typeof comparisons should be to string literals.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "undefined == typeof foo",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
errors: [
|
||||
{
|
||||
message: "Typeof comparisons should be to string literals.",
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "typeof foo === `undefined${foo}`",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Typeof comparisons should be to string literals.",
|
||||
type: "TemplateLiteral",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "typeof foo === `${string}`",
|
||||
options: [{ requireStringLiterals: true }],
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
errors: [
|
||||
{
|
||||
message: "Typeof comparisons should be to string literals.",
|
||||
type: "TemplateLiteral",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// Babel-specific test cases.
|
||||
{
|
||||
code: "typeof foo === 'bgiint'",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "'bignit' === typeof foo",
|
||||
errors: [
|
||||
{ message: "Invalid typeof comparison value.", type: "Literal" },
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -17,5 +17,8 @@ module.exports = {
|
||||
"@babel/plugin-syntax-export-namespace-from",
|
||||
["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: false }],
|
||||
["@babel/plugin-proposal-pipeline-operator", { proposal: "minimal" }],
|
||||
"@babel/plugin-syntax-bigint",
|
||||
"@babel/plugin-proposal-private-methods",
|
||||
"@babel/plugin-proposal-do-expressions",
|
||||
],
|
||||
};
|
||||
25
eslint/babel-eslint-shared-fixtures/package.json
Normal file
25
eslint/babel-eslint-shared-fixtures/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "@babel/eslint-shared-fixtures",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "Shared fixtures for testing @babel/eslint-* packages",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.1.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.1.2",
|
||||
"@babel/plugin-proposal-do-expressions": "^7.7.4",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
|
||||
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
|
||||
"@babel/plugin-proposal-private-methods": "^7.7.4",
|
||||
"@babel/plugin-syntax-bigint": "^7.7.4",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||
"@babel/plugin-syntax-export-default-from": "^7.0.0",
|
||||
"@babel/plugin-syntax-export-namespace-from": "^7.0.0",
|
||||
"@babel/plugin-syntax-import-meta": "^7.0.0",
|
||||
"@babel/plugin-syntax-numeric-separator": "^7.0.0",
|
||||
"@babel/preset-env": "^7.1.5",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"@babel/preset-react": "^7.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,19 @@
|
||||
// These packages undet the @babel namespace aren't in this monorepo.
|
||||
const externalBabelPackages = [
|
||||
"plugin-syntax-async-generators",
|
||||
"plugin-syntax-bigint",
|
||||
"plugin-syntax-dynamic-import",
|
||||
"plugin-syntax-json-strings",
|
||||
"plugin-syntax-nullish-coalescing-operator",
|
||||
"plugin-syntax-object-rest-spread",
|
||||
"plugin-syntax-optional-catch-binding",
|
||||
"plugin-syntax-optional-chaining",
|
||||
];
|
||||
|
||||
// prettier-ignore
|
||||
const monorepoPackagePattern =
|
||||
`^@babel/(?!eslint-)(?!${externalBabelPackages.join("|")})([a-zA-Z0-9_-]+)$`;
|
||||
|
||||
module.exports = {
|
||||
collectCoverageFrom: [
|
||||
"packages/*/src/**/*.mjs",
|
||||
@@ -46,6 +62,7 @@ module.exports = {
|
||||
"<rootDir>/build/",
|
||||
],
|
||||
moduleNameMapper: {
|
||||
"^@babel/([a-zA-Z0-9_-]+)$": "<rootDir>/packages/babel-$1/",
|
||||
[monorepoPackagePattern]: "<rootDir>/packages/babel-$1/",
|
||||
"^@babel/eslint-([a-zA-Z0-9_-]+)$": "<rootDir>/eslint/babel-eslint-$1/",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "7.7.4-csx.1",
|
||||
"version": "7.8.3-csx.2",
|
||||
"changelog": {
|
||||
"repo": "babel/babel",
|
||||
"cacheDir": ".changelog",
|
||||
@@ -11,7 +11,8 @@
|
||||
"PR: Polish :nail_care:": ":nail_care: Polish",
|
||||
"PR: Docs :memo:": ":memo: Documentation",
|
||||
"PR: Internal :house:": ":house: Internal",
|
||||
"PR: Performance :running_woman:": ":running_woman: Performance"
|
||||
"PR: Performance :running_woman:": ":running_woman: Performance",
|
||||
"PR: Revert :leftwards_arrow_with_hook:": ":leftwards_arrow_with_hook: Revert"
|
||||
}
|
||||
},
|
||||
"command": {
|
||||
@@ -20,6 +21,7 @@
|
||||
"*.md",
|
||||
"*.txt",
|
||||
"test/**",
|
||||
"**/test/**",
|
||||
"codemods/**",
|
||||
"# We ignore every JSON file, except for built-in-modules, built-ins and plugins defined in babel-preset-env/data.",
|
||||
"@(!(built-in-modules|built-ins|plugins|package)).json",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
declare module "resolve" {
|
||||
declare export default {
|
||||
(string, {| basedir: string |}, (err: ?Error, res: string) => void): void;
|
||||
sync: (string, {| basedir: string |}) => string;
|
||||
};
|
||||
}
|
||||
@@ -178,7 +179,7 @@ declare module "convert-source-map" {
|
||||
SourceMap: SourceMap,
|
||||
Converter: Converter,
|
||||
fromObject(obj: SourceMap | SourceMapGenerator): Converter,
|
||||
fromJSON(str: string): Converter,
|
||||
fromJSON(str: string | Buffer): Converter,
|
||||
fromBase64(str: string): Converter,
|
||||
fromComment(str: string): Converter,
|
||||
fromMapFileComment(str: string, dir: string): Converter,
|
||||
@@ -190,12 +191,6 @@ declare module "convert-source-map" {
|
||||
};
|
||||
}
|
||||
|
||||
declare module "js-levenshtein" {
|
||||
declare module.exports: {
|
||||
(string, string): number,
|
||||
};
|
||||
}
|
||||
|
||||
declare module "core-js-compat/data" {
|
||||
declare type Target = "node" | "chrome" | "opera" | "edge" | "firefox" | "safari" | "ie" | "ios" | "android" | "electron" | "samsung";
|
||||
|
||||
|
||||
27
package.json
27
package.json
@@ -3,6 +3,7 @@
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"bootstrap": "make bootstrap",
|
||||
"build": "make build",
|
||||
"fix": "make fix",
|
||||
"lint": "make lint",
|
||||
@@ -16,26 +17,30 @@
|
||||
"@babel/plugin-proposal-export-namespace-from": "^7.5.2",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.4.4",
|
||||
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.7.4",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.6.0",
|
||||
"@babel/plugin-transform-flow-strip-types": "^7.7.4",
|
||||
"@babel/plugin-transform-for-of": "^7.7.4",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.7.0",
|
||||
"@babel/plugin-transform-runtime": "^7.6.2",
|
||||
"@babel/preset-env": "^7.7.1",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"@babel/register": "^7.7.0",
|
||||
"@babel/runtime": "^7.7.2",
|
||||
"babel-eslint": "^11.0.0-beta.0",
|
||||
"@rollup/plugin-alias": "^2.2.0",
|
||||
"@rollup/plugin-json": "^4.0.0",
|
||||
"babel-eslint": "^11.0.0-beta.2",
|
||||
"babel-jest": "^24.9.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-plugin-transform-charcodes": "^0.2.0",
|
||||
"browserify": "^16.2.3",
|
||||
"bundle-collapser": "^1.2.1",
|
||||
"chalk": "^2.4.2",
|
||||
"charcodes": "^0.2.0",
|
||||
"derequire": "^2.0.2",
|
||||
"duplicate-package-checker-webpack-plugin": "^2.1.0",
|
||||
"enhanced-resolve": "^3.0.0",
|
||||
"eslint": "^6.0.1",
|
||||
"eslint-config-babel": "^9.0.0",
|
||||
"eslint-import-resolver-node": "^0.3.2",
|
||||
"eslint-plugin-flowtype": "^3.8.2",
|
||||
"eslint-plugin-import": "^2.17.2",
|
||||
"eslint-plugin-prettier": "^3.1.0",
|
||||
@@ -48,7 +53,6 @@
|
||||
"gulp-newer": "^1.0.0",
|
||||
"gulp-plumber": "^1.2.1",
|
||||
"gulp-rename": "^1.4.0",
|
||||
"gulp-uglify": "^3.0.2",
|
||||
"gulp-watch": "^5.0.1",
|
||||
"husky": "^3.0.0",
|
||||
"jest": "^24.9.0",
|
||||
@@ -56,24 +60,25 @@
|
||||
"lerna-changelog": "^0.5.0",
|
||||
"lint-staged": "^9.2.0",
|
||||
"lodash": "^4.17.13",
|
||||
"mergeiterator": "^1.2.5",
|
||||
"output-file-sync": "^2.0.0",
|
||||
"prettier": "^1.19.1",
|
||||
"pump": "^3.0.0",
|
||||
"rimraf": "^2.6.3",
|
||||
"rollup": "^1.12.0",
|
||||
"rollup": "^1.27.5",
|
||||
"rollup-plugin-babel": "^4.0.0",
|
||||
"rollup-plugin-commonjs": "^10.1.0",
|
||||
"rollup-plugin-node-builtins": "^2.1.2",
|
||||
"rollup-plugin-node-globals": "^1.4.0",
|
||||
"rollup-plugin-node-resolve": "^5.0.0",
|
||||
"rollup-plugin-replace": "^2.2.0",
|
||||
"rollup-plugin-terser": "^5.1.2",
|
||||
"test262-stream": "^1.3.0",
|
||||
"through2": "^2.0.0",
|
||||
"typescript": "^3.6.3",
|
||||
"warnings-to-errors-webpack-plugin": "^2.0.0",
|
||||
"webpack": "^3.4.1",
|
||||
"webpack-dependency-suite": "^2.4.4",
|
||||
"webpack-stream": "^4.0.0"
|
||||
"typescript": "^3.6.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"@lerna/**/@lerna/collect-updates": "https://github.com/babel/lerna.git#babel-collect-updates"
|
||||
"@lerna/collect-updates": "https://github.com/babel/lerna.git#babel-collect-updates"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.9.0 < 14.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@babel/cli",
|
||||
"version": "7.7.4-csx.1",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "Babel command line.",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
@@ -35,8 +35,9 @@
|
||||
"@babel/core": "^7.0.0-0 || csx"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.4",
|
||||
"@babel/helper-fixtures": "^7.6.3"
|
||||
"@babel/core": "7.8.3-csx.2",
|
||||
"@babel/helper-fixtures": "7.8.3-csx.2",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"babel": "./bin/babel.js",
|
||||
|
||||
@@ -9,6 +9,13 @@ import fs from "fs";
|
||||
import * as util from "./util";
|
||||
import { type CmdOptions } from "./options";
|
||||
|
||||
const FILE_TYPE = Object.freeze({
|
||||
NON_COMPILABLE: "NON_COMPILABLE",
|
||||
COMPILED: "COMPILED",
|
||||
IGNORED: "IGNORED",
|
||||
ERR_COMPILATION: "ERR_COMPILATION",
|
||||
});
|
||||
|
||||
function outputFileSync(filePath: string, data: string | Buffer): void {
|
||||
makeDirSync(path.dirname(filePath));
|
||||
fs.writeFileSync(filePath, data);
|
||||
@@ -20,15 +27,22 @@ export default async function({
|
||||
}: CmdOptions): Promise<void> {
|
||||
const filenames = cliOptions.filenames;
|
||||
|
||||
async function write(src: string, base: string): Promise<boolean> {
|
||||
async function write(
|
||||
src: string,
|
||||
base: string,
|
||||
): Promise<$Keys<typeof FILE_TYPE>> {
|
||||
let relative = path.relative(base, src);
|
||||
|
||||
if (!util.isCompilableExtension(relative, cliOptions.extensions)) {
|
||||
return false;
|
||||
return FILE_TYPE.NON_COMPILABLE;
|
||||
}
|
||||
|
||||
// remove extension and then append back on .js
|
||||
relative = util.adjustRelative(relative, cliOptions.keepFileExtension);
|
||||
relative = util.withExtension(
|
||||
relative,
|
||||
cliOptions.keepFileExtension
|
||||
? path.extname(relative)
|
||||
: cliOptions.outFileExtension,
|
||||
);
|
||||
|
||||
const dest = getDest(relative, base);
|
||||
|
||||
@@ -43,7 +57,7 @@ export default async function({
|
||||
),
|
||||
);
|
||||
|
||||
if (!res) return false;
|
||||
if (!res) return FILE_TYPE.IGNORED;
|
||||
|
||||
// we've requested explicit sourcemaps to be written to disk
|
||||
if (
|
||||
@@ -64,11 +78,11 @@ export default async function({
|
||||
console.log(src + " -> " + dest);
|
||||
}
|
||||
|
||||
return true;
|
||||
return FILE_TYPE.COMPILED;
|
||||
} catch (err) {
|
||||
if (cliOptions.watch) {
|
||||
console.error(err);
|
||||
return false;
|
||||
return FILE_TYPE.ERR_COMPILATION;
|
||||
}
|
||||
|
||||
throw err;
|
||||
@@ -85,13 +99,16 @@ export default async function({
|
||||
async function handleFile(src: string, base: string): Promise<boolean> {
|
||||
const written = await write(src, base);
|
||||
|
||||
if (!written && cliOptions.copyFiles) {
|
||||
if (
|
||||
(cliOptions.copyFiles && written === FILE_TYPE.NON_COMPILABLE) ||
|
||||
(cliOptions.copyIgnored && written === FILE_TYPE.IGNORED)
|
||||
) {
|
||||
const filename = path.relative(base, src);
|
||||
const dest = getDest(filename, base);
|
||||
outputFileSync(dest, fs.readFileSync(src));
|
||||
util.chmod(src, dest);
|
||||
}
|
||||
return written;
|
||||
return written === FILE_TYPE.COMPILED;
|
||||
}
|
||||
|
||||
async function handle(filenameOrDir: string): Promise<number> {
|
||||
|
||||
@@ -216,6 +216,7 @@ export default async function({
|
||||
const chokidar = util.requireChokidar();
|
||||
chokidar
|
||||
.watch(filenames, {
|
||||
disableGlobbing: true,
|
||||
persistent: true,
|
||||
ignoreInitial: true,
|
||||
awaitWriteFinish: {
|
||||
@@ -224,7 +225,10 @@ export default async function({
|
||||
},
|
||||
})
|
||||
.on("all", function(type: string, filename: string): void {
|
||||
if (!util.isCompilableExtension(filename, cliOptions.extensions)) {
|
||||
if (
|
||||
!util.isCompilableExtension(filename, cliOptions.extensions) &&
|
||||
!filenames.includes(filename)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,8 +74,8 @@ commander.option(
|
||||
booleanify,
|
||||
);
|
||||
commander.option(
|
||||
"--minified [true|false]",
|
||||
"Save as many bytes when printing.",
|
||||
"--minified",
|
||||
"Save as many bytes when printing. (false by default)",
|
||||
);
|
||||
commander.option(
|
||||
"--auxiliary-comment-before [string]",
|
||||
@@ -160,6 +160,15 @@ commander.option(
|
||||
"--delete-dir-on-start",
|
||||
"Delete the out directory before compilation.",
|
||||
);
|
||||
commander.option(
|
||||
"--out-file-extension [string]",
|
||||
"Use a specific extension for the output files",
|
||||
);
|
||||
|
||||
commander.option(
|
||||
"--copy-ignored",
|
||||
"Include ignored files when copying non-compilable files.",
|
||||
);
|
||||
|
||||
commander.version(pkg.version + " (@babel/core " + version + ")");
|
||||
commander.usage("[options] <files ...>");
|
||||
@@ -237,6 +246,12 @@ export default function parseArgv(args: Array<string>): CmdOptions | null {
|
||||
);
|
||||
}
|
||||
|
||||
if (commander.keepFileExtension && commander.outFileExtension) {
|
||||
errors.push(
|
||||
"--out-file-extension cannot be used with --keep-file-extension",
|
||||
);
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
console.error("babel:");
|
||||
errors.forEach(function(e) {
|
||||
@@ -293,6 +308,7 @@ export default function parseArgv(args: Array<string>): CmdOptions | null {
|
||||
filenames,
|
||||
extensions: opts.extensions,
|
||||
keepFileExtension: opts.keepFileExtension,
|
||||
outFileExtension: opts.outFileExtension,
|
||||
watch: opts.watch,
|
||||
skipInitialBuild: opts.skipInitialBuild,
|
||||
outFile: opts.outFile,
|
||||
@@ -304,6 +320,7 @@ export default function parseArgv(args: Array<string>): CmdOptions | null {
|
||||
quiet: opts.quiet,
|
||||
deleteDirOnStart: opts.deleteDirOnStart,
|
||||
sourceMapTarget: opts.sourceMapTarget,
|
||||
copyIgnored: opts.copyIgnored,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -127,12 +127,7 @@ export function requireChokidar(): Object {
|
||||
}
|
||||
}
|
||||
|
||||
export function adjustRelative(
|
||||
relative: string,
|
||||
keepFileExtension: boolean,
|
||||
): string {
|
||||
if (keepFileExtension) {
|
||||
return relative;
|
||||
}
|
||||
return relative.replace(/\.(\w*?)$/, "") + ".js";
|
||||
export function withExtension(filename: string, ext: string = ".js") {
|
||||
const newBasename = path.basename(filename, path.extname(filename)) + ext;
|
||||
return path.join(path.dirname(filename), newBasename);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"ignore": ["src/foo"]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"args": [
|
||||
"src",
|
||||
"--out-dir",
|
||||
"lib",
|
||||
"--copy-files",
|
||||
"--include-dotfiles",
|
||||
"--verbose"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
index;
|
||||
@@ -0,0 +1,2 @@
|
||||
src/index.js -> lib/index.js
|
||||
Successfully compiled 1 file with Babel.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user