ember-eslint-parser 0.5.3 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-eslint-parser",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "repository": {
@@ -17,6 +17,14 @@
17
17
  "files": [
18
18
  "src"
19
19
  ],
20
+ "dependencies": {
21
+ "@babel/eslint-parser": "^7.23.10",
22
+ "@glimmer/syntax": "^0.92.0",
23
+ "content-tag": "^2.0.1",
24
+ "eslint-scope": "^7.2.2",
25
+ "html-tags": "^3.3.1",
26
+ "svg-tags": "^1.0.0"
27
+ },
20
28
  "devDependencies": {
21
29
  "@babel/core": "^7.23.6",
22
30
  "@typescript-eslint/parser": "^7.1.0",
@@ -34,21 +42,11 @@
34
42
  "fs-extra": "^11.2.0",
35
43
  "prettier": "^3.2.5",
36
44
  "publint": "^0.2.6",
37
- "release-plan": "^0.8.0",
45
+ "release-plan": "^0.9.0",
38
46
  "typescript": "^5.3.3",
39
47
  "vite": "^5.0.12",
40
48
  "vitest": "^1.2.2"
41
49
  },
42
- "dependencies": {
43
- "@babel/eslint-parser": "^7.23.10",
44
- "@glimmer/syntax": "^0.92.0",
45
- "content-tag": "^2.0.1",
46
- "eslint-scope": "^7.2.2",
47
- "html-tags": "^3.3.1"
48
- },
49
- "engines": {
50
- "node": ">=16.0.0"
51
- },
52
50
  "peerDependencies": {
53
51
  "@babel/core": "^7.23.6",
54
52
  "@typescript-eslint/parser": "*"
@@ -58,12 +56,15 @@
58
56
  "optional": true
59
57
  }
60
58
  },
59
+ "engines": {
60
+ "node": ">=16.0.0"
61
+ },
61
62
  "scripts": {
62
- "test": "vitest run",
63
63
  "lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"",
64
+ "lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"",
64
65
  "lint:js": "eslint . --max-warnings=0",
66
+ "lint:js:fix": "eslint . --fix --max-warnings=0",
65
67
  "lint:package": "pnpm publint",
66
- "lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"",
67
- "lint:js:fix": "eslint . --fix --max-warnings=0"
68
+ "test": "vitest run"
68
69
  }
69
70
  }
@@ -29,7 +29,7 @@ module.exports = {
29
29
  patchTs();
30
30
  registerParsedFile(options.filePath);
31
31
  let jsCode = code;
32
- const info = transformForLint(code);
32
+ const info = transformForLint(code, options.filePath);
33
33
  jsCode = info.output;
34
34
 
35
35
  const isTypescript = options.filePath.endsWith('.gts') || options.filePath.endsWith('.ts');
@@ -4,6 +4,7 @@ const DocumentLines = require('../utils/document');
4
4
  const { visitorKeys: glimmerVisitorKeys } = require('@glimmer/syntax');
5
5
  const { Reference, Scope, Variable, Definition } = require('eslint-scope');
6
6
  const htmlTags = require('html-tags');
7
+ const svgTags = require('svg-tags');
7
8
 
8
9
  let TypescriptScope = null;
9
10
  try {
@@ -476,9 +477,6 @@ module.exports.convertAst = function convertAst(result, preprocessedResult, visi
476
477
  }
477
478
  }
478
479
  if (node.type === 'GlimmerElementNode') {
479
- if (node.tag === 'svg') {
480
- path.context.inSvg = true;
481
- }
482
480
  // always reference first part of tag name, this also has the advantage
483
481
  // that errors regarding this tag will only mark the tag name instead of
484
482
  // the whole tag + children
@@ -491,14 +489,27 @@ module.exports.convertAst = function convertAst(result, preprocessedResult, visi
491
489
  if we do not find a variable we register it with a missing variable if
492
490
  * it starts with upper case, it should be a component with a reference
493
491
  * it includes a dot, it's a path which should have a reference
494
- * it's NOT a standard html tag, it should have a referenced variable
492
+ * it's NOT a standard html or svg tag, it should have a referenced variable
495
493
  */
496
494
  const ignore =
497
- n.name === 'this' || n.name.startsWith(':') || n.name.startsWith('@') || !scope;
495
+ // Local instance access
496
+ n.name === 'this' ||
497
+ // named block
498
+ n.name.startsWith(':') ||
499
+ // argument
500
+ n.name.startsWith('@') ||
501
+ // defined locally
502
+ !scope ||
503
+ // custom-elements are allowed to be used even if they don't exist
504
+ // and are undefined
505
+ n.name.includes('-');
506
+
498
507
  const registerUndef =
499
- isUpperCase(n.name[0]) || node.name.includes('.') || !htmlTags.includes(node.name);
500
- const allowUndef = path.parentPath?.context.inSvg;
501
- if (!ignore && (variable || (registerUndef && !allowUndef))) {
508
+ isUpperCase(n.name[0]) ||
509
+ node.name.includes('.') ||
510
+ (!htmlTags.includes(node.name) && !svgTags.includes(node.name));
511
+
512
+ if (!ignore && (variable || registerUndef)) {
502
513
  registerNodeInScope(n, scope, variable);
503
514
  }
504
515
  }
@@ -567,7 +578,39 @@ module.exports.replaceRange = replaceRange;
567
578
 
568
579
  const processor = new ContentTag.Preprocessor();
569
580
 
570
- module.exports.transformForLint = function transformForLint(code) {
581
+ class EmberParserError extends Error {
582
+ constructor(message, fileName, location) {
583
+ super(message);
584
+ this.location = location;
585
+ this.fileName = fileName;
586
+ Object.defineProperty(this, 'name', {
587
+ configurable: true,
588
+ enumerable: false,
589
+ value: new.target.name,
590
+ });
591
+ }
592
+
593
+ // For old version of ESLint https://github.com/typescript-eslint/typescript-eslint/pull/6556#discussion_r1123237311
594
+ get index() {
595
+ return this.location.start.offset;
596
+ }
597
+
598
+ // https://github.com/eslint/eslint/blob/b09a512107249a4eb19ef5a37b0bd672266eafdb/lib/linter/linter.js#L853
599
+ get lineNumber() {
600
+ return this.location.start.line;
601
+ }
602
+
603
+ // https://github.com/eslint/eslint/blob/b09a512107249a4eb19ef5a37b0bd672266eafdb/lib/linter/linter.js#L854
604
+ get column() {
605
+ return this.location.start.column;
606
+ }
607
+ }
608
+
609
+ function createError(code, message, fileName, start, end = start) {
610
+ return new EmberParserError(message, fileName, { end, start });
611
+ }
612
+
613
+ module.exports.transformForLint = function transformForLint(code, fileName) {
571
614
  let jsCode = code;
572
615
  /**
573
616
  *
@@ -593,7 +636,26 @@ module.exports.transformForLint = function transformForLint(code) {
593
636
  * };
594
637
  * }[]}
595
638
  */
596
- const result = processor.parse(code);
639
+ let result = null;
640
+ try {
641
+ result = processor.parse(code);
642
+ } catch (e) {
643
+ // Parse Error at <anon>:1:19: 1:19
644
+ if (e.message.includes('Parse Error at')) {
645
+ const [line, column] = e.message
646
+ .split(':')
647
+ .slice(-2)
648
+ .map((x) => parseInt(x));
649
+ // e.source_code has actually usable info, e.g × Expected ',', got 'string literal (, '')'
650
+ // ╭─[9:1]
651
+ // 9 │
652
+ // 10 │ console.log(test'');
653
+ // · ──
654
+ // ╰────
655
+ throw createError(code, e.source_code, fileName, { line, column });
656
+ }
657
+ throw e;
658
+ }
597
659
  for (const tplInfo of result.reverse()) {
598
660
  const content = tplInfo.contents.replace(/`/g, '\\`').replace(/\$/g, '\\$');
599
661
  if (tplInfo.type === 'class-member') {