Skip to content

Commit c47043a

Browse files
committed
chore: refactor
1 parent 30627c7 commit c47043a

File tree

3 files changed

+29
-51
lines changed

3 files changed

+29
-51
lines changed

src/parser/typescript/analyze/index.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,22 @@ import {
1212
} from "../../../scope";
1313
import { addElementsToSortedArray, sortedLastIndex } from "../../../utils";
1414
import { parseScriptWithoutAnalyzeScope } from "../../script";
15-
import { TypeScriptContext } from "../context";
15+
import { VirtualTypeScriptContext } from "../context";
1616
import type { TSESParseForESLintResult } from "../types";
1717
import type ESTree from "estree";
1818

1919
const RESERVED_NAMES = new Set<string>(["$$props", "$$restProps", "$$slots"]);
2020
/**
2121
* Analyze <script> block script
2222
* Modify the source code to provide correct type information for svelte special variables and scopes.
23+
* See https://github.com/ota-meshi/svelte-eslint-parser/blob/main/docs/internal-mechanism.md#scope-types
2324
*/
2425
export function analyzeScript(
2526
code: { script: string; render: string },
2627
attrs: Record<string, string | undefined>,
2728
parserOptions: any
28-
): TypeScriptContext {
29-
const ctx = new TypeScriptContext(code.script + code.render);
29+
): VirtualTypeScriptContext {
30+
const ctx = new VirtualTypeScriptContext(code.script + code.render);
3031
ctx.appendOriginal(/^\s*/u.exec(code.script)![0].length);
3132

3233
// We will need to parse TypeScript once to extract the reactive variables.
@@ -54,14 +55,13 @@ export function analyzeScript(
5455
ctx.appendScript(`function ${renderFunctionName}(){`);
5556
ctx.appendOriginalToEnd();
5657
ctx.appendScript(`}`);
57-
ctx.restoreContext.addRestoreStatementProcess((node, context) => {
58+
ctx.restoreContext.addRestoreStatementProcess((node, result) => {
5859
if (
5960
node.type !== "FunctionDeclaration" ||
6061
node.id.name !== renderFunctionName
6162
) {
6263
return false;
6364
}
64-
const result = context.result;
6565
const program = result.ast;
6666
program.body.splice(program.body.indexOf(node), 1, ...node.body.body);
6767
for (const body of node.body.body) {
@@ -81,7 +81,7 @@ export function analyzeScript(
8181
*/
8282
function analyzeStoreReferenceNamesAndExtractThroughIdentifiers(
8383
result: TSESParseForESLintResult,
84-
ctx: TypeScriptContext
84+
ctx: VirtualTypeScriptContext
8585
) {
8686
const scopeManager = result.scopeManager;
8787
const programScope = getProgramScope(scopeManager as ScopeManager);
@@ -110,14 +110,13 @@ function analyzeStoreReferenceNamesAndExtractThroughIdentifiers(
110110
: never
111111
: T;`
112112
);
113-
ctx.restoreContext.addRestoreStatementProcess((node, context) => {
113+
ctx.restoreContext.addRestoreStatementProcess((node, result) => {
114114
if (
115115
node.type !== "TSTypeAliasDeclaration" ||
116116
node.id.name !== storeValueTypeName
117117
) {
118118
return false;
119119
}
120-
const result = context.result;
121120
const program = result.ast;
122121
program.body.splice(program.body.indexOf(node), 1);
123122

@@ -135,7 +134,7 @@ function analyzeStoreReferenceNamesAndExtractThroughIdentifiers(
135134
ctx.appendScript(
136135
`declare let ${nm}: ${storeValueTypeName}<typeof ${realName}>;`
137136
);
138-
ctx.restoreContext.addRestoreStatementProcess((node, context) => {
137+
ctx.restoreContext.addRestoreStatementProcess((node, result) => {
139138
if (
140139
node.type !== "VariableDeclaration" ||
141140
!node.declare ||
@@ -145,7 +144,6 @@ function analyzeStoreReferenceNamesAndExtractThroughIdentifiers(
145144
) {
146145
return false;
147146
}
148-
const result = context.result;
149147
const program = result.ast;
150148
program.body.splice(program.body.indexOf(node), 1);
151149

@@ -171,7 +169,7 @@ function analyzeStoreReferenceNamesAndExtractThroughIdentifiers(
171169
function analyzeReactiveScopes(
172170
result: TSESParseForESLintResult,
173171
throughIds: (TSESTree.Identifier | TSESTree.JSXIdentifier)[],
174-
ctx: TypeScriptContext
172+
ctx: VirtualTypeScriptContext
175173
) {
176174
for (const statement of result.ast.body) {
177175
if (statement.type === "LabeledStatement" && statement.label.name === "$") {
@@ -214,7 +212,7 @@ function transformForDeclareReactiveVar(
214212
id: TSESTree.Identifier | TSESTree.ArrayPattern | TSESTree.ObjectPattern,
215213
expression: TSESTree.AssignmentExpression,
216214
tokens: TSESTree.Token[],
217-
ctx: TypeScriptContext
215+
ctx: VirtualTypeScriptContext
218216
): void {
219217
// e.g.
220218
// From:
@@ -281,7 +279,7 @@ function transformForDeclareReactiveVar(
281279
ctx.appendScript(`}`);
282280

283281
// eslint-disable-next-line complexity -- ignore X(
284-
ctx.restoreContext.addRestoreStatementProcess((node, context) => {
282+
ctx.restoreContext.addRestoreStatementProcess((node, result) => {
285283
if ((node as any).type !== "SvelteReactiveStatement") {
286284
return false;
287285
}
@@ -303,7 +301,6 @@ function transformForDeclareReactiveVar(
303301
) {
304302
return false;
305303
}
306-
const result = context.result;
307304
const program = result.ast;
308305
const nextIndex = program.body.indexOf(node) + 1;
309306
const fnDecl = program.body[nextIndex];
@@ -375,7 +372,7 @@ function transformForDeclareReactiveVar(
375372
*/
376373
function transformForReactiveStatement(
377374
statement: TSESTree.LabeledStatement,
378-
ctx: TypeScriptContext
375+
ctx: VirtualTypeScriptContext
379376
) {
380377
const functionId = ctx.generateUniqueId("reactiveStatementScopeFunction");
381378
const originalBody = statement.body;
@@ -390,7 +387,7 @@ function transformForReactiveStatement(
390387
}
391388
ctx.appendOriginal(statement.range[1]);
392389

393-
ctx.restoreContext.addRestoreStatementProcess((node, context) => {
390+
ctx.restoreContext.addRestoreStatementProcess((node, result) => {
394391
if ((node as any).type !== "SvelteReactiveStatement") {
395392
return false;
396393
}
@@ -406,7 +403,6 @@ function transformForReactiveStatement(
406403
}
407404
reactiveStatement.body.parent = reactiveStatement;
408405

409-
const result = context.result;
410406
const scopeManager = result.scopeManager as ScopeManager;
411407
removeFunctionScope(body, scopeManager);
412408
return true;

src/parser/typescript/context.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import { UniqueIdGenerator } from "../../context/unique";
22
import { RestoreContext } from "./restore";
33
import type { TSESParseForESLintResult } from "./types";
44

5-
export class TypeScriptContext {
5+
/**
6+
* Context for virtual TypeScript code.
7+
* See https://github.com/ota-meshi/svelte-eslint-parser/blob/main/docs/internal-mechanism.md#scope-types
8+
*/
9+
export class VirtualTypeScriptContext {
610
private readonly originalCode: string;
711

812
public readonly restoreContext: RestoreContext;

src/parser/typescript/restore.ts

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type { TSESParseForESLintResult } from "./types";
66
/**
77
* A function that restores the statement.
88
* @param node The node to restore.
9-
* @param context The context to restore.
9+
* @param result The result of parsing.
1010
* @returns
1111
* If `false`, it indicates that the specified node was not processed.
1212
*
@@ -15,7 +15,7 @@ import type { TSESParseForESLintResult } from "./types";
1515
*/
1616
type RestoreStatementProcess = (
1717
node: TSESTree.Statement,
18-
context: RestoreNodeProcessContext
18+
result: TSESParseForESLintResult
1919
) => boolean;
2020

2121
export class RestoreContext {
@@ -52,15 +52,15 @@ export class RestoreContext {
5252
* Restore AST nodes
5353
*/
5454
public restore(result: TSESParseForESLintResult): void {
55-
const parentMap = remapLocationsAndGetParentMap(result, {
55+
remapLocations(result, {
5656
remapLocation: (n) => this.remapLocation(n),
5757
removeToken: (token) =>
5858
this.fragments.some(
5959
(f) => f.start <= token.range[0] && token.range[1] <= f.end
6060
),
6161
});
6262

63-
restoreStatements(result, this.restoreStatementProcesses, parentMap);
63+
restoreStatements(result, this.restoreStatementProcesses);
6464

6565
// Adjust program node location
6666
const firstOffset = Math.min(
@@ -137,26 +137,8 @@ export class RestoreContext {
137137
}
138138
}
139139

140-
export class RestoreNodeProcessContext {
141-
public readonly result: TSESParseForESLintResult;
142-
143-
private readonly parentMap: Map<TSESTree.Node, TSESTree.Node | null>;
144-
145-
public constructor(
146-
result: TSESParseForESLintResult,
147-
parentMap: Map<TSESTree.Node, TSESTree.Node | null>
148-
) {
149-
this.result = result;
150-
this.parentMap = parentMap;
151-
}
152-
153-
public getParent(node: TSESTree.Node): TSESTree.Node | null {
154-
return this.parentMap.get(node) || null;
155-
}
156-
}
157-
158-
/** Restore locations and generate parent map */
159-
function remapLocationsAndGetParentMap(
140+
/** Restore locations */
141+
function remapLocations(
160142
result: TSESParseForESLintResult,
161143
{
162144
remapLocation,
@@ -166,13 +148,13 @@ function remapLocationsAndGetParentMap(
166148
removeToken: (node: TSESTree.Token) => boolean;
167149
}
168150
) {
169-
const parentMap = new Map<TSESTree.Node, TSESTree.Node | null>();
151+
const traversed = new Map<TSESTree.Node, TSESTree.Node | null>();
170152
// remap locations
171153
traverseNodes(result.ast, {
172154
visitorKeys: result.visitorKeys,
173155
enterNode: (node, p) => {
174-
if (!parentMap.has(node)) {
175-
parentMap.set(node, p);
156+
if (!traversed.has(node)) {
157+
traversed.set(node, p);
176158

177159
remapLocation(node);
178160
}
@@ -193,24 +175,20 @@ function remapLocationsAndGetParentMap(
193175
for (const token of result.ast.comments || []) {
194176
remapLocation(token);
195177
}
196-
197-
return parentMap;
198178
}
199179

200180
/** Restore statement nodes */
201181
function restoreStatements(
202182
result: TSESParseForESLintResult,
203-
restoreStatementProcesses: RestoreStatementProcess[],
204-
parentMap: Map<TSESTree.Node, TSESTree.Node | null>
183+
restoreStatementProcesses: RestoreStatementProcess[]
205184
) {
206-
const context = new RestoreNodeProcessContext(result, parentMap);
207185
const restoreStatementProcessesSet = new Set(restoreStatementProcesses);
208186
for (const node of [...result.ast.body]) {
209187
if (!restoreStatementProcessesSet.size) {
210188
break;
211189
}
212190
for (const proc of restoreStatementProcessesSet) {
213-
if (proc(node, context)) {
191+
if (proc(node, result)) {
214192
restoreStatementProcessesSet.delete(proc);
215193
break;
216194
}

0 commit comments

Comments
 (0)