Skip to content

Commit

Permalink
internal: always pass the class name reference
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Apr 2, 2022
1 parent d8ec066 commit 8b236f3
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 25 deletions.
35 changes: 19 additions & 16 deletions internal/js_parser/js_parser.go
Expand Up @@ -608,9 +608,14 @@ type fnOnlyDataVisit struct {
thisCaptureRef *js_ast.Ref
argumentsCaptureRef *js_ast.Ref

// Inside a static class property initializer, "this" expressions should be
// replaced with the class name.
thisClassStaticRef *js_ast.Ref
// If true, we're inside a static class context where "this" expressions
// should be replaced with the class name.
shouldReplaceThisWithClassNameRef bool

// This is a reference to the enclosing class name if there is one. It's used
// to implement "this" and "super" references. A name is automatically generated
// if one is missing so this will always be present inside a class body.
classNameRef *js_ast.Ref

// If we're inside an async arrow function and async functions are not
// supported, then we will have to convert that arrow function to a generator
Expand Down Expand Up @@ -10203,13 +10208,12 @@ func (p *parser) visitClass(nameScopeLoc logger.Loc, class *js_ast.Class) js_ast
p.fnOnlyDataVisit = fnOnlyDataVisit{
isThisNested: true,
isNewTargetAllowed: true,
classNameRef: &shadowRef,
}

if classLoweringInfo.lowerAllStaticFields {
// Replace "this" with the class name inside static class blocks
p.fnOnlyDataVisit.thisClassStaticRef = &shadowRef

// Need to lower "super" since it won't be valid outside the class body
// Need to lower "this" and "super" since they won't be valid outside the class body
p.fnOnlyDataVisit.shouldReplaceThisWithClassNameRef = true
p.fnOrArrowDataVisit.shouldLowerSuperPropertyAccess = true
}

Expand Down Expand Up @@ -10282,10 +10286,11 @@ func (p *parser) visitClass(nameScopeLoc logger.Loc, class *js_ast.Class) js_ast
oldFnOnlyDataVisit := p.fnOnlyDataVisit
oldShouldLowerSuperPropertyAccess := p.fnOrArrowDataVisit.shouldLowerSuperPropertyAccess
p.fnOrArrowDataVisit.shouldLowerSuperPropertyAccess = false
p.fnOnlyDataVisit.shouldReplaceThisWithClassNameRef = false
p.fnOnlyDataVisit.isThisNested = true
p.fnOnlyDataVisit.isNewTargetAllowed = true
p.fnOnlyDataVisit.thisClassStaticRef = nil
p.fnOnlyDataVisit.superHelpers = nil
p.fnOnlyDataVisit.classNameRef = &shadowRef

// We need to explicitly assign the name to the property initializer if it
// will be transformed such that it is no longer an inline initializer.
Expand Down Expand Up @@ -10313,10 +10318,8 @@ func (p *parser) visitClass(nameScopeLoc logger.Loc, class *js_ast.Class) js_ast

if property.InitializerOrNil.Data != nil {
if property.IsStatic && classLoweringInfo.lowerAllStaticFields {
// Replace "this" with the class name inside static property initializers
p.fnOnlyDataVisit.thisClassStaticRef = &shadowRef

// Need to lower "super" since it won't be valid outside the class body
// Need to lower "this" and "super" since they won't be valid outside the class body
p.fnOnlyDataVisit.shouldReplaceThisWithClassNameRef = true
p.fnOrArrowDataVisit.shouldLowerSuperPropertyAccess = true
}
if nameToKeep != "" {
Expand Down Expand Up @@ -11118,10 +11121,10 @@ func (p *parser) valueForThis(
isCallTarget bool,
isDeleteTarget bool,
) (js_ast.Expr, bool) {
// Substitute "this" if we're inside a static class property initializer
if p.fnOnlyDataVisit.thisClassStaticRef != nil {
p.recordUsage(*p.fnOnlyDataVisit.thisClassStaticRef)
return js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: *p.fnOnlyDataVisit.thisClassStaticRef}}, true
// Substitute "this" if we're inside a static class context
if p.fnOnlyDataVisit.shouldReplaceThisWithClassNameRef {
p.recordUsage(*p.fnOnlyDataVisit.classNameRef)
return js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: *p.fnOnlyDataVisit.classNameRef}}, true
}

// Is this a top-level use of "this"?
Expand Down
18 changes: 9 additions & 9 deletions internal/js_parser/js_parser_lower.go
Expand Up @@ -2859,10 +2859,10 @@ func (p *parser) ensureSuperSet() {
func (p *parser) callSuperPropertyWrapper(loc logger.Loc, property js_ast.Expr, includeGet bool) js_ast.Expr {
var result js_ast.Expr

if thisRef := p.fnOnlyDataVisit.thisClassStaticRef; thisRef != nil {
p.recordUsage(*thisRef)
if p.fnOnlyDataVisit.shouldReplaceThisWithClassNameRef {
p.recordUsage(*p.fnOnlyDataVisit.classNameRef)
result = p.callRuntime(loc, "__superStaticWrapper", []js_ast.Expr{
{Loc: loc, Data: &js_ast.EIdentifier{Ref: *thisRef}},
{Loc: loc, Data: &js_ast.EIdentifier{Ref: *p.fnOnlyDataVisit.classNameRef}},
property,
})
} else {
Expand All @@ -2888,10 +2888,10 @@ func (p *parser) callSuperPropertyWrapper(loc logger.Loc, property js_ast.Expr,
}

func (p *parser) lowerSuperPropertyGet(loc logger.Loc, key js_ast.Expr) js_ast.Expr {
if thisRef := p.fnOnlyDataVisit.thisClassStaticRef; thisRef != nil {
p.recordUsage(*thisRef)
if p.fnOnlyDataVisit.shouldReplaceThisWithClassNameRef {
p.recordUsage(*p.fnOnlyDataVisit.classNameRef)
return p.callRuntime(loc, "__superStaticGet", []js_ast.Expr{
{Loc: loc, Data: &js_ast.EIdentifier{Ref: *thisRef}},
{Loc: loc, Data: &js_ast.EIdentifier{Ref: *p.fnOnlyDataVisit.classNameRef}},
key,
})
}
Expand All @@ -2906,10 +2906,10 @@ func (p *parser) lowerSuperPropertyGet(loc logger.Loc, key js_ast.Expr) js_ast.E
}

func (p *parser) lowerSuperPropertySet(loc logger.Loc, key js_ast.Expr, value js_ast.Expr) js_ast.Expr {
if thisRef := p.fnOnlyDataVisit.thisClassStaticRef; thisRef != nil {
p.recordUsage(*thisRef)
if p.fnOnlyDataVisit.shouldReplaceThisWithClassNameRef {
p.recordUsage(*p.fnOnlyDataVisit.classNameRef)
return p.callRuntime(loc, "__superStaticSet", []js_ast.Expr{
{Loc: loc, Data: &js_ast.EIdentifier{Ref: *thisRef}},
{Loc: loc, Data: &js_ast.EIdentifier{Ref: *p.fnOnlyDataVisit.classNameRef}},
key,
value,
})
Expand Down

0 comments on commit 8b236f3

Please sign in to comment.