ember-eslint-parser 0.14.6 → 0.14.8

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.14.6",
3
+ "version": "0.14.8",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "repository": {
@@ -33,6 +33,7 @@
33
33
  "@babel/core": "^7.23.6",
34
34
  "@babel/eslint-parser": "^7.28.6",
35
35
  "@babel/plugin-proposal-decorators": "^7.25.9",
36
+ "@typescript-eslint/eslint-plugin": "^8.46.4",
36
37
  "@typescript-eslint/parser": "^8.0.0",
37
38
  "@typescript-eslint/scope-manager": "^8.0.0",
38
39
  "@typescript-eslint/visitor-keys": "^8.0.0",
@@ -61,6 +61,13 @@ function findVarInParentScopes(scopeManager, nodePath, name) {
61
61
 
62
62
  function registerNodeInScope(node, scope, variable) {
63
63
  const ref = new Reference(node, scope, Reference.READ);
64
+ // A template reference always reads a value. typescript-eslint's scope
65
+ // manager flags every reference as a value or type reference, and its rules
66
+ // rely on that (no-unused-vars treats a reference without
67
+ // isValueReference as type-only since 8.71.1), but eslint-scope's
68
+ // Reference has neither flag.
69
+ ref.isValueReference = true;
70
+ ref.isTypeReference = false;
64
71
  if (variable) {
65
72
  variable.references.push(ref);
66
73
  ref.resolved = variable;
@@ -78,13 +85,24 @@ function isUpperCase(char) {
78
85
  return char.toUpperCase() === char;
79
86
  }
80
87
 
81
- function registerBlockParams(node, path, scopeManager, isTypescript) {
82
- const blockParamNodes = node.blockParamNodes || [];
83
- if (blockParamNodes.length === 0) return;
88
+ function createBlockScope(node, path, scopeManager, isTypescript) {
84
89
  const upperScope = findParentScope(scopeManager, path);
85
- const scope = isTypescript
90
+ return isTypescript
86
91
  ? new TypescriptScope.BlockScope(scopeManager, upperScope, node)
87
92
  : new Scope(scopeManager, 'block', upperScope, node);
93
+ }
94
+
95
+ // Give each template a scope of its own. Otherwise typescript-eslint's
96
+ // no-use-before-define treats a reference in `const Foo = <template>` as
97
+ // running in Foo's initializer, though a template reads its scope lazily.
98
+ function registerTemplateScope(node, path, scopeManager, isTypescript) {
99
+ createBlockScope(node, path, scopeManager, isTypescript);
100
+ }
101
+
102
+ function registerBlockParams(node, path, scopeManager, isTypescript) {
103
+ const blockParamNodes = node.blockParamNodes || [];
104
+ if (blockParamNodes.length === 0) return;
105
+ const scope = createBlockScope(node, path, scopeManager, isTypescript);
88
106
  const declaredVariables = scopeManager.declaredVariables || scopeManager.__declaredVariables;
89
107
  const vars = [];
90
108
  declaredVariables.set(node, vars);
@@ -97,7 +115,10 @@ function registerBlockParams(node, path, scopeManager, isTypescript) {
97
115
  };
98
116
  for (const [i, b] of blockParamNodes.entries()) {
99
117
  const v = new Variable(b.name, scope);
100
- v.identifiers.push(b);
118
+ // The block param, parented to the virtual function, so rules that walk
119
+ // up from a declaration (no-use-before-define's initializer check) stop
120
+ // there, as they do for a function parameter.
121
+ v.identifiers.push({ ...b, parent: virtualJSParentNode });
101
122
  scope.variables.push(v);
102
123
  scope.set.set(b.name, v);
103
124
  vars.push(v);
@@ -170,6 +191,9 @@ function registerElementNode(node, path, scopeManager) {
170
191
  export function buildGlimmerVisitors(scopeManager, isTypescript, collectComments) {
171
192
  if (!scopeManager) return null;
172
193
  const visitors = {
194
+ GlimmerTemplate(node, path) {
195
+ registerTemplateScope(node, path, scopeManager, isTypescript);
196
+ },
173
197
  GlimmerPathExpression(node, path) {
174
198
  registerPathExpression(node, path, scopeManager);
175
199
  },
@@ -244,6 +268,9 @@ export function registerGlimmerScopes(result) {
244
268
  traverse(result.visitorKeys, result.ast, (path) => {
245
269
  const node = path.node;
246
270
  if (!node) return;
271
+ if (node.type === 'GlimmerTemplate') {
272
+ registerTemplateScope(node, path, result.scopeManager, result.isTypescript);
273
+ }
247
274
  if (node.type === 'GlimmerPathExpression') {
248
275
  registerPathExpression(node, path, result.scopeManager);
249
276
  }