Prevent infinite visiting

This commit is contained in:
proteriax
2021-07-22 09:54:10 -04:00
parent 5b251be6e1
commit 563d5d9c34

View File

@ -2,9 +2,10 @@ import type * as babel from "@babel/core"
import type * as t from "@babel/types" import type * as t from "@babel/types"
interface State { interface State {
visited: WeakSet<t.ClassDeclaration>
getTSLib(): t.ImportSpecifier[] getTSLib(): t.ImportSpecifier[]
getParam(): t.Identifier __param(): t.Identifier
getDecorate(): t.Identifier __decorate(): t.Identifier
} }
export default ({ types: t }: typeof babel): babel.PluginObj<State> => ({ export default ({ types: t }: typeof babel): babel.PluginObj<State> => ({
@ -34,12 +35,16 @@ export default ({ types: t }: typeof babel): babel.PluginObj<State> => ({
const getParam = createGet("__param") const getParam = createGet("__param")
const getDecorate = createGet("__decorate") const getDecorate = createGet("__decorate")
state.getParam = () => t.cloneNode(getParam()) state.__param = () => t.cloneNode(getParam())
state.getDecorate = () => t.cloneNode(getDecorate()) state.__decorate = () => t.cloneNode(getDecorate())
state.visited = new WeakSet()
}, },
}, },
ClassDeclaration(path, state) { ClassDeclaration(path, state) {
if (state.visited.has(path.node)) return
state.visited.add(path.node)
const modifiers: (t.Expression | t.Statement)[] = [] const modifiers: (t.Expression | t.Statement)[] = []
const classDecorators: t.Expression[] = [] const classDecorators: t.Expression[] = []
const prefixes: t.Statement[] = [] const prefixes: t.Statement[] = []
@ -59,7 +64,7 @@ export default ({ types: t }: typeof babel): babel.PluginObj<State> => ({
case "ClassProperty": case "ClassProperty":
if (!child.decorators) continue if (!child.decorators) continue
modifiers.push( modifiers.push(
t.callExpression(state.getDecorate(), [ t.callExpression(state.__decorate(), [
t.arrayExpression(child.decorators.map(d => d.expression)), t.arrayExpression(child.decorators.map(d => d.expression)),
t.memberExpression(classID, t.identifier("prototype")), t.memberExpression(classID, t.identifier("prototype")),
t.isIdentifier(child.key) ? t.stringLiteral(child.key.name) : child.key, t.isIdentifier(child.key) ? t.stringLiteral(child.key.name) : child.key,
@ -83,9 +88,7 @@ export default ({ types: t }: typeof babel): babel.PluginObj<State> => ({
list.push( list.push(
...param.decorators ...param.decorators
.map(d => d.expression) .map(d => d.expression)
.map(e => .map(e => t.callExpression(state.__param(), [t.numericLiteral(i), e]))
t.callExpression(state.getParam(), [t.numericLiteral(i), e])
)
) )
param.decorators = null param.decorators = null
}) })
@ -108,7 +111,7 @@ export default ({ types: t }: typeof babel): babel.PluginObj<State> => ({
} }
modifiers.push( modifiers.push(
t.callExpression(state.getDecorate(), [ t.callExpression(state.__decorate(), [
t.arrayExpression(list), t.arrayExpression(list),
t.memberExpression(classID, t.identifier("prototype")), t.memberExpression(classID, t.identifier("prototype")),
key, key,
@ -134,7 +137,7 @@ export default ({ types: t }: typeof babel): babel.PluginObj<State> => ({
t.assignmentExpression( t.assignmentExpression(
"=", "=",
classID, classID,
t.callExpression(state.getDecorate(), [ t.callExpression(state.__decorate(), [
t.arrayExpression(classDecorators), t.arrayExpression(classDecorators),
classID, classID,
]) ])