Skip to content

Commit a93f47d

Browse files
authored
Change parser (#6)
* Change parser - Change parser to allow static template literals. - Change parser to allow undefined identifier. - Change parser to allow empty slots in array literals. - Change parser to allow spaces after `-`/`+` sign. - Change parser to allow number property key. - Change parser to allow regexp literal. - Change parser to allow bigint literal. - Change parser to parse all extensions (not only `.json`). * fix lint error * fix bigint test * fix test
1 parent b57bafd commit a93f47d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3664
-330
lines changed

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Also, [JSONC] and [JSON5], which are variants of [JSON], are more similar to Jav
2929

3030
### How does `eslint-plugin-jsonc` work?
3131

32-
This plugin parses `.json` with its own parser, but this parser just converts AST parsed by `espree` (ESLint standard parser) into AST with another name. However, AST that does not exist in [JSON] and [JSON5] will be reported as a parse error. By converting the AST to another name, we prevent false positives from ESLint standard rules.
32+
This plugin parses `.json` with its own parser, but this parser just converts AST parsed by `espree` (ESLint standard parser) into AST with another name. However, ASTs that do not exist in [JSON] and JSON-superset syntaxes are reported as parsing errors. By converting the AST to another name, we prevent false positives from ESLint core rules.
3333
Moreover, You can do the same linting using the extended rules of the ESLint core rules provided by this plugin.
3434

3535
<!--DOCS_IGNORE_START-->
@@ -54,8 +54,11 @@ npm install --save-dev eslint eslint-plugin-jsonc
5454
## Usage
5555

5656
<!--USAGE_SECTION_START-->
57+
<!--USAGE_GUIDE_START-->
5758

58-
Create `.eslintrc.*` file to configure rules. See also: [http://eslint.org/docs/user-guide/configuring](http://eslint.org/docs/user-guide/configuring).
59+
### Configuration
60+
61+
Use `.eslintrc.*` file to configure rules. See also: [https://eslint.org/docs/user-guide/configuring](https://eslint.org/docs/user-guide/configuring).
5962

6063
Example **.eslintrc.js**:
6164

@@ -73,8 +76,6 @@ module.exports = {
7376
}
7477
```
7578

76-
## Configs
77-
7879
This plugin provides configs:
7980

8081
- `plugin:jsonc/base` ... Configuration to enable correct JSON parsing.
@@ -83,7 +84,9 @@ This plugin provides configs:
8384
- `plugin:jsonc/recommended-with-json5` ... Recommended configuration for JSON5.
8485
- `plugin:jsonc/auto-config` ... Automatically apply jsonc rules similar to your configured ESLint core rules to JSON.
8586

86-
## Running ESLint from the command line
87+
See [the rule list](https://ota-meshi.github.io/eslint-plugin-jsonc/rules/) to get the `rules` that this plugin provides.
88+
89+
### Running ESLint from the command line
8790

8891
If you want to run `eslint` from the command line, make sure you include the `.json` extension using [the `--ext` option](https://eslint.org/docs/user-guide/configuring#specifying-file-extensions-to-lint) or a glob pattern, because ESLint targets only `.js` files by default.
8992

@@ -116,6 +119,7 @@ Example **.vscode/settings.json**:
116119
}
117120
```
118121

122+
<!--USAGE_GUIDE_END-->
119123
<!--USAGE_SECTION_END-->
120124

121125
## Rules

docs/.vuepress/components/components/EslintPluginEditor.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export default {
8787
parser: "json-eslint-parser",
8888
parserOptions: {
8989
sourceType: "script",
90-
ecmaVersion: 2019,
90+
ecmaVersion: 2020,
9191
},
9292
}
9393
},
@@ -121,7 +121,6 @@ export default {
121121
// Load linter asynchronously.
122122
const [{ default: eslint4b }, { parseForESLint }] = await Promise.all([
123123
import("eslint4b"),
124-
// eslint-disable-next-line @mysticatea/node/no-extraneous-import
125124
import("espree").then(() =>
126125
import("../../../../dist/parser/json-eslint-parser")
127126
),

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Also, [JSONC] and [JSON5], which are variants of [JSON], are more similar to Jav
2929

3030
### How does `eslint-plugin-jsonc` work?
3131

32-
This plugin parses `.json` with its own parser, but this parser just converts AST parsed by `espree` (ESLint standard parser) into AST with another name. However, AST that does not exist in [JSON] and [JSON5] will be reported as a parse error. By converting the AST to another name, we prevent false positives from ESLint standard rules.
32+
This plugin parses `.json` with its own parser, but this parser just converts AST parsed by `espree` (ESLint standard parser) into AST with another name. However, ASTs that do not exist in [JSON] and JSON-superset syntaxes are reported as parsing errors. By converting the AST to another name, we prevent false positives from ESLint core rules.
3333
Moreover, You can do the same linting using the extended rules of the ESLint core rules provided by this plugin.
3434

3535
## Usage

docs/user-guide/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ npm install --save-dev eslint eslint-plugin-jsonc
1313

1414
## Usage
1515

16+
<!--USAGE_GUIDE_START-->
17+
1618
### Configuration
1719

1820
Use `.eslintrc.*` file to configure rules. See also: [https://eslint.org/docs/user-guide/configuring](https://eslint.org/docs/user-guide/configuring).
@@ -75,3 +77,42 @@ Example **.vscode/settings.json**:
7577
]
7678
}
7779
```
80+
81+
<!--USAGE_GUIDE_END-->
82+
83+
## :question: FAQ
84+
85+
### How to parse files other than `.json` and `.json5`?
86+
87+
This plugin will parse `.json` and `.json5` using the configuration provided by the plugin.
88+
To parse other extensions, you need to add a setting to your configuration.
89+
90+
Example **.eslintrc.js**:
91+
92+
```js
93+
module.exports = {
94+
// ...
95+
// Add the following settings.
96+
overrides: [
97+
{
98+
files: ["*.json6"], // If you want to parse `.json6`
99+
parser: "eslint-plugin-jsonc", // Set this plugin as a parser.
100+
},
101+
],
102+
}
103+
```
104+
105+
If you want to apply `plugin:jsonc/auto-config` to files with this extension, add the following settings.
106+
107+
```diff
108+
module.exports = {
109+
// ...
110+
overrides: [
111+
{
112+
files: ["*.json6"],
113+
parser: "eslint-plugin-jsonc",
114+
+ processor: "jsonc/auto-config",
115+
},
116+
],
117+
}
118+
```

lib/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import recommendedWithJsonc from "./configs/recommended-with-jsonc"
88
import recommendedWithJson5 from "./configs/recommended-with-json5"
99
import { parseForESLint } from "./parser/json-eslint-parser"
1010
import { traverseNodes } from "./parser/traverse"
11+
import { getStaticJSONValue } from "./utils/ast"
1112

1213
const configs = {
1314
base,
@@ -32,4 +33,5 @@ export = {
3233

3334
// tools
3435
traverseNodes,
36+
getStaticJSONValue,
3537
}

lib/parser/ast.ts

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ export type JSONNode =
2828
| JSONExpression
2929
| JSONProperty
3030
| JSONIdentifier
31+
| JSONTemplateLiteral
32+
| JSONTemplateElement
3133
export interface JSONProgram extends BaseJSONNode {
3234
type: "Program"
3335
body: [JSONExpressionStatement]
@@ -48,10 +50,12 @@ export type JSONExpression =
4850
| JSONLiteral
4951
| JSONUnaryExpression
5052
| JSONNumberIdentifier
53+
| JSONUndefinedIdentifier
54+
| JSONTemplateLiteral
5155

5256
export interface JSONArrayExpression extends BaseJSONNode {
5357
type: "JSONArrayExpression"
54-
elements: JSONExpression[]
58+
elements: (JSONExpression | null)[]
5559
parent?: JSONArrayExpression | JSONProperty | JSONExpressionStatement
5660
}
5761

@@ -63,7 +67,7 @@ export interface JSONObjectExpression extends BaseJSONNode {
6367

6468
export interface JSONProperty extends BaseJSONNode {
6569
type: "JSONProperty"
66-
key: JSONIdentifier | JSONLiteral
70+
key: JSONIdentifier | JSONStringLiteral | JSONNumberLiteral
6771
value: JSONExpression
6872
kind: "init"
6973
method: false
@@ -86,9 +90,11 @@ export interface JSONNumberIdentifier extends JSONIdentifier {
8690
name: "Infinity" | "NaN"
8791
}
8892

89-
export interface JSONLiteral extends BaseJSONNode {
93+
export interface JSONUndefinedIdentifier extends JSONIdentifier {
94+
name: "undefined"
95+
}
96+
interface JSONLiteralBase extends BaseJSONNode {
9097
type: "JSONLiteral"
91-
value: string | boolean | number | null
9298
raw: string
9399
parent?:
94100
| JSONArrayExpression
@@ -97,16 +103,63 @@ export interface JSONLiteral extends BaseJSONNode {
97103
| JSONUnaryExpression
98104
}
99105

100-
export interface JSONNumberLiteral extends JSONLiteral {
101-
type: "JSONLiteral"
106+
export interface JSONStringLiteral extends JSONLiteralBase {
107+
value: string
108+
regex: null
109+
bigint: null
110+
}
111+
export interface JSONNumberLiteral extends JSONLiteralBase {
102112
value: number
103-
raw: string
113+
regex: null
114+
bigint: null
115+
}
116+
export interface JSONKeywordLiteral extends JSONLiteralBase {
117+
value: boolean | null
118+
regex: null
119+
bigint: null
120+
}
121+
export interface JSONRegExpLiteral extends JSONLiteralBase {
122+
value: null
123+
regex: {
124+
pattern: string
125+
flags: string
126+
}
127+
bigint: null
128+
}
129+
export interface JSONBigIntLiteral extends JSONLiteralBase {
130+
value: null
131+
regex: null
132+
bigint: string
104133
}
105134

135+
export type JSONLiteral =
136+
| JSONStringLiteral
137+
| JSONNumberLiteral
138+
| JSONKeywordLiteral
139+
| JSONRegExpLiteral
140+
| JSONBigIntLiteral
141+
106142
export interface JSONUnaryExpression extends BaseJSONNode {
107143
type: "JSONUnaryExpression"
108144
operator: "-" | "+"
109145
prefix: true
110146
argument: JSONNumberLiteral | JSONNumberIdentifier
111147
parent?: JSONArrayExpression | JSONProperty | JSONExpressionStatement
112148
}
149+
150+
export interface JSONTemplateLiteral extends BaseJSONNode {
151+
type: "JSONTemplateLiteral"
152+
quasis: [JSONTemplateElement]
153+
expressions: []
154+
parent?: JSONArrayExpression | JSONProperty | JSONExpressionStatement
155+
}
156+
157+
export interface JSONTemplateElement extends BaseJSONNode {
158+
type: "JSONTemplateElement"
159+
tail: boolean
160+
value: {
161+
cooked: string
162+
raw: string
163+
}
164+
parent?: JSONTemplateLiteral
165+
}

0 commit comments

Comments
 (0)