|
@@ -1,7 +1,6 @@
|
|
|
import {
|
|
import {
|
|
|
Node,
|
|
Node,
|
|
|
Identifier,
|
|
Identifier,
|
|
|
- VariableDeclarator,
|
|
|
|
|
BlockStatement,
|
|
BlockStatement,
|
|
|
CallExpression,
|
|
CallExpression,
|
|
|
ObjectPattern,
|
|
ObjectPattern,
|
|
@@ -30,14 +29,6 @@ export function shouldTransform(src: string): boolean {
|
|
|
return transformCheckRE.test(src)
|
|
return transformCheckRE.test(src)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export interface ReactiveDeclarator {
|
|
|
|
|
- node: VariableDeclarator
|
|
|
|
|
- statement: VariableDeclaration
|
|
|
|
|
- ids: Identifier[]
|
|
|
|
|
- isPattern: boolean
|
|
|
|
|
- isRoot: boolean
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
type Scope = Record<string, boolean>
|
|
type Scope = Record<string, boolean>
|
|
|
|
|
|
|
|
export interface RefTransformOptions {
|
|
export interface RefTransformOptions {
|
|
@@ -105,18 +96,26 @@ export function transform(
|
|
|
export function transformAST(
|
|
export function transformAST(
|
|
|
ast: Node,
|
|
ast: Node,
|
|
|
s: MagicString,
|
|
s: MagicString,
|
|
|
- offset = 0
|
|
|
|
|
|
|
+ offset = 0,
|
|
|
|
|
+ knownRootVars?: string[]
|
|
|
): {
|
|
): {
|
|
|
rootVars: string[]
|
|
rootVars: string[]
|
|
|
importedHelpers: string[]
|
|
importedHelpers: string[]
|
|
|
} {
|
|
} {
|
|
|
const importedHelpers = new Set<string>()
|
|
const importedHelpers = new Set<string>()
|
|
|
const blockStack: BlockStatement[] = []
|
|
const blockStack: BlockStatement[] = []
|
|
|
|
|
+ let currentBlock: BlockStatement | null = null
|
|
|
const rootScope: Scope = {}
|
|
const rootScope: Scope = {}
|
|
|
const blockToScopeMap = new WeakMap<BlockStatement, Scope>()
|
|
const blockToScopeMap = new WeakMap<BlockStatement, Scope>()
|
|
|
const excludedIds = new Set<Identifier>()
|
|
const excludedIds = new Set<Identifier>()
|
|
|
const parentStack: Node[] = []
|
|
const parentStack: Node[] = []
|
|
|
|
|
|
|
|
|
|
+ if (knownRootVars) {
|
|
|
|
|
+ for (const key of knownRootVars) {
|
|
|
|
|
+ rootScope[key] = true
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const error = (msg: string, node: Node) => {
|
|
const error = (msg: string, node: Node) => {
|
|
|
const e = new Error(msg)
|
|
const e = new Error(msg)
|
|
|
;(e as any).node = node
|
|
;(e as any).node = node
|
|
@@ -130,7 +129,6 @@ export function transformAST(
|
|
|
|
|
|
|
|
const registerBinding = (id: Identifier, isRef = false) => {
|
|
const registerBinding = (id: Identifier, isRef = false) => {
|
|
|
excludedIds.add(id)
|
|
excludedIds.add(id)
|
|
|
- const currentBlock = blockStack[blockStack.length - 1]
|
|
|
|
|
if (currentBlock) {
|
|
if (currentBlock) {
|
|
|
const currentScope = blockToScopeMap.get(currentBlock)
|
|
const currentScope = blockToScopeMap.get(currentBlock)
|
|
|
if (!currentScope) {
|
|
if (!currentScope) {
|
|
@@ -145,13 +143,16 @@ export function transformAST(
|
|
|
|
|
|
|
|
const registerRefBinding = (id: Identifier) => registerBinding(id, true)
|
|
const registerRefBinding = (id: Identifier) => registerBinding(id, true)
|
|
|
|
|
|
|
|
|
|
+ if (ast.type === 'Program') {
|
|
|
|
|
+ walkBlockDeclarations(ast, registerBinding)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 1st pass: detect macro callsites and register ref bindings
|
|
// 1st pass: detect macro callsites and register ref bindings
|
|
|
;(walk as any)(ast, {
|
|
;(walk as any)(ast, {
|
|
|
enter(node: Node, parent?: Node) {
|
|
enter(node: Node, parent?: Node) {
|
|
|
parent && parentStack.push(parent)
|
|
parent && parentStack.push(parent)
|
|
|
-
|
|
|
|
|
if (node.type === 'BlockStatement') {
|
|
if (node.type === 'BlockStatement') {
|
|
|
- blockStack.push(node)
|
|
|
|
|
|
|
+ blockStack.push((currentBlock = node))
|
|
|
walkBlockDeclarations(node, registerBinding)
|
|
walkBlockDeclarations(node, registerBinding)
|
|
|
if (parent && isFunctionType(parent)) {
|
|
if (parent && isFunctionType(parent)) {
|
|
|
walkFunctionParams(parent, registerBinding)
|
|
walkFunctionParams(parent, registerBinding)
|
|
@@ -213,6 +214,7 @@ export function transformAST(
|
|
|
parent && parentStack.pop()
|
|
parent && parentStack.pop()
|
|
|
if (node.type === 'BlockStatement') {
|
|
if (node.type === 'BlockStatement') {
|
|
|
blockStack.pop()
|
|
blockStack.pop()
|
|
|
|
|
+ currentBlock = blockStack[blockStack.length - 1] || null
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
@@ -356,7 +358,7 @@ export function transformAST(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
- rootVars: Object.keys(rootScope),
|
|
|
|
|
|
|
+ rootVars: Object.keys(rootScope).filter(key => rootScope[key]),
|
|
|
importedHelpers: [...importedHelpers]
|
|
importedHelpers: [...importedHelpers]
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|