diff --git a/README.md b/README.md index 7e9cb446..8ca2bd38 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,7 @@ The rules with the following star :star: are included in the config. | [jsonc/no-dupe-keys](https://ota-meshi.github.io/eslint-plugin-jsonc/rules/no-dupe-keys.html) | disallow duplicate keys in object literals | | :star: | :star: | :star: | | [jsonc/no-multi-str](https://ota-meshi.github.io/eslint-plugin-jsonc/rules/no-multi-str.html) | disallow multiline strings | | :star: | :star: | | | [jsonc/no-octal-escape](https://ota-meshi.github.io/eslint-plugin-jsonc/rules/no-octal-escape.html) | disallow octal escape sequences in string literals | | | | | +| [jsonc/no-sparse-arrays](https://ota-meshi.github.io/eslint-plugin-jsonc/rules/no-sparse-arrays.html) | disallow sparse arrays | | :star: | :star: | :star: | | [jsonc/no-useless-escape](https://ota-meshi.github.io/eslint-plugin-jsonc/rules/no-useless-escape.html) | disallow unnecessary escape usage | | :star: | :star: | :star: | | [jsonc/object-curly-newline](https://ota-meshi.github.io/eslint-plugin-jsonc/rules/object-curly-newline.html) | enforce consistent line breaks inside braces | :wrench: | | | | | [jsonc/object-curly-spacing](https://ota-meshi.github.io/eslint-plugin-jsonc/rules/object-curly-spacing.html) | enforce consistent spacing inside braces | :wrench: | | | | diff --git a/docs/rules/README.md b/docs/rules/README.md index a84a2a23..645a7ade 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -32,6 +32,7 @@ The rules with the following star :star: are included in the `plugin:jsonc/recom | [jsonc/no-dupe-keys](./no-dupe-keys.md) | disallow duplicate keys in object literals | | :star: | :star: | :star: | | [jsonc/no-multi-str](./no-multi-str.md) | disallow multiline strings | | :star: | :star: | | | [jsonc/no-octal-escape](./no-octal-escape.md) | disallow octal escape sequences in string literals | | | | | +| [jsonc/no-sparse-arrays](./no-sparse-arrays.md) | disallow sparse arrays | | :star: | :star: | :star: | | [jsonc/no-useless-escape](./no-useless-escape.md) | disallow unnecessary escape usage | | :star: | :star: | :star: | | [jsonc/object-curly-newline](./object-curly-newline.md) | enforce consistent line breaks inside braces | :wrench: | | | | | [jsonc/object-curly-spacing](./object-curly-spacing.md) | enforce consistent spacing inside braces | :wrench: | | | | diff --git a/docs/rules/no-sparse-arrays.md b/docs/rules/no-sparse-arrays.md new file mode 100644 index 00000000..1b45b5b5 --- /dev/null +++ b/docs/rules/no-sparse-arrays.md @@ -0,0 +1,51 @@ +--- +pageClass: "rule-details" +sidebarDepth: 0 +title: "jsonc/no-sparse-arrays" +description: "disallow sparse arrays" +--- +# jsonc/no-sparse-arrays + +> disallow sparse arrays + +- :gear: This rule is included in all of `"plugin:jsonc/recommended-with-json"`, `"plugin:jsonc/recommended-with-json5"` and `"plugin:jsonc/recommended-with-jsonc"`. + +## :book: Rule Details + +This rule disallows sparse array literals which have "holes" where commas are not preceded by elements. It does not apply to a trailing comma following the last element. + +JSON, JSONC and JSON5 do not allow arrays contain empty slots. + + + +```json5 +/* eslint jsonc/no-sparse-arrays: 'error' */ +{ + /* ✓ GOOD */ + "GOOD": [1, 2, 3, 4], + "GOOD": [1, 2, 3, 4,], + + /* ✗ BAD */ + "BAD": [1, , , 4], + "BAD": [, 2, 3, 4] +} +``` + + + +## :wrench: Options + +Nothing. + +## :couple: Related rules + +- [no-sparse-arrays] + +[no-sparse-arrays]: https://eslint.org/docs/rules/no-sparse-arrays + +## Implementation + +- [Rule source](https://github.com/ota-meshi/eslint-plugin-jsonc/blob/master/lib/rules/no-sparse-arrays.ts) +- [Test source](https://github.com/ota-meshi/eslint-plugin-jsonc/blob/master/tests/lib/rules/no-sparse-arrays.js) + +Taken with ❤️ [from ESLint core](https://eslint.org/docs/rules/no-sparse-arrays) diff --git a/lib/configs/recommended-with-json.ts b/lib/configs/recommended-with-json.ts index dda6ff42..0e7653e2 100644 --- a/lib/configs/recommended-with-json.ts +++ b/lib/configs/recommended-with-json.ts @@ -10,6 +10,7 @@ export = { "jsonc/no-comments": "error", "jsonc/no-dupe-keys": "error", "jsonc/no-multi-str": "error", + "jsonc/no-sparse-arrays": "error", "jsonc/no-template-literals": "error", "jsonc/no-undefined-value": "error", "jsonc/no-useless-escape": "error", diff --git a/lib/configs/recommended-with-json5.ts b/lib/configs/recommended-with-json5.ts index 4dee377d..85619488 100644 --- a/lib/configs/recommended-with-json5.ts +++ b/lib/configs/recommended-with-json5.ts @@ -7,6 +7,7 @@ export = { rules: { // eslint-plugin-jsonc rules "jsonc/no-dupe-keys": "error", + "jsonc/no-sparse-arrays": "error", "jsonc/no-template-literals": "error", "jsonc/no-undefined-value": "error", "jsonc/no-useless-escape": "error", diff --git a/lib/configs/recommended-with-jsonc.ts b/lib/configs/recommended-with-jsonc.ts index fe69b15e..3f0db8dd 100644 --- a/lib/configs/recommended-with-jsonc.ts +++ b/lib/configs/recommended-with-jsonc.ts @@ -8,6 +8,7 @@ export = { // eslint-plugin-jsonc rules "jsonc/no-dupe-keys": "error", "jsonc/no-multi-str": "error", + "jsonc/no-sparse-arrays": "error", "jsonc/no-template-literals": "error", "jsonc/no-undefined-value": "error", "jsonc/no-useless-escape": "error", diff --git a/lib/rules/no-sparse-arrays.ts b/lib/rules/no-sparse-arrays.ts new file mode 100644 index 00000000..c21d7e13 --- /dev/null +++ b/lib/rules/no-sparse-arrays.ts @@ -0,0 +1,19 @@ +import coreRule from "eslint/lib/rules/no-sparse-arrays" +import { createRule, defineWrapperListener } from "../utils" + +export default createRule("no-sparse-arrays", { + meta: { + docs: { + description: "disallow sparse arrays", + recommended: ["json", "jsonc", "json5"], + extensionRule: true, + }, + fixable: coreRule.meta!.fixable, + schema: coreRule.meta!.schema!, + messages: coreRule.meta!.messages!, + type: coreRule.meta!.type!, + }, + create(context) { + return defineWrapperListener(coreRule, context, context.options) + }, +}) diff --git a/lib/utils/rules.ts b/lib/utils/rules.ts index 2f9892c8..4ae8b3a9 100644 --- a/lib/utils/rules.ts +++ b/lib/utils/rules.ts @@ -10,6 +10,7 @@ import noComments from "../rules/no-comments" import noDupeKeys from "../rules/no-dupe-keys" import noMultiStr from "../rules/no-multi-str" import noOctalEscape from "../rules/no-octal-escape" +import noSparseArrays from "../rules/no-sparse-arrays" import noTemplateLiterals from "../rules/no-template-literals" import noUndefinedValue from "../rules/no-undefined-value" import noUselessEscape from "../rules/no-useless-escape" @@ -33,6 +34,7 @@ export const rules = [ noDupeKeys, noMultiStr, noOctalEscape, + noSparseArrays, noTemplateLiterals, noUndefinedValue, noUselessEscape, diff --git a/tests/lib/rules/no-sparse-arrays.ts b/tests/lib/rules/no-sparse-arrays.ts new file mode 100644 index 00000000..c6c94074 --- /dev/null +++ b/tests/lib/rules/no-sparse-arrays.ts @@ -0,0 +1,20 @@ +import { RuleTester } from "eslint" +import rule from "../../../lib/rules/no-sparse-arrays" + +const tester = new RuleTester({ + parser: require.resolve("../../../lib/parser/json-eslint-parser"), +}) + +tester.run("no-sparse-arrays", rule as any, { + valid: ["[1,2,3,4]", "[1,2,3,4,]"], + invalid: [ + { + code: "[1,,,4]", + errors: ["Unexpected comma in middle of array."], + }, + { + code: "[,2,3,4]", + errors: ["Unexpected comma in middle of array."], + }, + ], +}) diff --git a/tools/new-rule.ts b/tools/new-rule.ts index 1c3bd8d8..a9109e7d 100644 --- a/tools/new-rule.ts +++ b/tools/new-rule.ts @@ -32,10 +32,10 @@ export default createRule("${ruleId}", { description: "...", recommended: true, }, - fixable: coreRule.meta?.fixable, - schema: coreRule.meta?.schema!, - messages: coreRule.meta?.messages!, - type: coreRule.meta?.type!, + fixable: coreRule.meta!.fixable, + schema: coreRule.meta!.schema!, + messages: coreRule.meta!.messages!, + type: coreRule.meta!.type!, }, create(context) { return defineWrapperListener(coreRule, context, context.options)