diff --git a/scripts/eslint-plugin-ember-test.mjs b/scripts/eslint-plugin-ember-test.mjs index e671401..b73672c 100644 --- a/scripts/eslint-plugin-ember-test.mjs +++ b/scripts/eslint-plugin-ember-test.mjs @@ -13,7 +13,6 @@ await fse.ensureDir(FOLDERS.testRoot); // Using pnpm instead of yarn, because pnpm is way faster await execaCommand(`git clone ${REPO}`, { cwd: FOLDERS.testRoot, stdio: 'inherit' }); -await execaCommand(`pnpm import`, { cwd: FOLDERS.repo, stdio: 'inherit' }); // project uses a yarn lockfile await execaCommand(`pnpm install`, { cwd: FOLDERS.repo, stdio: 'inherit' }); await execaCommand(`pnpm add ${FOLDERS.here}`, { cwd: FOLDERS.repo, stdio: 'inherit' }); await execaCommand(`pnpm run test`, { cwd: FOLDERS.repo, stdio: 'inherit' }); 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..b7e87aa 100644 --- a/src/parser/transforms.js +++ b/src/parser/transforms.js @@ -567,7 +567,39 @@ 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 +625,26 @@ 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') { diff --git a/test-projects/gjs/package.json b/test-projects/gjs/package.json index 90762f6..99069b1 100644 --- a/test-projects/gjs/package.json +++ b/test-projects/gjs/package.json @@ -2,7 +2,9 @@ "name": "@test-project/gjs", "private": true, "scripts": { - "test": "eslint . --max-warnings=0" + "test": "pnpm run /test:.*/", + "test:correct-handle-syntax-error": "eslint . | grep -q '26:15 error Parsing error: × Unexpected eof'", + "test:only-one-error": "eslint --format compact . | egrep '^[0-9]+ problem[s]*' | wc -l | grep -q 1" }, "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 =