ember-eslint-parser 0.14.8 → 0.14.9
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 +1 -1
- package/src/parser/gjs-gts-parser.js +14 -0
- package/src/parser/transforms.js +29 -4
package/package.json
CHANGED
|
@@ -130,6 +130,20 @@ export function parseForESLint(code, options) {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
// Scope analysis ran on the placeholder JS, so a write of a template
|
|
134
|
+
// (`const Foo = <template>`, an assignment, a default parameter) still
|
|
135
|
+
// has the placeholder as its writeExpr. The placeholder is out of the
|
|
136
|
+
// AST and never gets a `parent`, which rules read (#257).
|
|
137
|
+
if (result.scopeManager && result.templateInfos?.length) {
|
|
138
|
+
const templates = new Map(result.templateInfos.map((ti) => [ti.placeholder, ti.ast]));
|
|
139
|
+
for (const scope of result.scopeManager.scopes) {
|
|
140
|
+
for (const ref of scope.references) {
|
|
141
|
+
const template = ref.writeExpr && templates.get(ref.writeExpr);
|
|
142
|
+
if (template) ref.writeExpr = template;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
133
147
|
// Surface Glimmer template comments in program.comments as type:'Block'
|
|
134
148
|
// so ESLint's inline-config scanner and plugin rules recognise them.
|
|
135
149
|
if (glimmerComments.length > 0) {
|
package/src/parser/transforms.js
CHANGED
|
@@ -15,6 +15,7 @@ const mathMLTagsSet = new Set(mathmlTagNames);
|
|
|
15
15
|
const require = createRequire(import.meta.url);
|
|
16
16
|
|
|
17
17
|
let TypescriptScope = null;
|
|
18
|
+
let TypescriptTemplateScope = null;
|
|
18
19
|
try {
|
|
19
20
|
const parserPath = require.resolve('@typescript-eslint/parser');
|
|
20
21
|
// eslint-disable-next-line n/no-unpublished-require
|
|
@@ -22,6 +23,26 @@ try {
|
|
|
22
23
|
paths: [parserPath],
|
|
23
24
|
});
|
|
24
25
|
TypescriptScope = require(scopeManagerPath);
|
|
26
|
+
TypescriptTemplateScope = class TemplateScope extends TypescriptScope.FunctionScope {
|
|
27
|
+
constructor(scopeManager, upperScope, block) {
|
|
28
|
+
// `isMethodDefinition` makes it strict without scanning the body for a
|
|
29
|
+
// "use strict" directive, which throws on a template's body.
|
|
30
|
+
super(scopeManager, upperScope, block, true);
|
|
31
|
+
// A template has no `arguments`, unlike the function FunctionScope models.
|
|
32
|
+
const args = this.set.get('arguments');
|
|
33
|
+
if (args) {
|
|
34
|
+
this.set.delete('arguments');
|
|
35
|
+
this.variables.splice(this.variables.indexOf(args), 1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Never called for a template scope: only closing a scope during analysis
|
|
40
|
+
// calls it, and templates get their scopes after that. The base would
|
|
41
|
+
// throw on a template's `body`, so guard it anyway.
|
|
42
|
+
isValidResolution() {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
25
46
|
} catch {
|
|
26
47
|
// not available
|
|
27
48
|
}
|
|
@@ -92,11 +113,15 @@ function createBlockScope(node, path, scopeManager, isTypescript) {
|
|
|
92
113
|
: new Scope(scopeManager, 'block', upperScope, node);
|
|
93
114
|
}
|
|
94
115
|
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
116
|
+
// A template compiles to a closure (`scope: () => ({ Foo })`), so give it a
|
|
117
|
+
// function scope: its references run in an execution context of their own,
|
|
118
|
+
// and no-use-before-define accepts `<Foo />` in `const Foo = <template>`.
|
|
98
119
|
function registerTemplateScope(node, path, scopeManager, isTypescript) {
|
|
99
|
-
|
|
120
|
+
const upperScope = findParentScope(scopeManager, path);
|
|
121
|
+
if (isTypescript) return new TypescriptTemplateScope(scopeManager, upperScope, node);
|
|
122
|
+
// `isMethodDefinition` as in TemplateScope. eslint-scope's base Scope
|
|
123
|
+
// declares no `arguments`.
|
|
124
|
+
return new Scope(scopeManager, 'function', upperScope, node, true);
|
|
100
125
|
}
|
|
101
126
|
|
|
102
127
|
function registerBlockParams(node, path, scopeManager, isTypescript) {
|