From 90ccc004ae6f91c5c9d53553f5e0fc789463db34 Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Thu, 8 Nov 2018 20:33:24 +0900 Subject: [PATCH 1/5] Breaking: switch 'jsx' option by filename (fixes #517) --- parser.js | 4 +++ tests/lib/tsx.js | 76 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/parser.js b/parser.js index 32b4e7c..411cb6b 100644 --- a/parser.js +++ b/parser.js @@ -20,6 +20,10 @@ const visitorKeys = require("./visitor-keys"); exports.version = require("./package.json").version; exports.parseForESLint = function parseForESLint(code, options) { + if (options && typeof options.filePath === "string" && options.filePath.endsWith(".tsx")) { + options.jsx = true; + } + const ast = parse(code, options); traverser.traverse(ast, { enter: node => { diff --git a/tests/lib/tsx.js b/tests/lib/tsx.js index 4fdf201..ff7eb01 100644 --- a/tests/lib/tsx.js +++ b/tests/lib/tsx.js @@ -11,8 +11,12 @@ // Requirements //------------------------------------------------------------------------------ -const path = require("path"), +const + assert = require("assert"), + path = require("path"), + { Linter } = require("eslint"), shelljs = require("shelljs"), + parser = require("../../"), testUtils = require("../../tools/test-utils"); //------------------------------------------------------------------------------ @@ -39,4 +43,74 @@ describe("TSX", () => { }; test(`fixtures/${filename}.src`, testUtils.createSnapshotTestBlock(code, config)); }); + + describe("if the filename ends with '.tsx', enable jsx option automatically.", () => { + const linter = new Linter(); + linter.defineParser("typescript-eslint-parser", parser); + + test("anonymous", () => { + const code = "const element = "; + const config = { + parser: "typescript-eslint-parser" + }; + const messages = linter.verify(code, config); + + assert.deepStrictEqual( + messages, + [{ + column: 18, + fatal: true, + line: 1, + message: "Parsing error: '>' expected.", + ruleId: null, + severity: 2, + source: "const element = " + }] + ); + }); + + test("test.ts", () => { + const code = "const element = "; + const config = { + parser: "typescript-eslint-parser" + }; + const messages = linter.verify(code, config, { filename: "test.ts" }); + + assert.deepStrictEqual( + messages, + [{ + column: 18, + fatal: true, + line: 1, + message: "Parsing error: '>' expected.", + ruleId: null, + severity: 2, + source: "const element = " + }] + ); + }); + + test("test.ts with 'jsx' option", () => { + const code = "const element = "; + const config = { + parser: "typescript-eslint-parser", + parserOptions: { + jsx: true + } + }; + const messages = linter.verify(code, config, { filename: "test.ts" }); + + assert.deepStrictEqual(messages, []); + }); + + test("test.tsx", () => { + const code = "const element = "; + const config = { + parser: "typescript-eslint-parser" + }; + const messages = linter.verify(code, config, { filename: "test.tsx" }); + + assert.deepStrictEqual(messages, []); + }); + }); }); From 0a48b03147c675eba9cb506c23f0abf2a2fcad36 Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Thu, 8 Nov 2018 20:38:49 +0900 Subject: [PATCH 2/5] update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 68c8dee..7183e57 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ By far the most common case will be installing the [eslint-plugin-typescript](ht The following additional configuration options are available by specifying them in [`parserOptions`](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) in your ESLint configuration file. -**`jsx`** - default `false`. Enable parsing JSX when `true`. More details can be found [here](https://www.typescriptlang.org/docs/handbook/jsx.html). +**`jsx`** - default `false`. It's `true` on `*.tsx` files automatically. Enable parsing JSX when `true`. More details can be found [here](https://www.typescriptlang.org/docs/handbook/jsx.html). **`useJSXTextNode`** - default `false`. The JSX AST changed the node type for string literals inside a JSX Element from `Literal` to `JSXText`. When value is `true`, these nodes will be parsed as type `JSXText`. When value is `false`, these nodes will be parsed as type `Literal`. From 98cbcf01bb501c2daa9add79e41377be269c8a00 Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Thu, 8 Nov 2018 20:43:02 +0900 Subject: [PATCH 3/5] don't modify the option object --- parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser.js b/parser.js index 411cb6b..7384bdf 100644 --- a/parser.js +++ b/parser.js @@ -21,7 +21,7 @@ exports.version = require("./package.json").version; exports.parseForESLint = function parseForESLint(code, options) { if (options && typeof options.filePath === "string" && options.filePath.endsWith(".tsx")) { - options.jsx = true; + options = Object.assign({}, options, { jsx: true }); } const ast = parse(code, options); From da5a810240a5368e240b8e94d6f47ab281d0b25b Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Fri, 9 Nov 2018 05:48:37 +0900 Subject: [PATCH 4/5] update behavior --- README.md | 7 +++++-- parser.js | 7 +++++-- tests/lib/tsx.js | 43 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7183e57..fd8d6bb 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,12 @@ By far the most common case will be installing the [eslint-plugin-typescript](ht The following additional configuration options are available by specifying them in [`parserOptions`](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) in your ESLint configuration file. -**`jsx`** - default `false`. It's `true` on `*.tsx` files automatically. Enable parsing JSX when `true`. More details can be found [here](https://www.typescriptlang.org/docs/handbook/jsx.html). +- **`jsx`** - default `false`. Enable parsing JSX when `true`. More details can be found [here](https://www.typescriptlang.org/docs/handbook/jsx.html). + - It's `false` on `*.ts` files regardless of this option. + - It's `true` on `*.tsx` files regardless of this option. + - Otherwise, it respects this option. -**`useJSXTextNode`** - default `false`. The JSX AST changed the node type for string literals inside a JSX Element from `Literal` to `JSXText`. When value is `true`, these nodes will be parsed as type `JSXText`. When value is `false`, these nodes will be parsed as type `Literal`. +- **`useJSXTextNode`** - default `false`. The JSX AST changed the node type for string literals inside a JSX Element from `Literal` to `JSXText`. When value is `true`, these nodes will be parsed as type `JSXText`. When value is `false`, these nodes will be parsed as type `Literal`. ### .eslintrc.json diff --git a/parser.js b/parser.js index 7384bdf..10d3063 100644 --- a/parser.js +++ b/parser.js @@ -20,8 +20,11 @@ const visitorKeys = require("./visitor-keys"); exports.version = require("./package.json").version; exports.parseForESLint = function parseForESLint(code, options) { - if (options && typeof options.filePath === "string" && options.filePath.endsWith(".tsx")) { - options = Object.assign({}, options, { jsx: true }); + if (options && typeof options.filePath === "string") { + const tsx = options.filePath.endsWith(".tsx"); + if (tsx || options.filePath.endsWith(".ts")) { + options = Object.assign({}, options, { jsx: tsx }); + } } const ast = parse(code, options); diff --git a/tests/lib/tsx.js b/tests/lib/tsx.js index ff7eb01..4152be3 100644 --- a/tests/lib/tsx.js +++ b/tests/lib/tsx.js @@ -48,7 +48,7 @@ describe("TSX", () => { const linter = new Linter(); linter.defineParser("typescript-eslint-parser", parser); - test("anonymous", () => { + test("filePath was not provided", () => { const code = "const element = "; const config = { parser: "typescript-eslint-parser" @@ -69,6 +69,19 @@ describe("TSX", () => { ); }); + test("filePath was not provided and 'jsx:true' option", () => { + const code = "const element = "; + const config = { + parser: "typescript-eslint-parser", + parserOptions: { + jsx: true + } + }; + const messages = linter.verify(code, config); + + assert.deepStrictEqual(messages, []); + }); + test("test.ts", () => { const code = "const element = "; const config = { @@ -90,7 +103,7 @@ describe("TSX", () => { ); }); - test("test.ts with 'jsx' option", () => { + test("test.ts with 'jsx:true' option", () => { const code = "const element = "; const config = { parser: "typescript-eslint-parser", @@ -100,7 +113,18 @@ describe("TSX", () => { }; const messages = linter.verify(code, config, { filename: "test.ts" }); - assert.deepStrictEqual(messages, []); + assert.deepStrictEqual( + messages, + [{ + column: 18, + fatal: true, + line: 1, + message: "Parsing error: '>' expected.", + ruleId: null, + severity: 2, + source: "const element = " + }] + ); }); test("test.tsx", () => { @@ -112,5 +136,18 @@ describe("TSX", () => { assert.deepStrictEqual(messages, []); }); + + test("test.tsx with 'jsx:false' option", () => { + const code = "const element = "; + const config = { + parser: "typescript-eslint-parser", + parserOptions: { + jsx: false + } + }; + const messages = linter.verify(code, config, { filename: "test.tsx" }); + + assert.deepStrictEqual(messages, []); + }); }); }); From 4b90b30b6dca64dfba4fdf500556fe69a1e2bac9 Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Fri, 9 Nov 2018 13:36:17 +0900 Subject: [PATCH 5/5] use expect() instead of assert() --- tests/lib/tsx.js | 70 +++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/tests/lib/tsx.js b/tests/lib/tsx.js index 4152be3..831d5fd 100644 --- a/tests/lib/tsx.js +++ b/tests/lib/tsx.js @@ -12,7 +12,6 @@ //------------------------------------------------------------------------------ const - assert = require("assert"), path = require("path"), { Linter } = require("eslint"), shelljs = require("shelljs"), @@ -55,18 +54,15 @@ describe("TSX", () => { }; const messages = linter.verify(code, config); - assert.deepStrictEqual( - messages, - [{ - column: 18, - fatal: true, - line: 1, - message: "Parsing error: '>' expected.", - ruleId: null, - severity: 2, - source: "const element = " - }] - ); + expect(messages).toStrictEqual([{ + column: 18, + fatal: true, + line: 1, + message: "Parsing error: '>' expected.", + ruleId: null, + severity: 2, + source: "const element = " + }]); }); test("filePath was not provided and 'jsx:true' option", () => { @@ -79,7 +75,7 @@ describe("TSX", () => { }; const messages = linter.verify(code, config); - assert.deepStrictEqual(messages, []); + expect(messages).toStrictEqual([]); }); test("test.ts", () => { @@ -89,18 +85,15 @@ describe("TSX", () => { }; const messages = linter.verify(code, config, { filename: "test.ts" }); - assert.deepStrictEqual( - messages, - [{ - column: 18, - fatal: true, - line: 1, - message: "Parsing error: '>' expected.", - ruleId: null, - severity: 2, - source: "const element = " - }] - ); + expect(messages).toStrictEqual([{ + column: 18, + fatal: true, + line: 1, + message: "Parsing error: '>' expected.", + ruleId: null, + severity: 2, + source: "const element = " + }]); }); test("test.ts with 'jsx:true' option", () => { @@ -113,18 +106,15 @@ describe("TSX", () => { }; const messages = linter.verify(code, config, { filename: "test.ts" }); - assert.deepStrictEqual( - messages, - [{ - column: 18, - fatal: true, - line: 1, - message: "Parsing error: '>' expected.", - ruleId: null, - severity: 2, - source: "const element = " - }] - ); + expect(messages).toStrictEqual([{ + column: 18, + fatal: true, + line: 1, + message: "Parsing error: '>' expected.", + ruleId: null, + severity: 2, + source: "const element = " + }]); }); test("test.tsx", () => { @@ -134,7 +124,7 @@ describe("TSX", () => { }; const messages = linter.verify(code, config, { filename: "test.tsx" }); - assert.deepStrictEqual(messages, []); + expect(messages).toStrictEqual([]); }); test("test.tsx with 'jsx:false' option", () => { @@ -147,7 +137,7 @@ describe("TSX", () => { }; const messages = linter.verify(code, config, { filename: "test.tsx" }); - assert.deepStrictEqual(messages, []); + expect(messages).toStrictEqual([]); }); }); });