From f42052d32ccece7200bdb0a9f8e36e73c6323a24 Mon Sep 17 00:00:00 2001 From: Patrick Pircher Date: Thu, 21 Nov 2024 11:58:20 +0100 Subject: [PATCH 1/4] throw useful error message for eslint --- src/parser/gjs-gts-parser.js | 2 +- src/parser/transforms.js | 53 ++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/parser/gjs-gts-parser.js b/src/parser/gjs-gts-parser.js index 2e95035..a83fb8e 100644 --- a/src/parser/gjs-gts-parser.js +++ b/src/parser/gjs-gts-parser.js @@ -29,7 +29,7 @@ module.exports = { patchTs(); registerParsedFile(options.filePath); let jsCode = code; - const info = transformForLint(code); + const info = transformForLint(code, options.filePath); jsCode = info.output; const isTypescript = options.filePath.endsWith('.gts') || options.filePath.endsWith('.ts'); diff --git a/src/parser/transforms.js b/src/parser/transforms.js index 11d3794..50e226e 100644 --- a/src/parser/transforms.js +++ b/src/parser/transforms.js @@ -567,7 +567,40 @@ module.exports.replaceRange = replaceRange; const processor = new ContentTag.Preprocessor(); -module.exports.transformForLint = function transformForLint(code) { + +class EmberParserError extends Error { + constructor(message, fileName, location) { + super(message); + this.location = location; + this.fileName = fileName; + Object.defineProperty(this, "name", { + configurable: true, + enumerable: false, + value: new.target.name, + }); + } + + // For old version of ESLint https://github.com/typescript-eslint/typescript-eslint/pull/6556#discussion_r1123237311 + get index() { + return this.location.start.offset; + } + + // https://github.com/eslint/eslint/blob/b09a512107249a4eb19ef5a37b0bd672266eafdb/lib/linter/linter.js#L853 + get lineNumber() { + return this.location.start.line; + } + + // https://github.com/eslint/eslint/blob/b09a512107249a4eb19ef5a37b0bd672266eafdb/lib/linter/linter.js#L854 + get column() { + return this.location.start.column; + } +} + +function createError(code, message, fileName, start, end = start) { + return new EmberParserError(message, fileName, { end, start }); +} + +module.exports.transformForLint = function transformForLint(code, fileName) { let jsCode = code; /** * @@ -593,7 +626,23 @@ module.exports.transformForLint = function transformForLint(code) { * }; * }[]} */ - const result = processor.parse(code); + let result = null; + try { + result = processor.parse(code); + } catch (e) { + // Parse Error at :1:19: 1:19 + if (e.message.includes("Parse Error at")) { + const [line, column] = e.message.split(":").slice(-2).map(x => parseInt(x)); + // e.source_code has actually usable info, e.g × Expected ',', got 'string literal (, '')' + // ╭─[9:1] + // 9 │ + // 10 │ console.log(test''); + // · ── + // ╰──── + throw createError(code, e.source_code, fileName, { line, column }); + } + throw e; + } for (const tplInfo of result.reverse()) { const content = tplInfo.contents.replace(/`/g, '\\`').replace(/\$/g, '\\$'); if (tplInfo.type === 'class-member') { From eae58134d9df290f1abfa915bb3109bdf9b42c97 Mon Sep 17 00:00:00 2001 From: Patrick Pircher Date: Thu, 21 Nov 2024 12:11:10 +0100 Subject: [PATCH 2/4] add test --- src/parser/transforms.js | 10 ++++++---- test-projects/gjs/package.json | 2 +- test-projects/gjs/src/placeholer.gjs | 3 +++ tests/parser.test.js | 24 ++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/parser/transforms.js b/src/parser/transforms.js index 50e226e..b7e87aa 100644 --- a/src/parser/transforms.js +++ b/src/parser/transforms.js @@ -567,13 +567,12 @@ module.exports.replaceRange = replaceRange; const processor = new ContentTag.Preprocessor(); - class EmberParserError extends Error { constructor(message, fileName, location) { super(message); this.location = location; this.fileName = fileName; - Object.defineProperty(this, "name", { + Object.defineProperty(this, 'name', { configurable: true, enumerable: false, value: new.target.name, @@ -631,8 +630,11 @@ module.exports.transformForLint = function transformForLint(code, fileName) { result = processor.parse(code); } catch (e) { // Parse Error at :1:19: 1:19 - if (e.message.includes("Parse Error at")) { - const [line, column] = e.message.split(":").slice(-2).map(x => parseInt(x)); + if (e.message.includes('Parse Error at')) { + const [line, column] = e.message + .split(':') + .slice(-2) + .map((x) => parseInt(x)); // e.source_code has actually usable info, e.g × Expected ',', got 'string literal (, '')' // ╭─[9:1] // 9 │ diff --git a/test-projects/gjs/package.json b/test-projects/gjs/package.json index 90762f6..7d23a59 100644 --- a/test-projects/gjs/package.json +++ b/test-projects/gjs/package.json @@ -2,7 +2,7 @@ "name": "@test-project/gjs", "private": true, "scripts": { - "test": "eslint . --max-warnings=0" + "test": "eslint . --max-warnings=0 | grep -q '26:15 error Parsing error: × Unexpected eof'" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^6.21.0", diff --git a/test-projects/gjs/src/placeholer.gjs b/test-projects/gjs/src/placeholer.gjs index 0c33d96..7d0795b 100644 --- a/test-projects/gjs/src/placeholer.gjs +++ b/test-projects/gjs/src/placeholer.gjs @@ -21,3 +21,6 @@ export const Placeholder = ; + + +console.log(') diff --git a/tests/parser.test.js b/tests/parser.test.js index 64b9f54..9fb7667 100644 --- a/tests/parser.test.js +++ b/tests/parser.test.js @@ -2677,4 +2677,28 @@ export const NotFound =