Skip to content

Commit

Permalink
print decorators in js printer
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Apr 2, 2023
1 parent ebc9718 commit 7cd307d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
6 changes: 5 additions & 1 deletion internal/js_parser/js_parser_lower.go
Original file line number Diff line number Diff line change
Expand Up @@ -2375,7 +2375,8 @@ func (p *parser) lowerClass(stmt js_ast.Stmt, expr js_ast.Expr, result visitClas
if key, ok := prop.Key.Data.(*js_ast.EString); ok {
isConstructor = helpers.UTF16EqualsString(key.Value, "constructor")
}
for i, arg := range fn.Fn.Args {
args := fn.Fn.Args
for i, arg := range args {
for _, decorator := range arg.Decorators {
// Generate a call to "__decorateParam()" for this parameter decorator
var decorators *[]js_ast.Expr = &prop.Decorators
Expand All @@ -2388,6 +2389,7 @@ func (p *parser) lowerClass(stmt js_ast.Stmt, expr js_ast.Expr, result visitClas
decorator,
}),
)
args[i].Decorators = nil
}
}
}
Expand Down Expand Up @@ -2492,6 +2494,7 @@ func (p *parser) lowerClass(stmt js_ast.Stmt, expr js_ast.Expr, result visitClas
descriptorKey,
{Loc: loc, Data: &js_ast.ENumber{Value: descriptorKind}},
})
prop.Decorators = nil

// Static decorators are grouped after instance decorators
if prop.Flags.Has(js_ast.PropertyIsStatic) {
Expand Down Expand Up @@ -2945,6 +2948,7 @@ func (p *parser) lowerClass(stmt js_ast.Stmt, expr js_ast.Expr, result visitClas
))
p.recordUsage(nameForClassDecorators.Ref)
p.recordUsage(nameForClassDecorators.Ref)
class.Decorators = nil
}
if generatedLocalStmt {
// "export default class x {}" => "class x {} export {x as default}"
Expand Down
68 changes: 68 additions & 0 deletions internal/js_printer/js_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,7 @@ func (p *printer) printFnArgs(args []js_ast.Arg, opts fnArgsOpts) {
p.print(",")
p.printSpace()
}
p.printDecorators(arg.Decorators, printDecoratorsAllOnOneLine)
if opts.hasRestArg && i+1 == len(args) {
p.print("...")
}
Expand All @@ -863,6 +864,67 @@ func (p *printer) printFn(fn js_ast.Fn) {
p.printBlock(fn.Body.Loc, fn.Body.Block)
}

type printDecorators uint8

const (
printDecoratorsOnSeparateLines printDecorators = iota
printDecoratorsAllOnOneLine
)

func (p *printer) printDecorators(decorators []js_ast.Expr, how printDecorators) {
for _, decorator := range decorators {
wrap := false
expr := decorator

outer:
for {
switch e := expr.Data.(type) {
case *js_ast.EIdentifier, *js_ast.ECall:
// "@foo"
break outer

case *js_ast.EDot:
// "@foo.bar"
expr = e.Target

case *js_ast.EIndex:
if _, ok := e.Index.Data.(*js_ast.EPrivateIdentifier); !ok {
// "@(foo[bar])"
wrap = true
break outer
}

// "@foo.#bar"
expr = e.Target

default:
// "@(foo + bar)"
// "@(() => {})"
wrap = true
break outer
}
}

p.print("@")
if wrap {
p.print("(")
}
p.printExpr(decorator, js_ast.LLowest, 0)
if wrap {
p.print(")")
}

switch how {
case printDecoratorsOnSeparateLines:
p.printNewline()
p.printIndent()

case printDecoratorsAllOnOneLine:
p.printSpace()
}
}
}

func (p *printer) printClass(class js_ast.Class) {
if class.ExtendsOrNil.Data != nil {
p.print(" extends")
Expand All @@ -879,6 +941,7 @@ func (p *printer) printClass(class js_ast.Class) {
for _, item := range class.Properties {
p.printSemicolonIfNeeded()
p.printIndent()
p.printDecorators(item.Decorators, printDecoratorsOnSeparateLines)

if item.Kind == js_ast.PropertyClassStaticBlock {
p.addSourceMapping(item.Loc)
Expand Down Expand Up @@ -2507,6 +2570,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla
if wrap {
p.print("(")
}
p.printDecorators(e.Class.Decorators, printDecoratorsAllOnOneLine)
p.printSpaceBeforeIdentifier()
p.addSourceMapping(expr.Loc)
p.print("class")
Expand Down Expand Up @@ -3737,6 +3801,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) {
p.printNewline()

case *js_ast.SClass:
p.printDecorators(s.Class.Decorators, printDecoratorsOnSeparateLines)
p.addSourceMapping(stmt.Loc)
p.printIndent()
p.printSpaceBeforeIdentifier()
Expand All @@ -3759,6 +3824,9 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) {
case *js_ast.SExportDefault:
p.addSourceMapping(stmt.Loc)
p.printIndent()
if s2, ok := s.Value.Data.(*js_ast.SClass); ok {
p.printDecorators(s2.Class.Decorators, printDecoratorsOnSeparateLines)
}
p.printSpaceBeforeIdentifier()
p.print("export default")
p.printSpace()
Expand Down

0 comments on commit 7cd307d

Please sign in to comment.