Skip to content

Commit d230c1f

Browse files
authored
Change template parsing method (#29)
* Add scope testcases * update * Change template parsing method
1 parent 415d63a commit d230c1f

File tree

536 files changed

+491977
-131202
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

536 files changed

+491977
-131202
lines changed

src/ast.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export type SvelteNode =
7171
| SvelteShorthandAttribute
7272
| SvelteSpreadAttribute
7373
| SvelteDirective
74+
| SvelteSpecialDirective
7475
| SvelteHTMLComment
7576
| SvelteReactiveStatement
7677

src/context/index.ts

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,54 @@
11
import type { Comment, Locations, Position, Token } from "../ast"
22
import lodash from "lodash"
33
import type ESTree from "estree"
4-
import type { ScopeManager } from "eslint-scope"
5-
import { TemplateScopeManager } from "./template-scope-manager"
4+
import { ScriptLetContext } from "./script-let"
5+
import { LetDirectiveCollections } from "./let-directive-collection"
66

7-
type ContextSourceCode = {
8-
template: string
9-
scripts: {
10-
code: string
11-
attrs: Record<string, string | undefined>
7+
export class ScriptsSourceCode {
8+
private readonly raw
9+
10+
public readonly attrs: Record<string, string | undefined>
11+
12+
private _vcode: string | null = null
13+
14+
public separateSemiIndex: number
15+
16+
public constructor(
17+
script: string,
18+
attrs: Record<string, string | undefined>,
19+
) {
20+
this.raw = script
21+
this.attrs = attrs
22+
this.separateSemiIndex = script.length
23+
}
24+
25+
public get vcode(): string {
26+
if (this._vcode == null) {
27+
return this.raw
28+
}
29+
return this._vcode
30+
}
31+
32+
public addLet(letCode: string): { start: number; end: number } {
33+
if (this._vcode == null) {
34+
this._vcode = this.raw.trimEnd()
35+
this.separateSemiIndex = this._vcode.length
36+
this._vcode += ";"
37+
const after = this.raw.slice(this._vcode.length)
38+
this._vcode += after
39+
}
40+
const start = this._vcode.length
41+
this._vcode += letCode
42+
return {
43+
start,
44+
end: this._vcode.length,
45+
}
1246
}
1347
}
48+
export type ContextSourceCode = {
49+
template: string
50+
scripts: ScriptsSourceCode
51+
}
1452
export class Context {
1553
public readonly code: string
1654

@@ -26,7 +64,9 @@ export class Context {
2664

2765
private readonly locsMap = new Map<number, Position>()
2866

29-
private _templateScopeManager: TemplateScopeManager | null = null
67+
public readonly scriptLet: ScriptLetContext
68+
69+
public readonly letDirCollections = new LetDirectiveCollections()
3070

3171
public constructor(code: string, parserOptions: any) {
3272
this.code = code
@@ -50,17 +90,15 @@ export class Context {
5090
}
5191
start = block.codeRange[1]
5292
}
53-
const before = code.slice(start)
54-
templateCode += before
55-
scriptCode += before.replace(/[^\n\r ]/g, " ")
93+
const after = code.slice(start)
94+
templateCode += after
95+
scriptCode += after.replace(/[^\n\r ]/g, " ")
5696

5797
this.sourceCode = {
5898
template: templateCode,
59-
scripts: {
60-
code: scriptCode,
61-
attrs: scriptAttrs,
62-
},
99+
scripts: new ScriptsSourceCode(scriptCode, scriptAttrs),
63100
}
101+
this.scriptLet = new ScriptLetContext(this)
64102
}
65103

66104
public getLocFromIndex(index: number): { line: number; column: number } {
@@ -119,14 +157,6 @@ export class Context {
119157
public getText(range: { start: number; end: number }): string {
120158
return this.code.slice(range.start, range.end)
121159
}
122-
123-
public readyScopeManager(scopeManager: ScopeManager): void {
124-
this._templateScopeManager = new TemplateScopeManager(scopeManager)
125-
}
126-
127-
public get templateScopeManager(): TemplateScopeManager {
128-
return this._templateScopeManager!
129-
}
130160
}
131161

132162
/** Extract <script> blocks */
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import type { SvelteLetDirective } from "../ast"
2+
import type * as ESTree from "estree"
3+
import type { ScriptLetCallback, ScriptLetCallbackOption } from "./script-let"
4+
5+
/** A class that collects pattern nodes for Let directives. */
6+
export class LetDirectiveCollection {
7+
private readonly list: {
8+
pattern: ESTree.Pattern
9+
directive: SvelteLetDirective
10+
callbacks: ScriptLetCallback<ESTree.Pattern>[]
11+
}[] = []
12+
13+
public isEmpty(): boolean {
14+
return this.list.length === 0
15+
}
16+
17+
public getLetParams(): ESTree.Pattern[] {
18+
return this.list.map((d) => d.pattern)
19+
}
20+
21+
public getCallback(): (
22+
nodes: ESTree.Pattern[],
23+
options: ScriptLetCallbackOption,
24+
) => void {
25+
return (nodes, options) => {
26+
for (let index = 0; index < nodes.length; index++) {
27+
const node = nodes[index]
28+
for (const callback of this.list[index].callbacks) {
29+
callback(node, options)
30+
}
31+
}
32+
}
33+
}
34+
35+
public addPattern(
36+
pattern: ESTree.Pattern,
37+
directive: SvelteLetDirective,
38+
...callbacks: ScriptLetCallback<ESTree.Pattern>[]
39+
): ScriptLetCallback<ESTree.Pattern>[] {
40+
this.list.push({
41+
pattern,
42+
directive,
43+
callbacks,
44+
})
45+
return callbacks
46+
}
47+
}
48+
export class LetDirectiveCollections {
49+
private readonly stack: LetDirectiveCollection[] = []
50+
51+
public beginExtract(): void {
52+
this.stack.push(new LetDirectiveCollection())
53+
}
54+
55+
public getCollection(): LetDirectiveCollection {
56+
return this.stack[this.stack.length - 1]
57+
}
58+
59+
public extract(): LetDirectiveCollection {
60+
return this.stack.pop()!
61+
}
62+
}

0 commit comments

Comments
 (0)