Skip to content

Enum and namespace transformer #284

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7bb5f8c
Isolate parse and emit utilities for testing
rbuckton Jan 29, 2025
3a637f6
Move LinkStore to core
rbuckton Feb 4, 2025
867fdb9
New nodes should start with an undefined TextRange (-1,-1)
rbuckton Feb 4, 2025
b6bca00
Use NodeFactory pointer in EmitContext/NodeVisitor
rbuckton Feb 4, 2025
9fc95a8
Add EnumDeclarationNode alias
rbuckton Feb 4, 2025
f2b907f
Add original node side table to EmitContext
rbuckton Feb 4, 2025
d141b58
Add emitNode side table to EmitContext
rbuckton Feb 4, 2025
c3f77fe
add EnumTransformer, extract name resolution from checker
rbuckton Feb 6, 2025
d5f3f37
Don't use shared 'syntheticRecursiveVisitor' in tests
rbuckton Feb 6, 2025
97ad2bd
Merge remote-tracking branch 'upstream/main' into enum-transform
rbuckton Feb 6, 2025
e9e8a4c
fix lint
rbuckton Feb 6, 2025
556f124
Use getNamespaceParameterName
rbuckton Feb 6, 2025
08ec81c
Fix argument order to SetOriginal
rbuckton Feb 6, 2025
8b64a94
Merge remote-tracking branch 'upstream/main' into enum-transform
rbuckton Feb 7, 2025
278309c
Rename EnumTransformer, implement namespace emit
rbuckton Feb 7, 2025
295b5ec
Merge remote-tracking branch 'upstream/main' into enum-transform
rbuckton Feb 7, 2025
324f750
Rename emit and parse test utility packages
rbuckton Feb 7, 2025
1d80190
Merge branch 'main' into enum-transform
rbuckton Feb 12, 2025
2a986f1
Fix lint
rbuckton Feb 12, 2025
c16a772
Merge remote-tracking branch 'upstream/main' into enum-transform
rbuckton Feb 12, 2025
9a3b69a
Align module/enum downlevel parenthesization with old emitter
rbuckton Feb 12, 2025
1052e19
Fix excessive indentation depth on Block body emit
rbuckton Feb 12, 2025
684b056
Fix condition in getSymbolExportContainer
rbuckton Feb 12, 2025
2d46183
Merge remote-tracking branch 'upstream/main' into enum-transform
rbuckton Feb 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions internal/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type NodeFactory struct {

func newNode(kind Kind, data nodeData) *Node {
n := data.AsNode()
n.Loc = core.UndefinedTextRange()
n.Kind = kind
n.data = data
return n
Expand Down Expand Up @@ -104,7 +105,11 @@ func (list *NodeList) Pos() int { return list.Loc.Pos() }
func (list *NodeList) End() int { return list.Loc.End() }

func (list *NodeList) HasTrailingComma() bool {
return len(list.Nodes) > 0 && list.Nodes[len(list.Nodes)-1].End() < list.End()
if len(list.Nodes) == 0 || PositionIsSynthesized(list.End()) {
return false
}
last := list.Nodes[len(list.Nodes)-1]
return !PositionIsSynthesized(last.End()) && last.End() < list.End()
}

// ModifierList
Expand Down Expand Up @@ -257,6 +262,14 @@ func (n *Node) Expression() *Node {
return n.AsAwaitExpression().Expression
case KindYieldExpression:
return n.AsYieldExpression().Expression
case KindIfStatement:
return n.AsIfStatement().Expression
case KindDoStatement:
return n.AsDoStatement().Expression
case KindWhileStatement:
return n.AsWhileStatement().Expression
case KindWithStatement:
return n.AsWithStatement().Expression
case KindForInStatement, KindForOfStatement:
return n.AsForInOrOfStatement().Expression
case KindSwitchStatement:
Expand All @@ -267,14 +280,12 @@ func (n *Node) Expression() *Node {
return n.AsExpressionStatement().Expression
case KindReturnStatement:
return n.AsReturnStatement().Expression
case KindThrowStatement:
return n.AsThrowStatement().Expression
case KindExternalModuleReference:
return n.AsExternalModuleReference().Expression
case KindIfStatement:
return n.AsIfStatement().Expression
case KindWhileStatement:
return n.AsWhileStatement().Expression
case KindDoStatement:
return n.AsDoStatement().Expression
case KindExportAssignment:
return n.AsExportAssignment().Expression
}
panic("Unhandled case in Node.Expression")
}
Expand Down Expand Up @@ -1487,7 +1498,9 @@ type (
ParameterDeclarationNode = Node
HeritageClauseNode = Node
ExpressionWithTypeArgumentsNode = Node
EnumDeclarationNode = Node
EnumMemberNode = Node
ModuleDeclarationNode = Node
ImportClauseNode = Node
ImportAttributesNode = Node
ImportAttributeNode = Node
Expand Down Expand Up @@ -4244,6 +4257,9 @@ type BinaryExpression struct {
}

func (f *NodeFactory) NewBinaryExpression(left *Expression, operatorToken *TokenNode, right *Expression) *Node {
if operatorToken == nil {
panic("operatorToken is required")
}
data := f.binaryExpressionPool.New()
data.Left = left
data.OperatorToken = operatorToken
Expand Down
71 changes: 69 additions & 2 deletions internal/ast/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@ func GetNameOfDeclaration(declaration *Node) *Node {
if declaration == nil {
return nil
}
nonAssignedName := getNonAssignedNameOfDeclaration(declaration)
nonAssignedName := GetNonAssignedNameOfDeclaration(declaration)
if nonAssignedName != nil {
return nonAssignedName
}
Expand All @@ -1279,7 +1279,8 @@ func GetNameOfDeclaration(declaration *Node) *Node {
return nil
}

func getNonAssignedNameOfDeclaration(declaration *Node) *Node {
func GetNonAssignedNameOfDeclaration(declaration *Node) *Node {
// !!!
switch declaration.Kind {
case KindBinaryExpression:
if IsFunctionPropertyAssignment(declaration) {
Expand Down Expand Up @@ -2137,3 +2138,69 @@ func NodeHasName(statement *Node, id *Node) bool {
}
return false
}

func GetAssertedTypeNode(node *Node) *Node {
switch node.Kind {
case KindAsExpression:
return node.AsAsExpression().Type
case KindSatisfiesExpression:
return node.AsSatisfiesExpression().Type
case KindTypeAssertionExpression:
return node.AsTypeAssertion().Type
}
panic("Unhandled case in getAssertedTypeNode")
}

func IsConstAssertion(node *Node) bool {
switch node.Kind {
case KindAsExpression, KindTypeAssertionExpression:
return IsConstTypeReference(GetAssertedTypeNode(node))
}
return false
}

func IsConstTypeReference(node *Node) bool {
return IsTypeReferenceNode(node) && len(node.TypeArguments()) == 0 && IsIdentifier(node.AsTypeReferenceNode().TypeName) && node.AsTypeReferenceNode().TypeName.Text() == "const"
}

func IsGlobalSourceFile(node *Node) bool {
return node.Kind == KindSourceFile && !IsExternalOrCommonJsModule(node.AsSourceFile())
}

func IsParameterLikeOrReturnTag(node *Node) bool {
switch node.Kind {
case KindParameter, KindTypeParameter, KindJSDocParameterTag, KindJSDocReturnTag:
return true
}
return false
}

func GetDeclarationOfKind(symbol *Symbol, kind Kind) *Node {
for _, declaration := range symbol.Declarations {
if declaration.Kind == kind {
return declaration
}
}
return nil
}

func FindConstructorDeclaration(node *ClassLikeDeclaration) *Node {
for _, member := range node.ClassLikeData().Members.Nodes {
if IsConstructorDeclaration(member) && NodeIsPresent(member.AsConstructorDeclaration().Body) {
return member
}
}
return nil
}

func GetFirstIdentifier(node *Node) *Node {
switch node.Kind {
case KindIdentifier:
return node
case KindQualifiedName:
return GetFirstIdentifier(node.AsQualifiedName().Left)
case KindPropertyAccessExpression:
return GetFirstIdentifier(node.AsPropertyAccessExpression().Expression)
}
panic("Unhandled case in GetFirstIdentifier")
}
6 changes: 3 additions & 3 deletions internal/ast/visitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
// NodeVisitor

type NodeVisitor struct {
Visit func(node *Node) *Node // The callback used to visit a node
Factory NodeFactory // A NodeFactory used to produce new nodes when passed to VisitEachChild
Visit func(node *Node) *Node // Required. The callback used to visit a node
Factory *NodeFactory // Required. The NodeFactory used to produce new nodes when passed to VisitEachChild
Hooks NodeVisitorHooks // Hooks to be invoked when visiting a node
}

Expand Down Expand Up @@ -155,7 +155,7 @@ func (v *NodeVisitor) VisitEachChild(node *Node) *Node {

updated := node.VisitEachChild(v)
if updated != node && v.Hooks.SetOriginal != nil {
v.Hooks.SetOriginal(node, updated)
v.Hooks.SetOriginal(updated, node)
}
return updated
}
Expand Down
Loading
Loading