Skip to content

Commit

Permalink
simplify class lowering code generation
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed May 6, 2024
1 parent ad2d0f6 commit 316eee5
Showing 1 changed file with 15 additions and 16 deletions.
31 changes: 15 additions & 16 deletions internal/js_parser/js_parser_lower_class.go
Original file line number Diff line number Diff line change
Expand Up @@ -1722,7 +1722,6 @@ func (ctx *lowerClassContext) finishAndGenerateCode(p *parser, result visitClass
}

var prefixExprs []js_ast.Expr
var middleExprs []js_ast.Expr
var suffixExprs []js_ast.Expr

// Any of the computed property chain that we hoisted out of the class
Expand All @@ -1731,13 +1730,19 @@ func (ctx *lowerClassContext) finishAndGenerateCode(p *parser, result visitClass
prefixExprs = append(prefixExprs, ctx.computedPropertyChain)
}

// WeakSets and WeakMaps
suffixExprs = append(suffixExprs, ctx.privateMembers...)

// Lowered initializers for static methods (including getters and setters)
suffixExprs = append(suffixExprs, ctx.staticPrivateMethods...)

// Lowered initializers for static fields, static accessors, and static blocks
suffixExprs = append(suffixExprs, ctx.staticMembers...)

// The official TypeScript compiler adds generated code after the class body
// in this exact order. Matching this order is important for correctness.
middleExprs = append(middleExprs, ctx.privateMembers...)
middleExprs = append(middleExprs, ctx.staticPrivateMethods...)
middleExprs = append(middleExprs, ctx.staticMembers...)
middleExprs = append(middleExprs, ctx.instanceExperimentalDecorators...)
middleExprs = append(middleExprs, ctx.staticExperimentalDecorators...)
suffixExprs = append(suffixExprs, ctx.instanceExperimentalDecorators...)
suffixExprs = append(suffixExprs, ctx.staticExperimentalDecorators...)

// Run TypeScript experimental class decorators at the end of class initialization
if len(classExperimentalDecorators) > 0 {
Expand All @@ -1762,13 +1767,12 @@ func (ctx *lowerClassContext) finishAndGenerateCode(p *parser, result visitClass
// Calling "nameFunc" will replace "classExpr", so make sure to do that first
// before joining "classExpr" with any other expressions
var nameToJoin js_ast.Expr
if ctx.didCaptureClassExpr || len(middleExprs) > 0 || len(suffixExprs) > 0 {
if ctx.didCaptureClassExpr || len(suffixExprs) > 0 {
nameToJoin = ctx.nameFunc()
}

// Insert expressions on either side of the class as appropriate
ctx.classExpr = js_ast.JoinWithComma(js_ast.JoinAllWithComma(prefixExprs), ctx.classExpr)
ctx.classExpr = js_ast.JoinWithComma(ctx.classExpr, js_ast.JoinAllWithComma(middleExprs))
ctx.classExpr = js_ast.JoinWithComma(ctx.classExpr, js_ast.JoinAllWithComma(suffixExprs))

// Finally join "classExpr" with the variable that holds the class object
Expand Down Expand Up @@ -1895,21 +1899,16 @@ func (ctx *lowerClassContext) finishAndGenerateCode(p *parser, result visitClass
}
}

// Insert expressions in between the class body and the outer class declaration
for _, expr := range middleExprs {
// Insert expressions after the class as appropriate
for _, expr := range suffixExprs {
stmts = append(stmts, js_ast.Stmt{Loc: expr.Loc, Data: &js_ast.SExpr{Value: expr}})
}

// This must come after the class body initializers have finished
if outerClassNameDecl.Data != nil {
// This must come after the class body initializers have finished
stmts = append(stmts, outerClassNameDecl)
}

// Insert expressions after the class as appropriate
for _, expr := range suffixExprs {
stmts = append(stmts, js_ast.Stmt{Loc: expr.Loc, Data: &js_ast.SExpr{Value: expr}})
}

if nameForClassDecorators.Ref != ast.InvalidRef && ctx.kind == classKindExportDefaultStmt {
// "export default class x {}" => "class x {} export {x as default}"
stmts = append(stmts, js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SExportClause{
Expand Down

0 comments on commit 316eee5

Please sign in to comment.