Compare commits

..

14 Commits

Author SHA1 Message Date
4fd9f6e6a2 Fixed semver coercing 2019-11-14 23:00:40 +01:00
08550a076c Attempt to fix babel's assertVersion(7) from not seeing our 7.#.#.csx-.. as valid version of babel 7 2019-11-12 01:02:54 +01:00
d50037be8f Fixing peerDependencies 2019-11-11 23:46:12 +01:00
fd2c2f61bb Fix @babel/core to use csx-version of helpers 2019-11-11 20:28:35 +01:00
0e5c224ff1 Resolving to csx won't work, thus this... (and let's hope it doesnt fuckup things once it reaches npm) 2019-11-11 19:17:58 +01:00
b0b6a92b90 Trying with local package-references 2019-11-11 19:08:20 +01:00
a5c141ea85 Updated the makefile to match the lerna command currently used to publish packages 2019-11-11 19:02:43 +01:00
e488c32244 Nearly there, pointing dependencies of @babel/helpers to the CSX version 2019-11-11 19:01:53 +01:00
0febc4f55f Attempt #n+1 to figure out what lerna's "lerna ERR! Only absolute URLs are supported" is about (and it not outputing a lerna-debug.out like it says it would...) 2019-11-11 16:50:00 +01:00
5415a390a9 Fixed a test-error that mysteriously popped up 2019-11-11 15:10:30 +01:00
7dd772001d Working around odd backslash issue with corejs2 iterableToArray-helper 2019-11-11 14:35:07 +01:00
d314e28457 Fixed tests 2019-11-11 14:18:26 +01:00
b248b3f4e9 Adding the prepublish step to the custom publish-cerxes makefile-target 2019-11-11 11:37:07 +01:00
c8c6ff7c4c Implemented a fix to initializers+class-properties 2019-11-11 11:33:32 +01:00
705 changed files with 6880 additions and 19258 deletions

View File

@ -1,5 +1,4 @@
version: 2.1
version: 2
aliases:
- &restore-node-modules-cache
keys:
@ -40,22 +39,15 @@ aliases:
- &artifact_test262_xunit
path: ~/test-results
- &artifact_test262_diff_tap
path: ~/diff.tap
executors:
node-executor:
docker:
- image: circleci/node:13
working_directory: ~/babel
jobs:
test:
executor: node-executor
working_directory: ~/babel
docker:
- image: circleci/node:13
steps:
- checkout
- restore_cache: *restore-yarn-cache
- restore_cache: *restore-node-modules-cache
- 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
@ -71,24 +63,26 @@ jobs:
- store_artifacts: *artifact_env_min
- save_cache: *save-node-modules-cache
- save_cache: *save-yarn-cache
test262:
executor: node-executor
working_directory: ~/babel
docker:
- image: circleci/node:12
steps:
- checkout
- run:
name: Sync with latest master branch (only on PRs)
command: |
if [ -n "$CIRCLE_PULL_REQUEST" ]
then
git fetch origin refs/pull/$CIRCLE_PR_NUMBER/merge
git checkout -qf FETCH_HEAD
fi
- restore_cache: *restore-yarn-cache
- restore_cache: *restore-node-modules-cache
- restore-cache: *restore-yarn-cache
- restore-cache: *restore-node-modules-cache
- run:
name: Build Babel
command: BABEL_ENV=test make bootstrap
- run:
name: Link Babel
command: |
cd packages
for package in */; do
cd $package
yarn link
cd ..
done
- run:
name: Setup Test Runner
command: |
@ -96,86 +90,32 @@ jobs:
cd babel-test262-runner
yarn
yarn add tap-mocha-reporter --dev
curl -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 > jq
chmod +x ./jq
for package in ../packages/*/package.json; do
yarn link $(./jq -j ".name" $package)
done
node lib/download-node
- run:
name: Download master branch Test262 artifact
command: node lib/download-master-artifact ~/master.tap
<<: *test262_workdir
- run:
name: Run Test262
command: BABEL_PATH=.. node lib/run-tests I_AM_SURE | tee ~/test262.tap
command: node lib/run-tests I_AM_SURE | tee ~/test262.tap
<<: *test262_workdir
- store_artifacts: *artifact_test262_tap
- run:
name: Output Test262 results
name: Output test262 results
command: |
cat ~/test262.tap | $(npm bin)/tap-mocha-reporter spec || true
<<: *test262_workdir
- run:
name: Compare previous master branch & current job results
command: |
mkdir -p ~/test-results/test262
node lib/compare-results ~/master.tap ~/test262.tap | tee ~/diff.tap
<<: *test262_workdir
- store_artifacts: *artifact_test262_diff_tap
- run:
name: Output comparision results and report to CircleCI
command: |
mkdir -p ~/test-results/test262
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
publish-verdaccio:
executor: node-executor
steps:
- checkout
- run: yarn install
- run: ./scripts/integration-tests/publish-local.sh
- persist_to_workspace:
root: /tmp/verdaccio-workspace
paths:
- storage
- htpasswd
e2e-babel:
executor: node-executor
steps:
- checkout
- attach_workspace:
at: /tmp/verdaccio-workspace
- run: ./scripts/integration-tests/e2e-babel.sh
workflows:
version: 2
test:
jobs:
- test
test262-master:
master:
jobs:
- test262:
filters:
branches:
only:
- master
test262:
jobs:
- approve-test262-run:
type: approval
filters:
branches:
ignore:
- master
- test262:
requires:
- approve-test262-run
filters:
branches:
ignore:
- master
e2e:
jobs:
- publish-verdaccio
- e2e-babel:
requires:
- publish-verdaccio

View File

@ -24,8 +24,3 @@ packages/babel-preset-env-standalone/babel-preset-env.min.js
packages/babel-standalone/babel.js
packages/babel-standalone/babel.min.js
packages/babel-parser/test/expressions
eslint/*/lib
eslint/*/node_modules
eslint/*/test
eslint/*/tests

View File

@ -1,48 +0,0 @@
module.exports = {
root: true,
plugins: ["prettier", "@babel/development", "import"],
extends: "babel",
rules: {
"prettier/prettier": "error",
// TODO: remove after babel-eslint-config-internal is fully integrated into this repository.
"max-len": "off",
},
env: {
node: true,
},
overrides: [
{
files: [
"packages/*/src/**/*.js",
"codemods/*/src/**/*.js",
"eslint/*/src/**/*.js",
],
rules: {
"@babel/development/no-undefined-identifier": "error",
"@babel/development/no-deprecated-clone": "error",
"import/no-extraneous-dependencies": "error",
"guard-for-in": "error",
},
},
{
files: [
"packages/*/test/**/*.js",
"codemods/*/test/**/*.js",
"eslint/*/test/**/*.js",
"packages/babel-helper-transform-fixture-test-runner/src/helpers.js",
"test/**/*.js",
],
env: {
jest: true,
},
},
{
files: ["packages/babel-plugin-*/src/index.js"],
excludedFiles: ["packages/babel-plugin-transform-regenerator/**/*.js"],
rules: {
"@babel/development/plugin-name": "error",
eqeqeq: ["error", "always", { null: "ignore" }],
},
},
],
};

41
.eslintrc.json Normal file
View File

@ -0,0 +1,41 @@
{
"root": true,
"plugins": ["prettier", "@babel/development", "import"],
"extends": "babel",
"rules": {
"prettier/prettier": "error"
},
"env": {
"node": true
},
"overrides": [
{
"files": ["packages/*/src/**/*.js", "codemods/*/src/**/*.js"],
"rules": {
"@babel/development/no-undefined-identifier": "error",
"@babel/development/no-deprecated-clone": "error",
"import/no-extraneous-dependencies": "error",
"guard-for-in": "error"
}
},
{
"files": [
"packages/*/test/**/*.js",
"codemods/*/test/**/*.js",
"packages/babel-helper-transform-fixture-test-runner/src/helpers.js",
"test/**/*.js"
],
"env": {
"jest": true
}
},
{
"files": ["packages/babel-plugin-*/src/index.js"],
"excludedFiles": ["packages/babel-plugin-transform-regenerator/**/*.js"],
"rules": {
"@babel/development/plugin-name": "error",
"eqeqeq": ["error", "always", { "null": "ignore" }]
}
}
]
}

View File

@ -9,11 +9,6 @@ assignees: ''
## Bug Report
<!--
@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.
-->
**Current Behavior**
A clear and concise description of the behavior.
@ -27,8 +22,7 @@ var your => (code) => here;
**Expected behavior/code**
A clear and concise description of what you expected to happen (or code).
**Babel Configuration (babel.config.js, .babelrc, package.json#babel, cli command, .eslintrc)**
- Filename: `babel.config.js`
**Babel Configuration (.babelrc, package.json, cli command)**
```js
{
@ -37,10 +31,6 @@ A clear and concise description of what you expected to happen (or code).
```
**Environment**
<!--- Tip: Instead of filling out the questions below, you can run `npx envinfo --preset babel` and paste the result below ``` -->
```
```
- Babel version(s): [e.g. v6.0.0, v7.0.0-beta.34]
- Node/npm version: [e.g. Node 8/npm 5]
- OS: [e.g. OSX 10.13.4, Windows 10]

View File

@ -26,10 +26,7 @@ A clear and concise description of what the regression is.
var your => (code) => here;
```
**Expected behavior/code**
A clear and concise description of what you expected to happen (or code).
**Babel Configuration (babel.config.js, .babelrc, package.json#babel, cli command)**
**Babel Configuration (.babelrc, package.json, cli command)**
```js
{
@ -37,11 +34,10 @@ A clear and concise description of what you expected to happen (or code).
}
```
**Environment**
<!--- Tip: Instead of filling out the questions below, you can run `npx envinfo --preset babel` and paste the result below ``` -->
```
**Expected behavior/code**
A clear and concise description of what you expected to happen (or code).
```
**Environment**
- Babel version(s): [e.g. v6.0.0, v7.0.0-beta.34]
- Node/npm version: [e.g. Node 8/npm 5]
- OS: [e.g. OSX 10.13.4, Windows 10]

7
.gitignore vendored
View File

@ -35,7 +35,7 @@ package-lock.json
!/packages/babel-runtime-corejs2/helpers/temporalRef.js
/packages/babel-runtime-corejs2/helpers/esm/*.js
!/packages/babel-runtime-corejs2/helpers/esm/toArray.js
!/packages/babel-runtime-corejs2/helpers/esm/iterableToArray.js
/packages/babel-runtime-corejs2/helpers/esm/iterableToArray.js
!/packages/babel-runtime-corejs2/helpers/esm/temporalRef.js
/packages/babel-runtime-corejs2/core-js/**/*.js
!/packages/babel-runtime-corejs2/core-js/map.js
@ -60,8 +60,3 @@ packages/babel-preset-env-standalone/babel-preset-env.min.js
/packages/babel-parser/build
.idea/
/.changelog
/eslint/*/lib
/eslint/*/node_modules
/eslint/*/LICENSE
!/packages/babel-eslint-plugin/LICENSE

View File

@ -13,12 +13,10 @@
"**/codemods/*/src/**/*.js",
"**/codemods/*/test/**/*.js",
"**/packages/*/src/**/*.js",
"**/packages/*/test/**/*.js",
"**/eslint/*/src/**/*.js",
"**/eslint/*/test/**/*.js"
"**/packages/*/test/**/*.js"
],
"parser": "babylon",
"options": {
"parser": "babel",
"trailingComma": "all"
}
}]

View File

@ -13,59 +13,10 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
See [CHANGELOG - v4](/.github/CHANGELOG-v4.md), [CHANGELOG - v5](/.github/CHANGELOG-v5.md), and [CHANGELOG - v6](/.github/CHANGELOG-v6.md) for v4.x-v6.x changes.
See [CHANGELOG - 6to5](/.github/CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
See [Babylon's CHANGELOG](packages/babel-parser/CHANGELOG.md) for the Babylon pre-7.0.0-beta.29 version changelog.
See [`babel-eslint`'s releases](https://github.com/babel/babel-eslint/releases) for the changelog before `@babel/eslint-parser` 7.8.0.
See [`eslint-plugin-babel`'s releases](https://github.com/babel/eslint-plugin-babel/releases) for the changelog before `@babel/eslint-plugin` 7.8.0.
See [Babylon's CHANGELOG](packages/babylon/CHANGELOG.md) for the Babylon pre-7.0.0-beta.29 version changelog.
<!-- DO NOT CHANGE THESE COMMENTS - See .github/actions/trigger-github-release/update-changelog.js -->
<!-- insert-new-changelog-here -->
## v7.7.4 (2019-11-23)
#### :bug: Bug Fix
* `babel-runtime-corejs2`, `babel-runtime-corejs3`, `babel-runtime`
* [#10748](https://github.com/babel/babel/pull/10748) Add support for native esm to @babel/runtime. ([@nicolo-ribaudo](https://github.com/nicolo-ribaudo))
* `babel-preset-env`
* [#10742](https://github.com/babel/babel/pull/10742) Update preset-env mappings. ([@existentialism](https://github.com/existentialism))
* `babel-parser`
* [#10737](https://github.com/babel/babel/pull/10737) Flow enums: fix enum body location. ([@gkz](https://github.com/gkz))
* [#10657](https://github.com/babel/babel/pull/10657) Fix some incorrect typeof parsing in flow. ([@existentialism](https://github.com/existentialism))
* [#10582](https://github.com/babel/babel/pull/10582) [parser] Allow optional async methods. ([@gonzarodriguezt](https://github.com/gonzarodriguezt))
* [#10710](https://github.com/babel/babel/pull/10710) register import equals specifier. ([@JLHwung](https://github.com/JLHwung))
* [#10592](https://github.com/babel/babel/pull/10592) Allow TypeScript type assertions in array destructuring. ([@SakibulMowla](https://github.com/SakibulMowla))
* `babel-preset-env-standalone`
* [#10732](https://github.com/babel/babel/pull/10732) fix: add missing available plugins to babel-preset-env-standalone. ([@JLHwung](https://github.com/JLHwung))
* `babel-plugin-transform-function-name`, `babel-plugin-transform-modules-umd`, `babel-preset-env`
* [#10701](https://github.com/babel/babel/pull/10701) Circumvent typeof transform for umd build template. ([@JLHwung](https://github.com/JLHwung))
* `babel-cli`
* [#10698](https://github.com/babel/babel/pull/10698) Babel should not silently remove unknown options after commander arguments. ([@JLHwung](https://github.com/JLHwung))
* `babel-plugin-proposal-optional-chaining`
* [#10694](https://github.com/babel/babel/pull/10694) Fix optional method chaining in derived classes. ([@Shriram-Balaji](https://github.com/Shriram-Balaji))
* `babel-parser`, `babel-types`
* [#10677](https://github.com/babel/babel/pull/10677) Add `asserts this [is type]` parsing support. ([@JLHwung](https://github.com/JLHwung))
* `babel-traverse`
* [#10598](https://github.com/babel/babel/pull/10598) Fix parentheses on replaceWithMultiple for JSX. ([@khoumani](https://github.com/khoumani))
* `babel-helpers`, `babel-plugin-proposal-object-rest-spread`, `babel-preset-env`
* [#10683](https://github.com/babel/babel/pull/10683) Fix: Don't call Object.keys on non-objects (babel#10482). ([@chrishinrichs](https://github.com/chrishinrichs))
#### :nail_care: Polish
* `babel-plugin-proposal-nullish-coalescing-operator`
* [#10720](https://github.com/babel/babel/pull/10720) polish: skip creating extra reference for safely re-used node. ([@JLHwung](https://github.com/JLHwung))
#### :house: Internal
* Other
* [#10731](https://github.com/babel/babel/pull/10731) Removed duplicate key in package.json. ([@rajasekarm](https://github.com/rajasekarm))
* [#10718](https://github.com/babel/babel/pull/10718) chore: use loose mode of transform. ([@JLHwung](https://github.com/JLHwung))
* [#10579](https://github.com/babel/babel/pull/10579) Implement PR workflow for running test262 on babel PRs. ([@jbhoosreddy](https://github.com/jbhoosreddy))
* [#10648](https://github.com/babel/babel/pull/10648) bump @babel/* dev dependencies. ([@JLHwung](https://github.com/JLHwung))
* [#10569](https://github.com/babel/babel/pull/10569) E2E test Babel with itself before publishing. ([@nicolo-ribaudo](https://github.com/nicolo-ribaudo))
* `babel-core`
* [#10668](https://github.com/babel/babel/pull/10668) Reduce standalone build size. ([@JLHwung](https://github.com/JLHwung))
* `babel-plugin-transform-literals`, `babel-preset-env-standalone`
* [#10725](https://github.com/babel/babel/pull/10725) fix typo [ci-skip]. ([@JLHwung](https://github.com/JLHwung))
* `babel-cli`
* [#10692](https://github.com/babel/babel/pull/10692) Add missing flow type to babel-cli for consistency. ([@ZYSzys](https://github.com/ZYSzys))
## v7.7.3 (2019-11-08)
#### :bug: Bug Fix

View File

@ -17,7 +17,7 @@ const rollupNodeResolve = require("rollup-plugin-node-resolve");
const rollupReplace = require("rollup-plugin-replace");
const { registerStandalonePackageTask } = require("./scripts/gulp-tasks");
const defaultSourcesGlob = "./@(codemods|packages|eslint)/*/src/**/*.js";
const defaultSourcesGlob = "./@(codemods|packages)/*/src/**/*.js";
function swapSrcWithLib(srcPath) {
const parts = srcPath.split(path.sep);

View File

@ -1,18 +1,10 @@
FLOW_COMMIT = 09669846b7a7ca5a6c23c12d56bb3bebdafd67e9
TEST262_COMMIT = 8688c4ab79059c3097098605e69f1ee5eda6c409
FORCE_PUBLISH = "@babel/runtime,@babel/runtime-corejs2,@babel/runtime-corejs3,@babel/standalone,@babel/preset-env-standalone"
# Fix color output until TravisCI fixes https://github.com/travis-ci/travis-ci/issues/7967
export FORCE_COLOR = true
SOURCES = packages codemods eslint
COMMA := ,
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
COMMA_SEPARATED_SOURCES = $(subst $(SPACE),$(COMMA),$(SOURCES))
SOURCES = packages codemods
.PHONY: build build-dist watch lint fix clean test-clean test-only test test-ci publish bootstrap
@ -119,7 +111,7 @@ fix-js:
yarn eslint scripts $(SOURCES) '*.js' --format=codeframe --fix
fix-json:
yarn prettier "{$(COMMA_SEPARATED_SOURCES)}/*/test/fixtures/**/options.json" --write --loglevel warn
yarn prettier "{packages,codemod}/*/test/fixtures/**/options.json" --write --loglevel warn
clean: test-clean
rm -f .npmrc
@ -197,13 +189,10 @@ prepublish:
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 --force-publish="@babel/runtime,@babel/runtime-corejs2,@babel/runtime-corejs3,@babel/standalone,@babel/preset-env-standalone"
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 initializers-fix --canary --preid csx --dist-tag csx
# NOTE: Run make new-version first
publish: prepublish
@ -221,43 +210,24 @@ endif
rm -f .npmrc
$(MAKE) clean
publish-test:
ifneq ("$(I_AM_USING_VERDACCIO)", "I_AM_SURE")
echo "You probably don't know what you are doing"
exit 1
endif
$(MAKE) prepublish-build
yarn lerna version patch --force-publish=$(FORCE_PUBLISH) --no-push --yes --tag-version-prefix="version-e2e-test-"
yarn lerna publish from-git --registry http://localhost:4873 --yes --tag-version-prefix="version-e2e-test-"
$(MAKE) clean
publish-eslint:
$(call set-json-field, ./eslint/$(PKG)/package.json, private, false)
cd eslint/$(PKG); yarn publish
$(call set-json-field, ./eslint/$(PKG)/package.json, private, true)
bootstrap-only: lerna-bootstrap
yarn-install: clean-all
yarn --ignore-engines
lerna-bootstrap: yarn-install
# todo: remove `-- -- --ignore-engines` in Babel 8
yarn lerna bootstrap -- -- --ignore-engines
yarn lerna bootstrap
bootstrap: bootstrap-only
$(MAKE) build
clean-lib:
# TODO: Don't delete eslint/*/lib when they use src
$(foreach source, $(SOURCES), \
$(if $(filter-out $(source), eslint), \
$(call clean-source-lib, $(source))))
$(call clean-source-lib, $(source)))
clean-runtime-helpers:
rm -f packages/babel-runtime/helpers/**/*.js
rm -f packages/babel-runtime-corejs2/helpers/**/*.js
rm -f packages/babel-runtime-corejs3/helpers/**/*.js
rm -rf packages/babel-runtime/helpers
rm -rf packages/babel-runtime-corejs2/helpers
rm -rf packages/babel-runtime-corejs2/core-js
clean-all:
@ -282,16 +252,8 @@ define clean-source-test
endef
define clean-source-all
# TODO: Don't delete eslint/*/lib when they use src
$(if $(filter-out $1, eslint), $(call clean-source-lib, $1))
rm -rf $(1)/*/lib
rm -rf $(1)/*/node_modules
rm -rf $(1)/*/package-lock.json
endef
define set-json-field
node -e "\
require('fs').writeFileSync('$1'.trim(), \
JSON.stringify({ ...require('$1'.trim()), $2: $3 }, null, 2) + '\\n' \
)"
endef

View File

@ -4,10 +4,17 @@
</a>
</p>
<p align="center">
<span style="color:darkred">
<b><i>WARNING</i> This is a fork of babel to test a fix for initializer-variables with class-properties (proposals-stuff)</b>
</span>
</p>
<p align="center">
The compiler for writing next generation JavaScript.
</p>
<p align="center">
<a href="https://www.npmjs.com/package/@babel/core"><img alt="v7 npm Downloads" src="https://img.shields.io/npm/dm/@babel/core.svg?maxAge=43200&label=v7%20downloads"></a>
<a href="https://www.npmjs.com/package/babel-core"><img alt="v6 npm Downloads" src="https://img.shields.io/npm/dm/babel-core.svg?maxAge=43200&label=v6%20downloads"></a>
@ -108,7 +115,7 @@ Some resources:
- Our [CONTRIBUTING.md](CONTRIBUTING.md) to get started with setting up the repo.
- Our discussions/notes/roadmap: [babel/notes](https://github.com/babel/notes)
- Our progress on TC39 proposals: [babel/proposals](https://github.com/babel/proposals)
- Our blog which contains release posts and explanations: [/blog](https://babeljs.io/blog)
- Our blog which contains release posts and explainations: [/blog](https://babeljs.io/blog)
- Our videos page with talks about open source and Babel: [/videos](https://babeljs.io/videos)
- Our [podcast](https://podcast.babeljs.io)

View File

@ -11,7 +11,6 @@ module.exports = function(api) {
exclude: ["transform-typeof-symbol"],
};
const envOpts = Object.assign({}, envOptsNoTargets);
let transformRuntimeOpts = null;
let convertESM = true;
let ignoreLib = true;
@ -51,17 +50,6 @@ 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),
};
}
const config = {
// Our dependencies are all standard CommonJS, along with all sorts of
// other random files in Babel's codebase, so we use script as the default,
@ -89,8 +77,8 @@ module.exports = function(api) {
"@babel/proposal-object-rest-spread",
{ useBuiltIns: true, loose: true },
],
["@babel/plugin-proposal-optional-chaining", { loose: true }],
["@babel/plugin-proposal-nullish-coalescing-operator", { loose: true }],
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-proposal-nullish-coalescing-operator",
convertESM ? "@babel/transform-modules-commonjs" : null,
].filter(Boolean),
@ -124,8 +112,6 @@ module.exports = function(api) {
"packages/*/test",
"codemods/*/src",
"codemods/*/test",
"eslint/*/src",
"eslint/*/test",
],
sourceType: "unambiguous",
},
@ -137,7 +123,7 @@ module.exports = function(api) {
],
plugins: [
includeRuntime
? ["@babel/transform-runtime", transformRuntimeOpts]
? ["@babel/transform-runtime", { version: "7.4.4" }]
: null,
].filter(Boolean),
},

View File

@ -1,6 +1,6 @@
{
"name": "@babel/plugin-codemod-object-assign-to-object-spread",
"version": "7.7.4-csx.0",
"version": "7.0.0",
"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",
@ -13,13 +13,16 @@
"@babel/plugin"
],
"dependencies": {
"@babel/plugin-syntax-object-rest-spread": "^7.7.4"
"@babel/plugin-syntax-object-rest-spread": "^7.0.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0 || csx"
},
"devDependencies": {
"@babel/core": "^7.7.4",
"@babel/helper-plugin-test-runner": "^7.7.4"
"@babel/core": "^7.0.0",
"@babel/helper-plugin-test-runner": "^7.0.0"
},
"publishConfig": {
"access": "public"
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@babel/plugin-codemod-optional-catch-binding",
"version": "7.7.4-csx.0",
"version": "7.0.0",
"description": "Remove unused catch bindings",
"repository": "https://github.com/babel/babel/tree/master/codemods/babel-plugin-codemod-remove-unused-catch-binding",
"license": "MIT",
@ -13,13 +13,13 @@
"@babel/plugin"
],
"dependencies": {
"@babel/plugin-syntax-optional-catch-binding": "^7.7.4"
"@babel/plugin-syntax-optional-catch-binding": "^7.0.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0 || csx"
},
"devDependencies": {
"@babel/core": "^7.7.4",
"@babel/helper-plugin-test-runner": "^7.7.4"
"@babel/core": "^7.0.0",
"@babel/helper-plugin-test-runner": "^7.0.0"
}
}

View File

@ -1,3 +1,3 @@
{
"plugins": ["../../../../lib"]
}
"plugins": ["../../../../lib"]
}

View File

@ -1,4 +0,0 @@
src
test
.*
*.log

View File

@ -1,4 +0,0 @@
## @babel/eslint-config-internal
---
ESLint config for the Babel codebase (originally taken from `eslint-config-kittens`)

View File

@ -1,49 +0,0 @@
"use strict";
module.exports = {
parser: "babel-eslint",
extends: "eslint:recommended",
plugins: ["flowtype"],
parserOptions: {
ecmaVersion: 2020,
sourceType: "module",
},
globals: {
// Flow
Iterator: true,
$Keys: true,
},
env: {
node: true,
es2020: true,
browser: true,
},
rules: {
camelcase: "off",
"consistent-return": "off",
curly: ["error", "multi-line"],
"linebreak-style": ["error", "unix"],
"new-cap": "off",
"no-case-declarations": "error",
"no-cond-assign": "off",
"no-confusing-arrow": "error",
"no-console": "off",
"no-constant-condition": "off",
"no-empty": "off",
"no-fallthrough": "off",
"no-inner-declarations": "off",
"no-labels": "off",
"no-loop-func": "off",
"no-process-exit": "off",
"no-return-assign": "off",
"no-shadow": "off",
"no-underscore-dangle": "off",
"no-unreachable": "off",
"no-use-before-define": "off",
"no-var": "error",
"prefer-const": "error",
strict: "off",
"flowtype/define-flow-type": "warn",
"flowtype/use-flow-type": "warn",
},
};

View File

@ -1,15 +0,0 @@
{
"name": "@babel/eslint-config-internal",
"version": "0.0.0",
"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/",
"license": "MIT",
"private": true,
"repository": "https://github.com/babel/babel/tree/master/eslint/babel-eslint-config-internal",
"main": "lib/index.js",
"peerDependencies": {
"babel-eslint": "^10.0.0 || ^11.0.0-0",
"eslint-plugin-flowtype": "^3.0.0"
}
}

View File

@ -1,4 +0,0 @@
src
test
.*
*.log

View File

@ -1,128 +0,0 @@
# babel-eslint [![npm](https://img.shields.io/npm/v/babel-eslint.svg)](https://www.npmjs.com/package/babel-eslint) [![travis](https://img.shields.io/travis/babel/babel-eslint/master.svg)](https://travis-ci.org/babel/babel-eslint) [![npm-downloads](https://img.shields.io/npm/dm/babel-eslint.svg)](https://www.npmjs.com/package/babel-eslint)
**babel-eslint** allows you to lint **ALL** valid Babel code with the fantastic
[ESLint](https://github.com/eslint/eslint).
## Breaking change in v11.x.x
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.
## 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).
## How does it work?
ESLint allows for the use of [custom parsers](https://eslint.org/docs/developer-guide/working-with-custom-parsers). When using this plugin, your code is parsed by Babel's parser (using the configuration specified in your [Babel configuration file](https://babeljs.io/docs/en/configuration)) and the resulting AST is
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.
## Usage
### Installation
```sh
$ npm install eslint babel-eslint --save-dev
# or
$ yarn add eslint babel-eslint -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).
### 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).
**.eslintrc.js**
```js
module.exports = {
parser: "babel-eslint",
};
```
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`.
### 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.
- `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.
**.eslintrc.js**
```js
module.exports = {
parser: "babel-eslint",
parserOptions: {
sourceType: "module",
allowImportExportEverywhere: false,
ecmaFeatures: {
globalReturn: false,
},
babelOptions: {
configFile: "path/to/config.js",
},
},
};
```
**.eslintrc.js using glob-based configuration**
This configuration would use the default parser for all files except for those found by the `"files/transformed/by/babel/*.js"` glob.
```js
module.exports = {
rules: {
indent: "error"
},
overrides: [
{
files: ["files/transformed/by/babel/*.js"],
parser: "babel-eslint",
}
]
};
```
### Run
```sh
$ ./node_modules/.bin/eslint yourfile.js
```
## Known issues
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)
- 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)
Modules/strict mode
- `no-unused-vars: ["error", { vars: local }]` [#136](https://github.com/babel/babel-eslint/issues/136)
Please check out [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) for React/JSX issues.
- `no-unused-vars` with jsx
Please check out [eslint-plugin-babel](https://github.com/babel/eslint-plugin-babel) for other issues.
## 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.
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).

View File

@ -1,51 +0,0 @@
{
"name": "babel-eslint",
"version": "7.7.4-csx.1",
"description": "Custom parser for ESLint",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"license": "MIT",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/babel/babel-eslint.git"
},
"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'"
},
"engines": {
"node": ">=6"
},
"main": "lib/index.js",
"peerDependencies": {
"@babel/core": ">=7.2.0",
"eslint": ">= 4.12.1"
},
"dependencies": {
"eslint-scope": "3.7.1",
"eslint-visitor-keys": "^1.0.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",
"dedent": "^0.7.0",
"eslint": "^6.0.1",
"espree": "^6.0.0"
}
}

View File

@ -1,338 +0,0 @@
"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");
const flowFlippedAliasKeys = t.FLIPPED_ALIAS_KEYS.Flow.concat([
"ArrayPattern",
"ClassDeclaration",
"ClassExpression",
"FunctionDeclaration",
"FunctionExpression",
"Identifier",
"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 propertyTypes = {
// loops
callProperties: { type: "loop", values: ["value"] },
indexers: { type: "loop", values: ["key", "value"] },
properties: { type: "loop", values: ["argument", "value"] },
types: { type: "loop" },
params: { type: "loop" },
// single property
argument: { type: "single" },
elementType: { type: "single" },
qualification: { type: "single" },
rest: { type: "single" },
returnType: { type: "single" },
// others
typeAnnotation: { type: "typeAnnotation" },
typeParameters: { type: "typeParameters" },
id: { type: "id" },
};
class PatternVisitor extends OriginalPatternVisitor {
ArrayPattern(node) {
node.elements.forEach(this.visit, this);
}
ObjectPattern(node) {
node.properties.forEach(this.visit, this);
}
}
class Referencer extends OriginalReferencer {
// inherits.
visitPattern(node, options, callback) {
if (!node) {
return;
}
// Visit type annotations.
this._checkIdentifierOrVisit(node.typeAnnotation);
if (t.isAssignmentPattern(node)) {
this._checkIdentifierOrVisit(node.left.typeAnnotation);
}
// Overwrite `super.visitPattern(node, options, callback)` in order to not visit `ArrayPattern#typeAnnotation` and `ObjectPattern#typeAnnotation`.
if (typeof options === "function") {
callback = options;
options = { processRightHandNodes: false };
}
const visitor = new PatternVisitor(this.options, node, callback);
visitor.visit(node);
// Process the right hand nodes recursively.
if (options.processRightHandNodes) {
visitor.rightHandNodes.forEach(this.visit, this);
}
}
// inherits.
visitClass(node) {
// Decorators.
this._visitArray(node.decorators);
// Flow type parameters.
const typeParamScope = this._nestTypeParamScope(node);
// Flow super types.
this._visitTypeAnnotation(node.implements);
this._visitTypeAnnotation(
node.superTypeParameters && node.superTypeParameters.params,
);
// Basic.
super.visitClass(node);
// Close the type parameter scope.
if (typeParamScope) {
this.close(node);
}
}
// inherits.
visitFunction(node) {
const typeParamScope = this._nestTypeParamScope(node);
// Flow return types.
this._checkIdentifierOrVisit(node.returnType);
// Basic.
super.visitFunction(node);
// Close the type parameter scope.
if (typeParamScope) {
this.close(node);
}
}
// inherits.
visitProperty(node) {
if (node.value && node.value.type === "TypeCastExpression") {
this._visitTypeAnnotation(node.value);
}
this._visitArray(node.decorators);
super.visitProperty(node);
}
InterfaceDeclaration(node) {
this._createScopeVariable(node, node.id);
const typeParamScope = this._nestTypeParamScope(node);
// TODO: Handle mixins
this._visitArray(node.extends);
this.visit(node.body);
if (typeParamScope) {
this.close(node);
}
}
TypeAlias(node) {
this._createScopeVariable(node, node.id);
const typeParamScope = this._nestTypeParamScope(node);
this.visit(node.right);
if (typeParamScope) {
this.close(node);
}
}
ClassProperty(node) {
this._visitClassProperty(node);
}
ClassPrivateProperty(node) {
this._visitClassProperty(node);
}
DeclareModule(node) {
this._visitDeclareX(node);
}
DeclareFunction(node) {
this._visitDeclareX(node);
}
DeclareVariable(node) {
this._visitDeclareX(node);
}
DeclareClass(node) {
this._visitDeclareX(node);
}
// visit OptionalMemberExpression as a MemberExpression.
OptionalMemberExpression(node) {
super.MemberExpression(node);
}
_visitClassProperty(node) {
this._visitTypeAnnotation(node.typeAnnotation);
this.visitProperty(node);
}
_visitDeclareX(node) {
if (node.id) {
this._createScopeVariable(node, node.id);
}
const typeParamScope = this._nestTypeParamScope(node);
if (typeParamScope) {
this.close(node);
}
}
_createScopeVariable(node, name) {
this.currentScope().variableScope.__define(
name,
new Definition("Variable", name, node, null, null, null),
);
}
_nestTypeParamScope(node) {
if (!node.typeParameters) {
return null;
}
const parentScope = this.scopeManager.__currentScope;
const scope = new escope.Scope(
this.scopeManager,
"type-parameters",
parentScope,
node,
false,
);
this.scopeManager.__nestScope(scope);
for (let j = 0; j < node.typeParameters.params.length; j++) {
const name = node.typeParameters.params[j];
scope.__define(name, new Definition("TypeParameter", name, name));
if (name.typeAnnotation) {
this._checkIdentifierOrVisit(name);
}
}
scope.__define = function() {
return parentScope.__define.apply(parentScope, arguments);
};
return scope;
}
_visitTypeAnnotation(node) {
if (!node) {
return;
}
if (Array.isArray(node)) {
node.forEach(this._visitTypeAnnotation, this);
return;
}
// get property to check (params, id, etc...)
const visitorValues = visitorKeysMap[node.type];
if (!visitorValues) {
return;
}
// can have multiple properties
for (let i = 0; i < visitorValues.length; i++) {
const visitorValue = visitorValues[i];
const propertyType = propertyTypes[visitorValue];
const nodeProperty = node[visitorValue];
// check if property or type is defined
if (propertyType == null || nodeProperty == null) {
continue;
}
if (propertyType.type === "loop") {
for (let j = 0; j < nodeProperty.length; j++) {
if (Array.isArray(propertyType.values)) {
for (let k = 0; k < propertyType.values.length; k++) {
const loopPropertyNode = nodeProperty[j][propertyType.values[k]];
if (loopPropertyNode) {
this._checkIdentifierOrVisit(loopPropertyNode);
}
}
} else {
this._checkIdentifierOrVisit(nodeProperty[j]);
}
}
} else if (propertyType.type === "single") {
this._checkIdentifierOrVisit(nodeProperty);
} else if (propertyType.type === "typeAnnotation") {
this._visitTypeAnnotation(node.typeAnnotation);
} else if (propertyType.type === "typeParameters") {
for (let l = 0; l < node.typeParameters.params.length; l++) {
this._checkIdentifierOrVisit(node.typeParameters.params[l]);
}
} else if (propertyType.type === "id") {
if (node.id.type === "Identifier") {
this._checkIdentifierOrVisit(node.id);
} else {
this._visitTypeAnnotation(node.id);
}
}
}
}
_checkIdentifierOrVisit(node) {
if (node && node.typeAnnotation) {
this._visitTypeAnnotation(node.typeAnnotation);
} else if (node && node.type === "Identifier") {
this.visit(node);
} else {
this._visitTypeAnnotation(node);
}
}
_visitArray(nodeList) {
if (nodeList) {
for (const node of nodeList) {
this.visit(node);
}
}
}
}
module.exports = function(ast, parserOptions) {
const options = {
ignoreEval: true,
optimistic: false,
directive: false,
nodejsScope:
ast.sourceType === "script" &&
(parserOptions.ecmaFeatures &&
parserOptions.ecmaFeatures.globalReturn) === true,
impliedStrict: false,
sourceType: ast.sourceType,
ecmaVersion: parserOptions.ecmaVersion,
fallback,
};
options.childVisitorKeys = childVisitorKeys;
const scopeManager = new escope.ScopeManager(options);
const referencer = new Referencer(options, scopeManager);
referencer.visit(ast);
return scopeManager;
};

View File

@ -1,99 +0,0 @@
"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);
};
const astTransformVisitor = {
noScope: true,
enter(path) {
const node = path.node;
// private var to track original node type
node._babelType = node.type;
if (node.innerComments) {
delete node.innerComments;
}
if (node.trailingComments) {
delete node.trailingComments;
}
if (node.leadingComments) {
delete node.leadingComments;
}
},
exit(path) {
const node = path.node;
if (path.isTypeParameter()) {
node.type = "Identifier";
node.typeAnnotation = node.bound;
delete node.bound;
}
// flow: prevent "no-undef"
// for "Component" in: "let x: React.Component"
if (path.isQualifiedTypeIdentifier()) {
delete node.id;
}
// for "b" in: "var a: { b: Foo }"
if (path.isObjectTypeProperty()) {
delete node.key;
}
// for "indexer" in: "var a: {[indexer: string]: number}"
if (path.isObjectTypeIndexer()) {
delete node.id;
}
// for "param" in: "var a: { func(param: Foo): Bar };"
if (path.isFunctionTypeParam()) {
delete node.name;
}
// 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];
q.range[0] -= 1;
if (q.tail) {
q.range[1] += 1;
} else {
q.range[1] += 2;
}
q.loc.start.column -= 1;
if (q.tail) {
q.loc.end.column += 1;
} else {
q.loc.end.column += 2;
}
}
}
},
};

View File

@ -1,17 +0,0 @@
"use strict";
module.exports = function(comments) {
for (let i = 0; i < comments.length; i++) {
const comment = comments[i];
if (comment.type === "CommentBlock") {
comment.type = "Block";
} else if (comment.type === "CommentLine") {
comment.type = "Line";
}
// sometimes comments don't get ranges computed,
// even with options.ranges === true
if (!comment.range) {
comment.range = [comment.start, comment.end];
}
}
};

View File

@ -1,40 +0,0 @@
"use strict";
module.exports = function(ast) {
ast.type = "Program";
ast.sourceType = ast.program.sourceType;
ast.directives = ast.program.directives;
ast.body = ast.program.body;
delete ast.program;
if (ast.comments.length) {
const lastComment = ast.comments[ast.comments.length - 1];
if (!ast.tokens.length) {
// if no tokens, the program starts at the end of the last comment
ast.start = lastComment.end;
ast.loc.start.line = lastComment.loc.end.line;
ast.loc.start.column = lastComment.loc.end.column;
} else {
const lastToken = ast.tokens[ast.tokens.length - 1];
if (lastComment.end > lastToken.end) {
// If there is a comment after the last token, the program ends at the
// last token and not the comment
ast.range[1] = lastToken.end;
ast.loc.end.line = lastToken.loc.end.line;
ast.loc.end.column = lastToken.loc.end.column;
}
}
} else {
if (!ast.tokens.length) {
ast.loc.start.line = 1;
ast.loc.end.line = 1;
}
}
if (ast.body && ast.body.length > 0) {
ast.loc.start.line = ast.body[0].loc.start.line;
ast.range[0] = ast.body[0].start;
}
};

View File

@ -1,92 +0,0 @@
"use strict";
module.exports = function(tokens, tt) {
let curlyBrace = null;
let templateTokens = [];
const result = [];
function addTemplateType() {
const start = templateTokens[0];
const end = templateTokens[templateTokens.length - 1];
const value = templateTokens.reduce((result, token) => {
if (token.value) {
result += token.value;
} else if (token.type !== tt.template) {
result += token.type.label;
}
return result;
}, "");
result.push({
type: "Template",
value: value,
start: start.start,
end: end.end,
loc: {
start: start.loc.start,
end: end.loc.end,
},
});
templateTokens = [];
}
tokens.forEach(token => {
switch (token.type) {
case tt.backQuote:
if (curlyBrace) {
result.push(curlyBrace);
curlyBrace = null;
}
templateTokens.push(token);
if (templateTokens.length > 1) {
addTemplateType();
}
break;
case tt.dollarBraceL:
templateTokens.push(token);
addTemplateType();
break;
case tt.braceR:
if (curlyBrace) {
result.push(curlyBrace);
}
curlyBrace = token;
break;
case tt.template:
if (curlyBrace) {
templateTokens.push(curlyBrace);
curlyBrace = null;
}
templateTokens.push(token);
break;
case tt.eof:
if (curlyBrace) {
result.push(curlyBrace);
}
break;
default:
if (curlyBrace) {
result.push(curlyBrace);
curlyBrace = null;
}
result.push(token);
}
});
return result;
};

View File

@ -1,85 +0,0 @@
"use strict";
module.exports = function(token, tt, source) {
const type = token.type;
token.range = [token.start, token.end];
if (type === tt.name) {
token.type = "Identifier";
} else if (
type === tt.semi ||
type === tt.comma ||
type === tt.parenL ||
type === tt.parenR ||
type === tt.braceL ||
type === tt.braceR ||
type === tt.slash ||
type === tt.dot ||
type === tt.bracketL ||
type === tt.bracketR ||
type === tt.ellipsis ||
type === tt.arrow ||
type === tt.pipeline ||
type === tt.star ||
type === tt.incDec ||
type === tt.colon ||
type === tt.question ||
type === tt.questionDot ||
type === tt.template ||
type === tt.backQuote ||
type === tt.dollarBraceL ||
type === tt.at ||
type === tt.logicalOR ||
type === tt.logicalAND ||
type === tt.nullishCoalescing ||
type === tt.bitwiseOR ||
type === tt.bitwiseXOR ||
type === tt.bitwiseAND ||
type === tt.equality ||
type === tt.relational ||
type === tt.bitShift ||
type === tt.plusMin ||
type === tt.modulo ||
type === tt.exponent ||
type === tt.bang ||
type === tt.tilde ||
type === tt.doubleColon ||
type === tt.hash ||
type.isAssign
) {
token.type = "Punctuator";
if (!token.value) token.value = type.label;
} else if (type === tt.jsxTagStart) {
token.type = "Punctuator";
token.value = "<";
} else if (type === tt.jsxTagEnd) {
token.type = "Punctuator";
token.value = ">";
} else if (type === tt.jsxName) {
token.type = "JSXIdentifier";
} else if (type === tt.jsxText) {
token.type = "JSXText";
} else if (type.keyword === "null") {
token.type = "Null";
} else if (type.keyword === "false" || type.keyword === "true") {
token.type = "Boolean";
} else if (type.keyword) {
token.type = "Keyword";
} else if (type === tt.num) {
token.type = "Numeric";
token.value = source.slice(token.start, token.end);
} else if (type === tt.string) {
token.type = "String";
token.value = source.slice(token.start, token.end);
} else if (type === tt.regexp) {
token.type = "RegularExpression";
const value = token.value;
token.regex = {
pattern: value.pattern,
flags: value.flags,
};
token.value = `/${value.pattern}/${value.flags}`;
}
return token;
};

View File

@ -1,10 +0,0 @@
"use strict";
const convertTemplateType = require("./convertTemplateType");
const convertToken = require("./convertToken");
module.exports = function(tokens, tt, code) {
return convertTemplateType(tokens, tt)
.filter(t => t.type !== "CommentLine" && t.type !== "CommentBlock")
.map(t => convertToken(t, tt, code));
};

View File

@ -1,11 +0,0 @@
"use strict";
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);
convertComments(ast.comments);
convertAST(ast, traverse, code);
};

View File

@ -1,33 +0,0 @@
"use strict";
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(
semver.coerce(CURRENT_BABEL_VERSION).raw,
SUPPORTED_BABEL_VERSION_RANGE,
);
exports.parse = function(code, options) {
return exports.parseForESLint(code, options).ast;
};
exports.parseForESLint = function(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);
};

View File

@ -1,12 +0,0 @@
"use strict";
const visitorKeys = require("./visitor-keys");
const analyzeScope = require("./analyze-scope");
const parse = require("./parse");
module.exports = function(code, options) {
const ast = parse(code, options);
const scopeManager = analyzeScope(ast, options);
return { ast, scopeManager, visitorKeys };
};

View File

@ -1,73 +0,0 @@
"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;
}
}
let ast;
try {
ast = parse(code, opts);
} catch (err) {
if (err instanceof SyntaxError) {
err.lineNumber = err.loc.line;
err.column = err.loc.column;
}
throw err;
}
babylonToEspree(ast, traverse, tt, code);
return ast;
};

View File

@ -1,15 +0,0 @@
"use strict";
const BABEL_VISITOR_KEYS = require("@babel/core").types.VISITOR_KEYS;
const ESLINT_VISITOR_KEYS = require("eslint-visitor-keys").KEYS;
module.exports = Object.assign(
{
Literal: ESLINT_VISITOR_KEYS.Literal,
MethodDefinition: ["decorators"].concat(
ESLINT_VISITOR_KEYS.MethodDefinition,
),
Property: ["decorators"].concat(ESLINT_VISITOR_KEYS.Property),
},
BABEL_VISITOR_KEYS,
);

View File

@ -1,527 +0,0 @@
"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");
const babelOptions = {
configFile: path.resolve(
__dirname,
"./fixtures/config/babel.config.js"
),
}
function parseAndAssertSame(code) {
code = unpad(code);
const esAST = espree.parse(code, {
ecmaFeatures: {
// enable JSX parsing
jsx: true,
// enable return in global scope
globalReturn: true,
// enable implied strict mode (if ecmaVersion >= 5)
impliedStrict: true,
// allow experimental object rest/spread
experimentalObjectRestSpread: true,
},
tokens: true,
loc: true,
range: true,
comment: true,
ecmaVersion: 2018,
sourceType: "module",
});
const babylonAST = babelEslint.parseForESLint(code, {
eslintVisitorKeys: true,
eslintScopeManager: true,
babelOptions,
}).ast;
assertImplementsAST(esAST, babylonAST);
}
describe("babylon-to-espree", () => {
describe("compatibility", () => {
it("should allow ast.analyze to be called without options", function() {
const esAST = babelEslint.parseForESLint("`test`", {
eslintScopeManager: true,
eslintVisitorKeys: true,
babelOptions,
}).ast;
expect(() => {
escope.analyze(esAST)
}).not.toThrow(new TypeError('Should allow no options argument.'));
});
});
describe("templates", () => {
it("empty template string", () => {
parseAndAssertSame("``");
});
it("template string", () => {
parseAndAssertSame("`test`");
});
it("template string using $", () => {
parseAndAssertSame("`$`");
});
it("template string with expression", () => {
parseAndAssertSame("`${a}`");
});
it("template string with multiple expressions", () => {
parseAndAssertSame("`${a}${b}${c}`");
});
it("template string with expression and strings", () => {
parseAndAssertSame("`a${a}a`");
});
it("template string with binary expression", () => {
parseAndAssertSame("`a${a + b}a`");
});
it("tagged template", () => {
parseAndAssertSame("jsx`<Button>Click</Button>`");
});
it("tagged template with expression", () => {
parseAndAssertSame("jsx`<Button>Hi ${name}</Button>`");
});
it("tagged template with new operator", () => {
parseAndAssertSame("new raw`42`");
});
it("template with nested function/object", () => {
parseAndAssertSame(
"`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(); }"
);
});
it("template also with braces #96", () => {
parseAndAssertSame(`
export default function f1() {
function f2(foo) {
const bar = 3;
return \`\${foo} \${bar}\`;
}
return f2;
}
`);
});
it("template with destructuring #31", () => {
parseAndAssertSame(`
module.exports = {
render() {
var {name} = this.props;
return Math.max(null, \`Name: \${name}, Name: \${name}\`);
}
};
`);
});
it("template with arrow returning template #603", () => {
parseAndAssertSame(`
var a = \`\${() => {
\`\${''}\`
}}\`;
`);
});
it("template string with object with template string inside", () => {
parseAndAssertSame("`${ { a:`${2}` } }`");
});
});
it("simple expression", () => {
parseAndAssertSame("a = 1");
});
it("logical NOT", () => {
parseAndAssertSame("!0");
});
it("bitwise NOT", () => {
parseAndAssertSame("~0");
});
it("class declaration", () => {
parseAndAssertSame("class Foo {}");
});
it("class expression", () => {
parseAndAssertSame("var a = class Foo {}");
});
it("jsx expression", () => {
parseAndAssertSame("<App />");
});
it("jsx expression with 'this' as identifier", () => {
parseAndAssertSame("<this />");
});
it("jsx expression with a dynamic attribute", () => {
parseAndAssertSame("<App foo={bar} />");
});
it("jsx expression with a member expression as identifier", () => {
parseAndAssertSame("<foo.bar />");
});
it("jsx expression with spread", () => {
parseAndAssertSame("var myDivElement = <div {...this.props} />;");
});
it("empty jsx text", () => {
parseAndAssertSame("<a></a>");
});
it("jsx text with content", () => {
parseAndAssertSame("<a>Hello, world!</a>");
});
it("nested jsx", () => {
parseAndAssertSame("<div>\n<h1>Wat</h1>\n</div>");
});
it("default import", () => {
parseAndAssertSame('import foo from "foo";');
});
it("import specifier", () => {
parseAndAssertSame('import { foo } from "foo";');
});
it("import specifier with name", () => {
parseAndAssertSame('import { foo as bar } from "foo";');
});
it("import bare", () => {
parseAndAssertSame('import "foo";');
});
it("export default class declaration", () => {
parseAndAssertSame("export default class Foo {}");
});
it("export default class expression", () => {
parseAndAssertSame("export default class {}");
});
it("export default function declaration", () => {
parseAndAssertSame("export default function Foo() {}");
});
it("export default function expression", () => {
parseAndAssertSame("export default function () {}");
});
it("export all", () => {
parseAndAssertSame('export * from "foo";');
});
it("export named", () => {
parseAndAssertSame("var foo = 1;export { foo };");
});
it("export named alias", () => {
parseAndAssertSame("var foo = 1;export { foo as bar };");
});
// Espree doesn't support the optional chaining operator yet
it("optional chaining operator (token)", () => {
const code = "foo?.bar";
const babylonAST = babelEslint.parseForESLint(code, {
eslintVisitorKeys: true,
eslintScopeManager: true,
babelOptions,
}).ast;
assert.strictEqual(babylonAST.tokens[1].type, "Punctuator");
});
// Espree doesn't support the nullish coalescing operator yet
it("nullish coalescing operator (token)", () => {
const code = "foo ?? bar";
const babylonAST = babelEslint.parseForESLint(code, {
eslintVisitorKeys: true,
eslintScopeManager: true,
babelOptions,
}).ast;
assert.strictEqual(babylonAST.tokens[1].type, "Punctuator");
});
// Espree doesn't support the pipeline operator yet
it("pipeline operator (token)", () => {
const code = "foo |> bar";
const babylonAST = babelEslint.parseForESLint(code, {
eslintVisitorKeys: true,
eslintScopeManager: true,
babelOptions,
}).ast;
assert.strictEqual(babylonAST.tokens[1].type, "Punctuator");
});
// Espree doesn't support the private fields yet
it("hash (token)", () => {
const code = "class A { #x }";
const babylonAST = babelEslint.parseForESLint(code, {
eslintVisitorKeys: true,
eslintScopeManager: true,
babelOptions,
}).ast;
assert.strictEqual(babylonAST.tokens[3].type, "Punctuator");
assert.strictEqual(babylonAST.tokens[3].value, "#");
});
it.skip("empty program with line comment", () => {
parseAndAssertSame("// single comment");
});
it.skip("empty program with block comment", () => {
parseAndAssertSame(" /* multiline\n * comment\n*/");
});
it("line comments", () => {
parseAndAssertSame(`
// single comment
var foo = 15; // comment next to statement
// second comment after statement
`);
});
it("block comments", () => {
parseAndAssertSame(`
/* single comment */
var foo = 15; /* comment next to statement */
/*
* multiline
* comment
*/
`);
});
it("block comments #124", () => {
parseAndAssertSame(`
React.createClass({
render() {
// return (
// <div />
// ); // <-- this is the line that is reported
}
});
`);
});
it("null", () => {
parseAndAssertSame("null");
});
it("boolean", () => {
parseAndAssertSame("if (true) {} else if (false) {}");
});
it("regexp", () => {
parseAndAssertSame("/affix-top|affix-bottom|affix|[a-z]/");
});
it("regexp", () => {
parseAndAssertSame("const foo = /foo/;");
});
it("regexp y flag", () => {
parseAndAssertSame("const foo = /foo/y;");
});
it("regexp u flag", () => {
parseAndAssertSame("const foo = /foo/u;");
});
it("regexp in a template string", () => {
parseAndAssertSame('`${/\\d/.exec("1")[0]}`');
});
it("first line is empty", () => {
parseAndAssertSame('\nimport Immutable from "immutable";');
});
it("empty", () => {
parseAndAssertSame("");
});
it("jsdoc", () => {
parseAndAssertSame(`
/**
* @param {object} options
* @return {number}
*/
const test = function({ a, b, c }) {
return a + b + c;
};
module.exports = test;
`);
});
it("empty block with comment", () => {
parseAndAssertSame(`
function a () {
try {
b();
} catch (e) {
// asdf
}
}
`);
});
describe("babel tests", () => {
it("MethodDefinition", () => {
parseAndAssertSame(`
export default class A {
a() {}
}
`);
});
it("MethodDefinition 2", () => {
parseAndAssertSame(
"export default class Bar { get bar() { return 42; }}"
);
});
it("ClassMethod", () => {
parseAndAssertSame(`
class A {
constructor() {
}
}
`);
});
it("ClassMethod multiple params", () => {
parseAndAssertSame(`
class A {
constructor(a, b, c) {
}
}
`);
});
it("ClassMethod multiline", () => {
parseAndAssertSame(`
class A {
constructor (
a,
b,
c
)
{
}
}
`);
});
it("ClassMethod oneline", () => {
parseAndAssertSame("class A { constructor(a, b, c) {} }");
});
it("ObjectMethod", () => {
parseAndAssertSame(`
var a = {
b(c) {
}
}
`);
});
it("do not allow import export everywhere", () => {
assert.throws(() => {
parseAndAssertSame('function F() { import a from "a"; }');
}, /SyntaxError: 'import' and 'export' may only appear at the top level/);
});
it("return outside function", () => {
parseAndAssertSame("return;");
});
it("super outside method", () => {
assert.throws(() => {
parseAndAssertSame("function F() { super(); }");
}, /SyntaxError: 'super' keyword outside a method/);
});
it("StringLiteral", () => {
parseAndAssertSame("");
parseAndAssertSame("");
parseAndAssertSame("a");
});
it("getters and setters", () => {
parseAndAssertSame("class A { get x ( ) { ; } }");
parseAndAssertSame(`
class A {
get x(
)
{
;
}
}
`);
parseAndAssertSame("class A { set x (a) { ; } }");
parseAndAssertSame(`
class A {
set x(a
)
{
;
}
}
`);
parseAndAssertSame(`
var B = {
get x () {
return this.ecks;
},
set x (ecks) {
this.ecks = ecks;
}
};
`);
});
it("RestOperator", () => {
parseAndAssertSame("var { a, ...b } = c");
parseAndAssertSame("var [ a, ...b ] = c");
parseAndAssertSame("var a = function (...b) {}");
});
it("SpreadOperator", () => {
parseAndAssertSame("var a = { b, ...c }");
parseAndAssertSame("var a = [ a, ...b ]");
parseAndAssertSame("var a = sum(...b)");
});
it("Async/Await", () => {
parseAndAssertSame(`
async function a() {
await 1;
}
`);
});
});
});

View File

@ -1,6 +0,0 @@
"use strict";
module.exports = {
presets: [["@babel/preset-env", { forceAllTransforms: true }]],
plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
};

View File

@ -1,21 +0,0 @@
"use strict";
module.exports = {
presets: [
["@babel/preset-env", { forceAllTransforms: true }],
["@babel/preset-flow", { all: true }],
"@babel/preset-react",
],
plugins: [
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
"@babel/plugin-syntax-export-default-from",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-syntax-numeric-separator",
"@babel/plugin-syntax-export-namespace-from",
["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: false }],
["@babel/plugin-proposal-pipeline-operator", { proposal: "minimal" }],
],
};

View File

@ -1,11 +0,0 @@
root: true
# babel-eslint
parser: ../../../lib/index.js
# use eslint-plugin-import
plugins:
- import
rules:
import/no-named-as-default: error
no-unused-vars: error

View File

@ -1 +0,0 @@
export default function foo() { }

View File

@ -1 +0,0 @@
import foo from './a.js';

View File

@ -1,4 +0,0 @@
// @flow
type Foo = {};
const FlowTypeButton = ({ }: Foo) => { };

View File

@ -1,3 +0,0 @@
function x () {
"use strict";
}

View File

@ -1 +0,0 @@
function x () {}

View File

@ -1,5 +0,0 @@
"use strict";
function x () {
"use strict";
}

View File

@ -1,3 +0,0 @@
"use strict";
function x () {}

View File

@ -1,6 +0,0 @@
"use strict";
/*
The empty statement is intentional. As of now, ESLint won't enforce
string: [2, "global"] on a program with an empty body. A test for that without
massaging the AST to ESlint's input format should fail.
*/

View File

@ -1 +0,0 @@
"no use strict anywhere";

View File

@ -1,6 +0,0 @@
class ClassName {
constructor() {
},
aMethod() {}
}

View File

@ -1,42 +0,0 @@
"use strict";
// Checks if the source ast implements the target ast. Ignores extra keys on source ast
module.exports = function assertImplementsAST(target, source, path) {
if (!path) {
path = [];
}
function error(text) {
const err = new Error(`At ${path.join(".")}: ${text}:`);
err.depth = path.length + 1;
throw err;
}
const typeA = target === null ? "null" : typeof target;
const typeB = source === null ? "null" : typeof source;
if (typeA !== typeB) {
error(
`have different types (${typeA} !== ${typeB}) (${target} !== ${source})`
);
} else if (
typeA === "object" &&
["RegExp"].indexOf(target.constructor.name) !== -1 &&
target.constructor.name !== source.constructor.name
) {
error(
`object have different constructors (${target.constructor.name} !== ${source.constructor.name}`
);
} else if (typeA === "object") {
const keysTarget = Object.keys(target);
for (const i in keysTarget) {
const key = keysTarget[i];
path.push(key);
assertImplementsAST(target[key], source[key], path);
path.pop();
}
} else if (target !== source) {
error(
`are different (${JSON.stringify(target)} !== ${JSON.stringify(source)})`
);
}
};

View File

@ -1,238 +0,0 @@
"use strict";
const eslint = require("eslint");
const fs = require("fs");
const path = require("path");
const parser = require("../");
eslint.linter.defineParser("current-babel-eslint", parser);
const paths = {
fixtures: path.join(__dirname, "fixtures", "rules"),
};
const encoding = "utf8";
const errorLevel = 2;
const baseEslintOpts = {
parser: "current-babel-eslint",
parserOptions: {
sourceType: "script",
},
};
/**
* Load a fixture and run eslint.linter.verify() on it.
* Pass the return value to done().
* @param object opts
* @param function done
*/
function lint(opts, done) {
readFixture(opts.fixture, (err, src) => {
if (err) return done(err);
done(null, eslint.linter.verify(src, opts.eslint));
});
}
/**
* Read a fixture file, passing the content to done().
* @param string|array id
* @param function done
*/
function readFixture(id, done) {
if (Array.isArray(id)) id = path.join.apply(path, id);
if (!path.extname(id)) id += ".js";
fs.readFile(path.join(paths.fixtures, id), encoding, done);
}
// readFixture
describe("Rules:", () => {
describe("`strict`", strictSuite);
});
// describe
function strictSuite() {
const ruleId = "strict";
describe("when set to 'never'", () => {
const eslintOpts = Object.assign({}, baseEslintOpts, {
rules: {},
});
eslintOpts.rules[ruleId] = [errorLevel, "never"];
["global-with", "function-with"].forEach(fixture => {
it(`should error on ${fixture.match(/^[^-]+/)[0]} directive`, done => {
lint(
{
fixture: ["strict", fixture],
eslint: eslintOpts,
},
(err, report) => {
if (err) return done(err);
expect(report[0].ruleId).toBe(ruleId);
done();
}
);
});
// it
});
});
// describe
describe("when set to 'global'", () => {
const eslintOpts = Object.assign({}, baseEslintOpts, {
rules: {},
});
eslintOpts.rules[ruleId] = [errorLevel, "global"];
it("shouldn't error on single global directive", done => {
lint(
{
fixture: ["strict", "global-with"],
eslint: eslintOpts,
},
(err, report) => {
if (err) return done(err);
expect(report.length).toBe(0);
done();
}
);
});
// it
it("should error twice on global directive: no and function directive: yes", done => {
lint(
{
fixture: ["strict", "function-with"],
eslint: eslintOpts,
},
(err, report) => {
if (err) return done(err);
[0, 1].forEach(i => {
expect(report[0].ruleId).toBe(ruleId);
});
done();
}
);
});
// it
it("should error on function directive", done => {
lint(
{
fixture: ["strict", "global-with-function-with"],
eslint: eslintOpts,
},
(err, report) => {
if (err) return done(err);
expect(report[0].ruleId).toBe(ruleId);
// This is to make sure the test fails prior to adapting Babel AST
// directive representation to ESLint format. Otherwise it reports an
// error for missing global directive that masquerades as the expected
// result of the previous assertion.
expect(report[0].nodeType).not.toBe("Program");
done();
}
);
});
// it
it("should error on no directive", done => {
lint(
{
fixture: ["strict", "none"],
eslint: eslintOpts,
},
(err, report) => {
if (err) return done(err);
expect(report[0].ruleId).toBe(ruleId);
done();
}
);
});
// it
});
// describe
describe("when set to 'function'", () => {
const eslintOpts = Object.assign({}, baseEslintOpts, {
rules: {},
});
eslintOpts.rules[ruleId] = [errorLevel, "function"];
it("shouldn't error on single function directive", done => {
lint(
{
fixture: ["strict", "function-with"],
eslint: eslintOpts,
},
(err, report) => {
if (err) return done(err);
expect(report.length).toBe(0);
done();
}
);
});
// it
it("should error twice on function directive: no and global directive: yes", done => {
lint(
{
fixture: ["strict", "global-with-function-without"],
eslint: eslintOpts,
},
(err, report) => {
if (err) return done(err);
[0, 1].forEach(i => {
expect(report[i].ruleId).toBe(ruleId);
});
done();
}
);
});
// it
it("should error on only global directive", done => {
lint(
{
fixture: ["strict", "global-with"],
eslint: eslintOpts,
},
(err, report) => {
if (err) return done(err);
expect(report[0].ruleId).toBe(ruleId);
done();
}
);
});
// it
it("should error on extraneous global directive", done => {
lint(
{
fixture: ["strict", "global-with-function-with"],
eslint: eslintOpts,
},
(err, report) => {
if (err) return done(err);
expect(report[0].ruleId).toBe(ruleId);
expect(report[0].nodeType.indexOf("Function")).toBe(-1);
done();
}
);
});
// it
});
}
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'];
let fileWithPath = files.map(file =>
path.resolve(__dirname, `./fixtures/eslint-plugin-import/${file}`));
engine.executeOnFiles(fileWithPath);
});
});

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +0,0 @@
src
test
.*
*.log

View File

@ -1,38 +0,0 @@
# @babel/eslint-plugin-development
A set of eslint rules to enforce best practices in the development of Babel plugins.
## Installation
You'll first need to install [ESLint](http://eslint.org):
```
$ npm install --save-dev eslint
```
Next, install `@babel/eslint-plugin-development`:
```
$ npm install --save-dev @babel/eslint-plugin-development
```
Then, load the plugin in your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
```json
{
"plugins": ["@babel/development"]
}
```
## Supported Rules
> Note: Rules marked with :wrench: are autofixable.
* `@babel/development/no-deprecated-clone` (:wrench:): Disallows using the deprecated
`t.clone(node)` and `t.cloneDeep(node)` methods from `@babel/types`. Those
calls are replaced with `t.cloneNode(node)` when using `eslint --fix`.
* `@babel/development/no-undefined-identifier`: Disallows using
`t.identifier("undefined")` to create a node which represents an `undefined`
value, since it might cause problem if `undefined` is redeclared.
* `@babel/development/plugin-name`: Requires plugins to have a `name` property, which
can be useful for debugging purposes.

View File

@ -1,31 +0,0 @@
{
"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.",
"private": true,
"keywords": [
"eslint",
"eslintplugin",
"eslint-plugin"
],
"author": {
"name": "Nicolò Ribaudo",
"email": "nicolo.ribaudo@gmail.com",
"url": "https://github.com/nicolo-ribaudo"
},
"main": "lib/index.js",
"devDependencies": {
"eslint": "^5.9.0"
},
"engines": {
"node": ">=8.0.0"
},
"publishConfig": {
"access": "public"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/babel/eslint-plugin-babel-plugin.git"
}
}

View File

@ -1,9 +0,0 @@
"use strict";
module.exports = {
rules: {
"no-deprecated-clone": require("./rules/no-deprecated-clone"),
"no-undefined-identifier": require("./rules/no-undefined-identifier"),
"plugin-name": require("./rules/plugin-name"),
},
};

View File

@ -1,41 +0,0 @@
"use strict";
const getReferenceOrigin = require("../utils/get-reference-origin");
const isFromBabelTypes = require("../utils/is-from-babel-types");
module.exports = {
meta: {
schema: [],
fixable: "code",
},
create(context) {
return {
CallExpression(node) {
const { callee } = node;
const scope = context.getScope();
const origin = getReferenceOrigin(callee, scope);
if (!origin) return;
const { name } = origin;
if (
(name === "clone" || name === "cloneDeep") &&
isFromBabelTypes(origin, scope)
) {
const isMemberExpression = callee.type === "MemberExpression";
const id = isMemberExpression ? callee.property : callee;
context.report({
node: id,
message: `t.${name}() is deprecated. Use t.cloneNode() instead.`,
fix(fixer) {
if (isMemberExpression) {
return fixer.replaceText(id, "cloneNode");
}
},
});
}
},
};
},
};

View File

@ -1,41 +0,0 @@
"use strict";
const getReferenceOrigin = require("../utils/get-reference-origin");
const isFromBabelTypes = require("../utils/is-from-babel-types");
function firstArgumentIsUndefinedString(argumentsArray) {
return (
argumentsArray.length > 0 &&
argumentsArray[0].type === "Literal" &&
argumentsArray[0].value === "undefined"
);
}
module.exports = {
meta: {
schema: [],
},
create(context) {
return {
CallExpression(node) {
const { callee } = node;
const scope = context.getScope();
const origin = getReferenceOrigin(callee, scope);
if (!origin) return;
const { name } = origin;
if (
(name === "identifier" || name === "Identifier") &&
firstArgumentIsUndefinedString(node.arguments) &&
isFromBabelTypes(origin, scope)
) {
context.report(
node,
"Use path.scope.buildUndefinedNode() to create an undefined identifier directly.",
);
}
},
};
},
};

View File

@ -1,52 +0,0 @@
"use strict";
const isBabelPluginFactory = require("../utils/is-babel-plugin-factory");
function getReturnValue(node) {
const { body } = node;
if (body.type === "BlockStatement") {
const returnNode = body.body.find(n => n.type === "ReturnStatement");
return returnNode && returnNode.argument;
}
// Arrow functions with implicit return
return body;
}
module.exports = {
meta: {
schema: [],
},
create(context /*: Context */) {
let pluginFound = false;
return {
FunctionDeclaration: functionVisitor,
FunctionExpression: functionVisitor,
ArrowFunctionExpression: functionVisitor,
"Program:exit"(node) {
if (!pluginFound) {
context.report(node, "This file does not export a Babel plugin.");
}
},
};
function functionVisitor(node) {
if (!isBabelPluginFactory(node, context.getScope())) return;
const returnValue = getReturnValue(node);
if (!returnValue || returnValue.type !== "ObjectExpression") return;
pluginFound = true;
if (!returnValue.properties.some(p => p.key.name === "name")) {
context.report(
returnValue,
"This Babel plugin doesn't have a 'name' property.",
);
}
}
},
};

View File

@ -1,24 +0,0 @@
"use strict";
module.exports = function getExportName(node) {
const { parent } = node;
if (parent.type === "ExportDefaultDeclaration") {
return "default";
}
if (parent.type === "ExportNamedDeclaration") {
return node.id.name;
}
if (
parent.type === "AssignmentExpression" &&
parent.left.type === "MemberExpression" &&
parent.left.object.type === "Identifier" &&
parent.left.object.name === "module" &&
parent.left.property.type === "Identifier" &&
parent.left.property.name === "exports"
) {
return "module.exports";
}
};

View File

@ -1,142 +0,0 @@
"use strict";
module.exports = getReferenceOrigin;
/*::
type ReferenceOriginImport = { kind: "import", source: string, name: string };
type ReferenceOriginParam = {
kind: "param",
index: number,
functionNode: Node,
};
type ReferenceOrigin =
| ReferenceOriginImport
| ReferenceOriginParam
| { kind: "import *", source: string }
| {
kind: "property",
base: ReferenceOriginImport | ReferenceOriginParam,
path: string,
name: string,
};
*/
// Given a node and a context, returns a description of where its value comes
// from.
// It resolves imports, parameters of exported functions and property accesses.
// See the ReferenceOrigin type for more informations.
function getReferenceOrigin(node, scope) /*: ?ReferenceOrigin */ {
if (node.type === "Identifier") {
const variable = getVariableDefinition(node.name, scope);
if (!variable) return null;
const definition = variable.definition;
const defNode = definition.node;
if (definition.type === "ImportBinding") {
if (defNode.type === "ImportSpecifier") {
return {
kind: "import",
source: definition.parent.source.value,
name: defNode.imported.name,
};
}
if (defNode.type === "ImportNamespaceSpecifier") {
return {
kind: "import *",
source: definition.parent.source.value,
};
}
}
if (definition.type === "Variable" && defNode.init) {
const origin = getReferenceOrigin(defNode.init, variable.scope);
return origin && patternToProperty(definition.name, origin);
}
if (definition.type === "Parameter") {
return patternToProperty(definition.name, {
kind: "param",
index: definition.index,
functionNode: definition.node,
});
}
}
if (node.type === "MemberExpression" && !node.computed) {
const origin = getReferenceOrigin(node.object, scope);
return origin && addProperty(origin, node.property.name);
}
return null;
}
function getVariableDefinition(name, scope) {
let currentScope = scope;
do {
const variable = currentScope.set.get(name);
if (variable && variable.defs[0]) {
return { scope: currentScope, definition: variable.defs[0] };
}
} while ((currentScope = currentScope.upper));
}
function patternToProperty(id, base) {
const path = getPatternPath(id);
return path && path.reduce(addProperty, base);
}
// Adds a property to a given origin. If it was a namespace import it becomes
// a named import, so that `import * as x from "foo"; x.bar` and
// `import { bar } from "foo"` have the same origin.
function addProperty(origin, name) {
if (origin.kind === "import *") {
return {
kind: "import",
source: origin.source,
name,
};
}
if (origin.kind === "property") {
return {
kind: "property",
base: origin.base,
path: origin.path + "." + name,
name,
};
}
return {
kind: "property",
base: origin,
path: name,
name,
};
}
// if "node" is c of { a: { b: c } }, the result is ["a","b"]
function getPatternPath(node) {
let current = node;
const path = [];
// Unshift keys to path while going up
do {
const property = current.parent;
if (
property.type === "ArrayPattern" ||
property.type === "AssignmentPattern" ||
property.computed
) {
// These nodes are not supported.
return null;
}
if (property.type === "Property") {
path.unshift(property.key.name);
} else {
// The destructuring pattern is finished
break;
}
} while ((current = current.parent.parent));
return path;
}

View File

@ -1,26 +0,0 @@
"use strict";
const getReferenceOrigin = require("./get-reference-origin");
const getExportName = require("./get-export-name");
module.exports = function isBabelPluginFactory(node, scope) {
const { parent } = node;
if (parent.type === "CallExpression") {
const calleeOrigin = getReferenceOrigin(parent.callee, scope);
// Using "declare" from "@babel/helper-plugin-utils"
return !!(
calleeOrigin &&
calleeOrigin.kind === "import" &&
calleeOrigin.name === "declare" &&
calleeOrigin.source === "@babel/helper-plugin-utils"
);
}
const exportName = getExportName(node);
// export default function ({ types: t }) {}
// module.exports = function ({ types: t }) {}
return exportName === "default" || exportName === "module.exports";
};

View File

@ -1,35 +0,0 @@
"use strict";
const isBabelPluginFactory = require("./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(
origin /*: ReferenceOrigin */,
scope /*: Scope */,
) {
if (origin.kind === "import" && origin.source === "@babel/types") {
// imported from @babel/types
return true;
}
if (
origin.kind === "property" &&
origin.base.kind === "import" &&
origin.base.name === "types" &&
origin.base.source === "@babel/core"
) {
// imported from @babel/core
return true;
}
if (
origin.kind === "property" &&
origin.base.kind === "param" &&
origin.base.index === 0
) {
return isBabelPluginFactory(origin.base.functionNode, scope);
}
return false;
};

View File

@ -1,138 +0,0 @@
"use strict";
const rule = require("../../src/rules/no-deprecated-clone");
const { RuleTester } = require("eslint");
const cloneError = "t.clone() is deprecated. Use t.cloneNode() instead.";
const cloneDeepError =
"t.cloneDeep() is deprecated. Use t.cloneNode() instead.";
const ruleTester = new RuleTester({
parserOptions: { sourceType: "module" },
});
ruleTester.run("no-deprecated-clone", rule, {
valid: [
`_.clone(obj)`,
`_.cloneDeep(obj)`,
`import * as t from "lib"; t.clone();`,
`import * as t from "lib"; t.cloneDeep();`,
`function f(_) { _.types.clone(); }`,
`function f(_) { _.types.cloneDeep(); }`,
`import * as t from "@babel/types"; t.cloneNode();`,
],
invalid: [
{
code: `import { clone } from "@babel/types"; clone();`,
errors: [cloneError],
},
{
code: `import { cloneDeep } from "@babel/types"; cloneDeep();`,
errors: [cloneDeepError],
},
{
code: `import { clone } from "@babel/types"; var clone2 = clone; clone2();`,
errors: [cloneError],
},
{
code: `import { cloneDeep } from "@babel/types"; var cloneDeep2 = cloneDeep; cloneDeep2();`,
errors: [cloneDeepError],
},
{
code: `import * as t from "@babel/types"; t.clone();`,
errors: [cloneError],
},
{
code: `import * as t from "@babel/types"; t.cloneDeep();`,
errors: [cloneDeepError],
},
{
code: `import * as t from "@babel/types"; var { clone } = t; clone();`,
errors: [cloneError],
},
{
code: `import * as t from "@babel/types"; var { cloneDeep } = t; cloneDeep();`,
errors: [cloneDeepError],
},
{
code: `import { clone as c } from "@babel/types"; c();`,
errors: [cloneError],
},
{
code: `import { cloneDeep as cD } from "@babel/types"; cD();`,
errors: [cloneDeepError],
},
{
code: `import * as babel from "@babel/core"; babel.types.clone();`,
errors: [cloneError],
},
{
code: `import * as babel from "@babel/core"; babel.types.cloneDeep();`,
errors: [cloneDeepError],
},
{
code: `import { types } from "@babel/core"; types.clone();`,
errors: [cloneError],
},
{
code: `import { types } from "@babel/core"; types.cloneDeep();`,
errors: [cloneDeepError],
},
{
code: `import { types as t } from "@babel/core"; t.clone();`,
errors: [cloneError],
},
{
code: `import { types as t } from "@babel/core"; t.cloneDeep();`,
errors: [cloneDeepError],
},
{
code: `export default function plugin(babel) { babel.types.clone() }`,
errors: [cloneError],
},
{
code: `export default function plugin(babel) { babel.types.cloneDeep() }`,
errors: [cloneDeepError],
},
{
code: `export default function plugin({ types }) { types.clone() }`,
errors: [cloneError],
},
{
code: `export default function plugin({ types }) { types.cloneDeep() }`,
errors: [cloneDeepError],
},
{
code: `export default function plugin({ types: t }) { t.clone() }`,
errors: [cloneError],
},
{
code: `export default function plugin({ types: t }) { t.cloneDeep() }`,
errors: [cloneDeepError],
},
{
code: `export default ({ types }) => { types.clone() }`,
errors: [cloneError],
},
{
code: `export default ({ types }) => { types.cloneDeep() }`,
errors: [cloneDeepError],
},
{
code: `module.exports = function plugin({ types }) { types.clone() }`,
errors: [cloneError],
},
{
code: `module.exports = function plugin({ types }) { types.cloneDeep() }`,
errors: [cloneDeepError],
},
{
code: `import { declare } from "@babel/helper-plugin-utils"; declare(({ types }) => { types.clone() });`,
errors: [cloneError],
},
{
code: `import { declare } from "@babel/helper-plugin-utils"; declare(({ types }) => { types.cloneDeep() });`,
errors: [cloneDeepError],
},
],
});

View File

@ -1,80 +0,0 @@
"use strict";
const rule = require("../../src/rules/no-undefined-identifier");
const { RuleTester } = require("eslint");
const error =
"Use path.scope.buildUndefinedNode() to create an undefined identifier directly.";
const ruleTester = new RuleTester({
parserOptions: { sourceType: "module" },
});
ruleTester.run("no-undefined-identifier", rule, {
valid: [
`_.identifier("undefined")`,
`_.Identifier("undefined")`,
`import * as t from "lib"; t.identifier("undefined");`,
`function f(_) { _.types.identifier("undefined"); }`,
`import * as t from "@babel/types"; t.identifier("not_undefined");`,
`path.scope.buildUndefinedNode();`,
],
invalid: [
{
code: `import { identifier } from "@babel/types"; identifier("undefined");`,
errors: [error],
},
{
code: `import { Identifier } from "@babel/types"; Identifier("undefined");`,
errors: [error],
},
{
code: `import * as t from "@babel/types"; t.identifier("undefined");`,
errors: [error],
},
{
code: `import * as t from "@babel/types"; var { identifier } = t; identifier("undefined");`,
errors: [error],
},
{
code: `import { identifier as id } from "@babel/types"; id("undefined");`,
errors: [error],
},
{
code: `import * as babel from "@babel/core"; babel.types.identifier("undefined");`,
errors: [error],
},
{
code: `import { types } from "@babel/core"; types.identifier("undefined");`,
errors: [error],
},
{
code: `import { types as t } from "@babel/core"; t.identifier("undefined");`,
errors: [error],
},
{
code: `export default function plugin(babel) { babel.types.identifier("undefined") }`,
errors: [error],
},
{
code: `export default function plugin({ types }) { types.identifier("undefined") }`,
errors: [error],
},
{
code: `export default function plugin({ types: t }) { t.identifier("undefined") }`,
errors: [error],
},
{
code: `export default ({ types }) => { types.identifier("undefined") }`,
errors: [error],
},
{
code: `module.exports = function plugin({ types }) { types.identifier("undefined") }`,
errors: [error],
},
{
code: `import { declare } from "@babel/helper-plugin-utils"; declare(({ types }) => { types.identifier("undefined") });`,
errors: [error],
},
],
});

View File

@ -1,54 +0,0 @@
"use strict";
const rule = require("../../src/rules/plugin-name");
const { RuleTester } = require("eslint");
const missingPluginError = "This file does not export a Babel plugin.";
const missingNameError = "This Babel plugin doesn't have a 'name' property.";
const ruleTester = new RuleTester({
parserOptions: { sourceType: "module" },
});
ruleTester.run("plugin-name", rule, {
valid: [
`export default function () { return { name: "test-plugin" } }`,
`import { declare } from "@babel/helper-plugin-utils"; declare(() => { return { name: "test-plugin" } })`,
`import { declare } from "@babel/helper-plugin-utils"; declare(() => ({ name: "test-plugin" }))`,
`module.exports = function () { return { name: "foo" }; }`,
],
invalid: [
{
code: `function fn() { return { name: "foo" } }`,
errors: [missingPluginError],
},
{
code: `export function fn() { return { name: "foo" } }`,
errors: [missingPluginError],
},
{
code: `(function fn() { return { name: "foo" } })`,
errors: [missingPluginError],
},
{
code: `() => { return { name: "foo" } }`,
errors: [missingPluginError],
},
{
code: `export default function fn() {}`,
errors: [missingPluginError],
},
{
code: `export default function fn() { return {} }`,
errors: [missingNameError],
},
{
code: `import { declare } from "@babel/helper-plugin-utils"; declare(() => ({}))`,
errors: [missingNameError],
},
{
code: `module.exports = function () { return {} }`,
errors: [missingNameError],
},
],
});

View File

@ -1,4 +0,0 @@
src
test
.*
*.log

View File

@ -1,23 +0,0 @@
Copyright (c) 2014-2015 Jason Quense <jason@quense.me>
Original work by respective rule authors; copywrites noted in files.
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,67 +0,0 @@
# eslint-plugin-babel
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.
> Requires Node 4 or greater
### Install
```sh
npm install eslint-plugin-babel --save-dev
```
Load the plugin in your `.eslintrc` file:
```json
{
"plugins": [
"babel"
]
}
```
Finally enable all the rules you would like to use (remember to disable the
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
}
}
```
### Rules
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 |

View File

@ -1,38 +0,0 @@
{
"name": "eslint-plugin-babel",
"version": "5.3.0",
"description": "an eslint rule plugin companion to babel-eslint",
"main": "lib/index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/babel/eslint-plugin-babel.git"
},
"keywords": [
"babel",
"eslint",
"eslintplugin",
"eslint-plugin",
"babel-eslint"
],
"author": "Jason Quense @monasticpanic",
"license": "MIT",
"private": true,
"engines": {
"node": ">=4"
},
"bugs": {
"url": "https://github.com/babel/eslint-plugin-babel/issues"
},
"homepage": "https://github.com/babel/eslint-plugin-babel#readme",
"peerDependencies": {
"eslint": ">=4.0.0"
},
"dependencies": {
"eslint-rule-composer": "^0.3.0"
},
"devDependencies": {
"babel-eslint": "^8.2.2",
"eslint": "^4.19.1",
"lodash.clonedeep": "^4.5.0"
}
}

View File

@ -1,38 +0,0 @@
"use strict";
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"),
},
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,
},
};

View File

@ -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;
},
};
},
};

View File

@ -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;
},
};
},
};

View File

@ -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);
}
},
};
},
};

View File

@ -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;
},
};
},
};

View File

@ -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;
},
};
},
};

View File

@ -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;
},
};
},
};

View File

@ -1,19 +0,0 @@
"use strict";
const ruleComposer = require("eslint-rule-composer");
const eslint = require("eslint");
const newCapRule = new eslint.Linter().getRules().get("new-cap");
/**
* Returns whether a node is under a decorator or not.
* @param {ASTNode} node CallExpression node
* @returns {Boolean} Returns true if the node is under a decorator.
*/
function isDecorator(node) {
return node.parent.type === "Decorator";
}
module.exports = ruleComposer.filterReports(
newCapRule,
problem => !isDecorator(problem.node),
);

View File

@ -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;
},
};
},
};

View File

@ -1,21 +0,0 @@
"use strict";
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 => {
let inClassProperty = false;
let node = problem.node;
while (node) {
if (node.type === "ClassProperty" || node.type === "ClassPrivateProperty") {
inClassProperty = true;
return;
}
node = node.parent;
}
return !inClassProperty;
});

View File

@ -1,64 +0,0 @@
"use strict";
const ruleComposer = require("eslint-rule-composer");
const eslint = require("eslint");
const rule = new eslint.Linter().getRules().get("no-unused-expressions");
/**
* @param {ASTNode} node - any node
* @returns {boolean} whether the given node is either an IfStatement or an
* ExpressionStatement and is the last node in the body of a BlockStatement
*/
function isFinalStatementInBlockStatement(node) {
const parent = node.parent;
return (
/^(?:If|Expression)Statement$/.test(node.type) &&
parent.type === "BlockStatement" &&
parent.body[parent.body.length - 1] === node
);
}
/**
* @param {ASTNode} node - any node
* @returns {boolean} whether the given node represents an unbroken chain of
* tail ExpressionStatements and IfStatements within a DoExpression
*/
function isInDoStatement(node) {
if (!node) return false;
if (node.type === "DoExpression") return true;
// this is an `else if`
if (
node.type === "IfStatement" &&
node.parent &&
node.parent.type === "IfStatement"
) {
return isInDoStatement(node.parent);
}
if (isFinalStatementInBlockStatement(node)) {
return isInDoStatement(node.parent.parent);
}
return false;
}
/**
* @param {ASTNode} node - any node
* @returns {boolean} whether the given node is an optional call expression,
* see https://github.com/tc39/proposal-optional-chaining
*/
function isOptionalCallExpression(node) {
return (
!!node &&
node.type === "ExpressionStatement" &&
node.expression.type === "OptionalCallExpression"
);
}
module.exports = ruleComposer.filterReports(
rule,
problem =>
!isInDoStatement(problem.node) && !isOptionalCallExpression(problem.node),
);

View File

@ -1,27 +0,0 @@
"use strict";
const ruleComposer = require("eslint-rule-composer");
const eslint = require("eslint");
const objectCurlySpacingRule = new eslint.Linter()
.getRules()
.get("object-curly-spacing");
module.exports = ruleComposer.filterReports(
objectCurlySpacingRule,
(problem, metadata) => {
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;
}
return true;
},
);

View File

@ -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;
},
};
},
};

View File

@ -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;
});

View File

@ -1,123 +0,0 @@
"use strict";
const ruleComposer = require("eslint-rule-composer");
const eslint = require("eslint");
const semiRule = new eslint.Linter().getRules().get("semi");
const OPT_OUT_PATTERN = /^[-[(/+`]/; // One of [(/+-`
const isSemicolon = token => token.type === "Punctuator" && token.value === ";";
const isUnnecessarySemicolon = (context, lastToken) => {
if (!isSemicolon(lastToken)) {
return false;
}
const nextToken = context.getSourceCode().getTokenAfter(lastToken);
if (!nextToken) {
return true;
}
const lastTokenLine = lastToken.loc.end.line;
const nextTokenLine = nextToken.loc.start.line;
const isOptOutToken =
OPT_OUT_PATTERN.test(nextToken.value) &&
nextToken.value !== "++" &&
nextToken.value !== "--";
const isDivider = nextToken.value === "}" || nextToken.value === ";";
return (lastTokenLine !== nextTokenLine && !isOptOutToken) || isDivider;
};
const isOneLinerBlock = (context, node) => {
const nextToken = context.getSourceCode().getTokenAfter(node);
if (!nextToken || nextToken.value !== "}") {
return false;
}
const parent = node.parent;
return (
parent &&
parent.type === "BlockStatement" &&
parent.loc.start.line === parent.loc.end.line
);
};
const report = (context, node, missing) => {
const lastToken = context.getSourceCode().getLastToken(node);
let message,
fix,
loc = lastToken.loc;
if (!missing) {
message = "Missing semicolon.";
loc = loc.end;
fix = function(fixer) {
return fixer.insertTextAfter(lastToken, ";");
};
} else {
message = "Extra semicolon.";
loc = loc.start;
fix = function(fixer) {
return fixer.remove(lastToken);
};
}
context.report({
node,
loc,
message,
fix,
});
};
const semiRuleWithClassProperty = ruleComposer.joinReports([
semiRule,
context => ({
ClassProperty(node) {
const options = context.options[1];
const exceptOneLine = options && options.omitLastInOneLineBlock === true;
const sourceCode = context.getSourceCode();
const lastToken = sourceCode.getLastToken(node);
if (context.options[0] === "never") {
if (isUnnecessarySemicolon(context, lastToken)) {
report(context, node, true);
}
} else {
if (!isSemicolon(lastToken)) {
if (!exceptOneLine || !isOneLinerBlock(context, node)) {
report(context, node);
}
} else {
if (exceptOneLine && isOneLinerBlock(context, node)) {
report(context, node, true);
}
}
}
},
}),
]);
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;
},
);

View File

@ -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";
});

View File

@ -1,7 +0,0 @@
var RuleTester = require("eslint").RuleTester;
RuleTester.setDefaultConfig({
parser: 'babel-eslint'
});
module.exports = RuleTester;

View File

@ -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",
},
],
},
],
});

View File

@ -1,300 +0,0 @@
/**
* @fileoverview Tests for new-cap rule.
* @author Nicholas C. Zakas
*/
var rule = require("../../src/rules/new-cap"),
RuleTester = require("../helpers/RuleTester");
var 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.",
},
],
},
],
});

View File

@ -1,688 +0,0 @@
/**
* @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
//------------------------------------------------------------------------------
/**
* A constant value for non strict mode environment.
* @returns {void}
*/
function NORMAL(pattern) {
pattern.parserOptions.sourceType = "script";
}
/**
* A constant value for strict mode environment.
* This modifies pattern object to make strict mode.
* @param {Object} pattern - A pattern object to modify.
* @returns {void}
*/
function USE_STRICT(pattern) {
pattern.code = '"use strict"; ' + pattern.code;
}
/**
* A constant value for implied strict mode.
* This modifies pattern object to impose strict mode.
* @param {Object} pattern - A pattern object to modify.
* @returns {void}
*/
function IMPLIED_STRICT(pattern) {
pattern.code = "/* implied strict mode */ " + pattern.code;
pattern.parserOptions.ecmaFeatures = pattern.parserOptions.ecmaFeatures || {};
pattern.parserOptions.ecmaFeatures.impliedStrict = true;
}
/**
* A constant value for modules environment.
* This modifies pattern object to make modules.
* @param {Object} pattern - A pattern object to modify.
* @returns {void}
*/
function MODULES(pattern) {
pattern.code = "/* modules */ " + pattern.code;
}
/**
* Extracts patterns each condition for a specified type. The type is `valid` or `invalid`.
* @param {Object[]} patterns - Original patterns.
* @param {string} type - One of `"valid"` or `"invalid"`.
* @returns {Object[]} Test patterns.
*/
function extractPatterns(patterns, type) {
// Clone and apply the pattern environment.
const patternsList = patterns.map(function(pattern) {
return pattern[type].map(function(applyCondition) {
const thisPattern = cloneDeep(pattern);
applyCondition(thisPattern);
if (type === "valid") {
thisPattern.errors = [];
} else {
thisPattern.code += " /* should error */";
}
delete thisPattern.invalid;
delete thisPattern.valid;
return thisPattern;
});
});
// Flatten.
return Array.prototype.concat.apply([], patternsList);
}
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
const errors = [
{ message: "Unexpected 'this'.", type: "ThisExpression" },
{ message: "Unexpected 'this'.", type: "ThisExpression" },
];
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.
{
code: "class A {a = this.b;};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code: "class A {a = () => {return this.b;};};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
// Class Private Instance Properties.
{
code: "class A {#a = this.b;};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code: "class A {#a = () => {return this.b;};};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
];
const ruleTester = new RuleTester();
ruleTester.run("no-invalid-this", rule, {
valid: extractPatterns(patterns, "valid"),
invalid: extractPatterns(patterns, "invalid"),
});

View File

@ -1,390 +0,0 @@
/**
* @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
//------------------------------------------------------------------------------
const ruleTester = new RuleTester();
ruleTester.run("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; }",
"let a = do { (foo + 1); }",
"let a = do { if (foo) { if (foo.bar) { foo.bar; } } }",
"let a = do { if (foo) { if (foo.bar) { foo.bar; } else if (foo.baz) { foo.baz; } } }",
"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: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "let a = do { if (foo) { foo.bar } else { a; bar.foo } }",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
],
});

File diff suppressed because it is too large Load Diff

View File

@ -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,
},
],
},
],
});

View File

@ -1,695 +0,0 @@
/* eslnit-disable */
/**
* @fileoverview Tests for semi rule.
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const rule = require("../../src/rules/semi"),
RuleTester = require("../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"
{ 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." }],
},
{
code: "class Foo { static bar = 'example' }",
errors: [{ message: "Missing semicolon." }],
},
{
code: "class Foo { bar = () => {} }",
options: ["always", { omitLastInOneLineBlock: true }],
errors: [{ message: "Missing semicolon." }],
},
// babel, "never"
{
code: "class Foo { bar = 'example'; }",
options: ["never"],
errors: [{ message: "Extra semicolon." }],
},
{
code: "class Foo { static bar = 'example'; }",
options: ["never"],
errors: [{ message: "Extra semicolon." }],
},
{
code: "class Foo { bar = () => {}; }",
options: ["never"],
errors: [{ message: "Extra semicolon." }],
},
],
});

View File

@ -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" },
],
},
],
});

View File

@ -1,51 +0,0 @@
module.exports = {
collectCoverageFrom: [
"packages/*/src/**/*.mjs",
"packages/*/src/**/*.js",
"codemods/*/src/**/*.mjs",
"codemods/*/src/**/*.js",
"eslint/*/src/**/*.mjs",
"eslint/*/src/**/*.js",
],
// The eslint/* packages use ESLint v6, which has dropped support for Node v6.
// TODO: Remove this process.version check in Babel 8.
testRegex: `./(packages|codemods${
/^v6./u.test(process.version) ? "" : "|eslint"
})/[^/]+/test/.+\\.m?js$`,
testPathIgnorePatterns: [
"/node_modules/",
"/test/fixtures/",
"/test/debug-fixtures/",
"/babel-parser/test/expressions/",
"/test/tmp/",
"/test/__data__/",
"/test/helpers/",
"<rootDir>/test/warning\\.js",
"<rootDir>/build/",
"_browser\\.js",
],
testEnvironment: "node",
setupFilesAfterEnv: ["<rootDir>/test/testSetupFile.js"],
transformIgnorePatterns: [
"/node_modules/",
"<rootDir>/packages/babel-standalone/babel(\\.min)?\\.js",
"<rootDir>/packages/babel-preset-env-standalone/babel-preset-env(\\.min)?\\.js",
"/test/(fixtures|tmp|__data__)/",
"<rootDir>/(packages|codemods|eslint)/[^/]+/lib/",
],
coveragePathIgnorePatterns: [
"/node_modules/",
"<rootDir>/packages/babel-standalone/babel(\\.min)?\\.js",
"<rootDir>/packages/babel-preset-env-standalone/babel-preset-env(\\.min)?\\.js",
"/test/(fixtures|tmp|__data__)/",
],
modulePathIgnorePatterns: [
"/test/fixtures/",
"/test/tmp/",
"/test/__data__/",
"<rootDir>/build/",
],
moduleNameMapper: {
"^@babel/([a-zA-Z0-9_-]+)$": "<rootDir>/packages/babel-$1/",
},
};

View File

@ -1,5 +1,5 @@
{
"version": "7.7.4-csx.1",
"version": "7.7.3",
"changelog": {
"repo": "babel/babel",
"cacheDir": ".changelog",
@ -22,19 +22,19 @@
"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",
"# Until the ESLint packages version are aligned with Babel's, we ignore them",
"eslint/**"
"@(!(built-in-modules|built-ins|plugins|package)).json"
]
}
},
"packages": [
"codemods/*",
"eslint/*",
"packages/*"
],
"npmClient": "yarn",
"npmClientArgs": [
"--no-lockfile"
]
],
"publishConfig": {
"registry": "https://npm.cerxes.net"
}
}

View File

@ -9,20 +9,20 @@
"test": "make test"
},
"devDependencies": {
"@babel/cli": "^7.7.0",
"@babel/core": "^7.7.2",
"@babel/cli": "^7.6.0",
"@babel/core": "^7.6.0",
"@babel/eslint-plugin-development": "^1.0.1",
"@babel/plugin-proposal-class-properties": "^7.7.0",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@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-optional-chaining": "^7.6.0",
"@babel/plugin-transform-modules-commonjs": "^7.7.0",
"@babel/plugin-transform-runtime": "^7.6.2",
"@babel/preset-env": "^7.7.1",
"@babel/plugin-transform-modules-commonjs": "^7.6.0",
"@babel/plugin-transform-runtime": "^7.6.0",
"@babel/preset-env": "^7.6.0",
"@babel/preset-flow": "^7.0.0",
"@babel/register": "^7.7.0",
"@babel/runtime": "^7.7.2",
"@babel/register": "^7.6.0",
"@babel/runtime": "^7.6.0",
"babel-eslint": "^11.0.0-beta.0",
"babel-jest": "^24.9.0",
"babel-loader": "^8.0.6",
@ -52,12 +52,12 @@
"gulp-watch": "^5.0.1",
"husky": "^3.0.0",
"jest": "^24.9.0",
"lerna": "^3.19.0",
"lerna": "^3.16.0",
"lerna-changelog": "^0.5.0",
"lint-staged": "^9.2.0",
"lodash": "^4.17.13",
"output-file-sync": "^2.0.0",
"prettier": "^1.19.1",
"prettier": "^1.17.1",
"pump": "^3.0.0",
"rimraf": "^2.6.3",
"rollup": "^1.12.0",
@ -89,5 +89,53 @@
"hooks": {
"pre-commit": "lint-staged"
}
},
"jest": {
"collectCoverageFrom": [
"packages/*/src/**/*.mjs",
"packages/*/src/**/*.js",
"codemods/*/src/**/*.mjs",
"codemods/*/src/**/*.js"
],
"testRegex": "./(packages|codemods)/[^/]+/test/.+\\.m?js$",
"testPathIgnorePatterns": [
"/node_modules/",
"/test/fixtures/",
"/test/debug-fixtures/",
"/babel-parser/test/expressions/",
"/test/tmp/",
"/test/__data__/",
"/test/helpers/",
"<rootDir>/test/warning\\.js",
"<rootDir>/build/",
"_browser\\.js"
],
"testEnvironment": "node",
"setupFilesAfterEnv": [
"<rootDir>/test/testSetupFile.js"
],
"transformIgnorePatterns": [
"/node_modules/",
"/packages/babel-standalone/babel.js",
"<rootDir>/packages/babel-standalone/babel(\\.min)?\\.js",
"<rootDir>/packages/babel-preset-env-standalone/babel-preset-env(\\.min)?\\.js",
"/test/(fixtures|tmp|__data__)/",
"<rootDir>/(packages|codemods)/[^/]+/lib/"
],
"coveragePathIgnorePatterns": [
"/node_modules/",
"<rootDir>/packages/babel-standalone/babel(\\.min)?\\.js",
"<rootDir>/packages/babel-preset-env-standalone/babel-preset-env(\\.min)?\\.js",
"/test/(fixtures|tmp|__data__)/"
],
"modulePathIgnorePatterns": [
"/test/fixtures/",
"/test/tmp/",
"/test/__data__/",
"<rootDir>/build/"
],
"moduleNameMapper": {
"^@babel/([a-zA-Z0-9_-]+)$": "<rootDir>/packages/babel-$1/"
}
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@babel/cli",
"version": "7.7.4-csx.1",
"version": "7.7.0",
"description": "Babel command line.",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
@ -19,7 +19,7 @@
"compiler"
],
"dependencies": {
"commander": "^4.0.1",
"commander": "^2.8.1",
"convert-source-map": "^1.1.0",
"fs-readdir-recursive": "^1.1.0",
"glob": "^7.0.0",
@ -35,7 +35,7 @@
"@babel/core": "^7.0.0-0 || csx"
},
"devDependencies": {
"@babel/core": "^7.7.4",
"@babel/core": "^7.7.0",
"@babel/helper-fixtures": "^7.6.3"
},
"bin": {

View File

@ -145,7 +145,7 @@ export default async function({
if (cliOptions.watch) {
const chokidar = util.requireChokidar();
filenames.forEach(function(filenameOrDir: string): void {
filenames.forEach(function(filenameOrDir) {
const watcher = chokidar.watch(filenameOrDir, {
persistent: true,
ignoreInitial: true,
@ -155,8 +155,8 @@ export default async function({
},
});
["add", "change"].forEach(function(type: string): void {
watcher.on(type, function(filename: string): void {
["add", "change"].forEach(function(type) {
watcher.on(type, function(filename) {
handleFile(
filename,
filename === filenameOrDir

Some files were not shown because too many files have changed in this diff Show More