Skip to content

Commit f52f600

Browse files
committed
pull out method lowering into helper
1 parent 092f635 commit f52f600

File tree

1 file changed

+101
-90
lines changed

1 file changed

+101
-90
lines changed

internal/js_parser/js_parser_lower_class.go

Lines changed: 101 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,104 @@ func (p *parser) lowerClass(stmt js_ast.Stmt, expr js_ast.Expr, result visitClas
720720
}
721721
}
722722

723+
// If this returns true, the method property should be dropped as it has
724+
// already been accounted for elsewhere (e.g. a lowered private method).
725+
lowerMethod := func(prop js_ast.Property, private *js_ast.EPrivateIdentifier) bool {
726+
if private != nil && p.privateSymbolNeedsToBeLowered(private) {
727+
loc := prop.Loc
728+
729+
// Don't generate a symbol for a getter/setter pair twice
730+
if p.symbols[private.Ref.InnerIndex].Link == js_ast.InvalidRef {
731+
// Generate a new symbol for this private method
732+
ref := p.generateTempRef(tempRefNeedsDeclare, "_"+p.symbols[private.Ref.InnerIndex].OriginalName[1:])
733+
p.symbols[private.Ref.InnerIndex].Link = ref
734+
735+
// Initialize the private method to a new WeakSet
736+
if p.weakSetRef == js_ast.InvalidRef {
737+
p.weakSetRef = p.newSymbol(js_ast.SymbolUnbound, "WeakSet")
738+
p.moduleScope.Generated = append(p.moduleScope.Generated, p.weakSetRef)
739+
}
740+
privateMembers = append(privateMembers, js_ast.Assign(
741+
js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}},
742+
js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.ENew{Target: js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: p.weakSetRef}}}},
743+
))
744+
p.recordUsage(ref)
745+
746+
// Determine where to store the private method
747+
var target js_ast.Expr
748+
if prop.Flags.Has(js_ast.PropertyIsStatic) {
749+
target = nameFunc()
750+
} else {
751+
target = js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}
752+
}
753+
754+
// Add every newly-constructed instance into this map
755+
methodExpr := p.callRuntime(loc, "__privateAdd", []js_ast.Expr{
756+
target,
757+
{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}},
758+
})
759+
p.recordUsage(ref)
760+
761+
// Make sure that adding to the map happens before any field
762+
// initializers to handle cases like this:
763+
//
764+
// class A {
765+
// pub = this.#priv;
766+
// #priv() {}
767+
// }
768+
//
769+
if prop.Flags.Has(js_ast.PropertyIsStatic) {
770+
// Move this property to an assignment after the class ends
771+
staticPrivateMethods = append(staticPrivateMethods, methodExpr)
772+
} else {
773+
// Move this property to an assignment inside the class constructor
774+
instancePrivateMethods = append(instancePrivateMethods, js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{Value: methodExpr}})
775+
}
776+
}
777+
778+
// Move the method definition outside the class body
779+
methodRef := p.generateTempRef(tempRefNeedsDeclare, "_")
780+
if prop.Kind == js_ast.PropertySet {
781+
p.symbols[methodRef.InnerIndex].Link = p.privateSetters[private.Ref]
782+
} else {
783+
p.symbols[methodRef.InnerIndex].Link = p.privateGetters[private.Ref]
784+
}
785+
p.recordUsage(methodRef)
786+
privateMembers = append(privateMembers, js_ast.Assign(
787+
js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: methodRef}},
788+
prop.ValueOrNil,
789+
))
790+
return true
791+
}
792+
793+
if key, ok := prop.Key.Data.(*js_ast.EString); ok && helpers.UTF16EqualsString(key.Value, "constructor") {
794+
if fn, ok := prop.ValueOrNil.Data.(*js_ast.EFunction); ok {
795+
// Remember where the constructor is for later
796+
ctor = fn
797+
798+
// Initialize TypeScript constructor parameter fields
799+
if p.options.ts.Parse {
800+
for _, arg := range ctor.Fn.Args {
801+
if arg.IsTypeScriptCtorField {
802+
if id, ok := arg.Binding.Data.(*js_ast.BIdentifier); ok {
803+
parameterFields = append(parameterFields, js_ast.AssignStmt(
804+
js_ast.Expr{Loc: arg.Binding.Loc, Data: p.dotOrMangledPropVisit(
805+
js_ast.Expr{Loc: arg.Binding.Loc, Data: js_ast.EThisShared},
806+
p.symbols[id.Ref.InnerIndex].OriginalName,
807+
arg.Binding.Loc,
808+
)},
809+
js_ast.Expr{Loc: arg.Binding.Loc, Data: &js_ast.EIdentifier{Ref: id.Ref}},
810+
))
811+
}
812+
}
813+
}
814+
}
815+
}
816+
}
817+
818+
return false
819+
}
820+
723821
classLoweringInfo := p.computeClassLoweringInfo(class)
724822

725823
for _, prop := range class.Properties {
@@ -1050,96 +1148,9 @@ func (p *parser) lowerClass(stmt js_ast.Stmt, expr js_ast.Expr, result visitClas
10501148
prop.InitializerOrNil = js_ast.Expr{}
10511149
}
10521150

1053-
if prop.Flags.Has(js_ast.PropertyIsMethod) {
1054-
if mustLowerPrivate {
1055-
loc := prop.Loc
1056-
1057-
// Don't generate a symbol for a getter/setter pair twice
1058-
if p.symbols[private.Ref.InnerIndex].Link == js_ast.InvalidRef {
1059-
// Generate a new symbol for this private method
1060-
ref := p.generateTempRef(tempRefNeedsDeclare, "_"+p.symbols[private.Ref.InnerIndex].OriginalName[1:])
1061-
p.symbols[private.Ref.InnerIndex].Link = ref
1062-
1063-
// Initialize the private method to a new WeakSet
1064-
if p.weakSetRef == js_ast.InvalidRef {
1065-
p.weakSetRef = p.newSymbol(js_ast.SymbolUnbound, "WeakSet")
1066-
p.moduleScope.Generated = append(p.moduleScope.Generated, p.weakSetRef)
1067-
}
1068-
privateMembers = append(privateMembers, js_ast.Assign(
1069-
js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}},
1070-
js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.ENew{Target: js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: p.weakSetRef}}}},
1071-
))
1072-
p.recordUsage(ref)
1073-
1074-
// Determine where to store the private method
1075-
var target js_ast.Expr
1076-
if prop.Flags.Has(js_ast.PropertyIsStatic) {
1077-
target = nameFunc()
1078-
} else {
1079-
target = js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}
1080-
}
1081-
1082-
// Add every newly-constructed instance into this map
1083-
methodExpr := p.callRuntime(loc, "__privateAdd", []js_ast.Expr{
1084-
target,
1085-
{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}},
1086-
})
1087-
p.recordUsage(ref)
1088-
1089-
// Make sure that adding to the map happens before any field
1090-
// initializers to handle cases like this:
1091-
//
1092-
// class A {
1093-
// pub = this.#priv;
1094-
// #priv() {}
1095-
// }
1096-
//
1097-
if prop.Flags.Has(js_ast.PropertyIsStatic) {
1098-
// Move this property to an assignment after the class ends
1099-
staticPrivateMethods = append(staticPrivateMethods, methodExpr)
1100-
} else {
1101-
// Move this property to an assignment inside the class constructor
1102-
instancePrivateMethods = append(instancePrivateMethods, js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{Value: methodExpr}})
1103-
}
1104-
}
1105-
1106-
// Move the method definition outside the class body
1107-
methodRef := p.generateTempRef(tempRefNeedsDeclare, "_")
1108-
if prop.Kind == js_ast.PropertySet {
1109-
p.symbols[methodRef.InnerIndex].Link = p.privateSetters[private.Ref]
1110-
} else {
1111-
p.symbols[methodRef.InnerIndex].Link = p.privateGetters[private.Ref]
1112-
}
1113-
p.recordUsage(methodRef)
1114-
privateMembers = append(privateMembers, js_ast.Assign(
1115-
js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: methodRef}},
1116-
prop.ValueOrNil,
1117-
))
1118-
continue
1119-
} else if key, ok := prop.Key.Data.(*js_ast.EString); ok && helpers.UTF16EqualsString(key.Value, "constructor") {
1120-
if fn, ok := prop.ValueOrNil.Data.(*js_ast.EFunction); ok {
1121-
// Remember where the constructor is for later
1122-
ctor = fn
1123-
1124-
// Initialize TypeScript constructor parameter fields
1125-
if p.options.ts.Parse {
1126-
for _, arg := range ctor.Fn.Args {
1127-
if arg.IsTypeScriptCtorField {
1128-
if id, ok := arg.Binding.Data.(*js_ast.BIdentifier); ok {
1129-
parameterFields = append(parameterFields, js_ast.AssignStmt(
1130-
js_ast.Expr{Loc: arg.Binding.Loc, Data: p.dotOrMangledPropVisit(
1131-
js_ast.Expr{Loc: arg.Binding.Loc, Data: js_ast.EThisShared},
1132-
p.symbols[id.Ref.InnerIndex].OriginalName,
1133-
arg.Binding.Loc,
1134-
)},
1135-
js_ast.Expr{Loc: arg.Binding.Loc, Data: &js_ast.EIdentifier{Ref: id.Ref}},
1136-
))
1137-
}
1138-
}
1139-
}
1140-
}
1141-
}
1142-
}
1151+
// Lower methods
1152+
if prop.Flags.Has(js_ast.PropertyIsMethod) && lowerMethod(prop, private) {
1153+
continue
11431154
}
11441155

11451156
// Keep this property

0 commit comments

Comments
 (0)