Skip to content

Commit

Permalink
Merge pull request #104 from ember-tooling/thow-usable-eslint-error
Browse files Browse the repository at this point in the history
throw useful error message for eslint
  • Loading branch information
NullVoxPopuli authored Nov 21, 2024
2 parents 257787c + 4a66532 commit d2c67ac
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 5 deletions.
1 change: 0 additions & 1 deletion scripts/eslint-plugin-ember-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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' });
2 changes: 1 addition & 1 deletion src/parser/gjs-gts-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
55 changes: 53 additions & 2 deletions src/parser/transforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
/**
*
Expand All @@ -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 <anon>: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') {
Expand Down
4 changes: 3 additions & 1 deletion test-projects/gjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions test-projects/gjs/src/placeholer.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ export const Placeholder = <template>
><code class="{{orGlimdown (qp 'format')}} hljs">{{context.text}}</code></pre>
{{/let}}
</template>;


console.log(')
24 changes: 24 additions & 0 deletions tests/parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2677,4 +2677,28 @@ export const NotFound = <template>
}
`);
});

it('throws eslint syntax error', () => {
try {
result = parseForESLint(`console.log('test)`, {
filePath: 'example.gts',
comment: true,
loc: true,
range: true,
tokens: true,
});
} catch (e) {
expect(e.lineNumber).toBe(1);
expect(e.column).toBe(19);
expect(e.fileName).toBe('example.gts');
expect(e.message).toMatchInlineSnapshot(`
"
× Unexpected eof
╭────
1 │ console.log('test)
╰────
"
`);
}
});
});

0 comments on commit d2c67ac

Please sign in to comment.