Skip to content

Reparse @import as synthetic type-only import declaration #831

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 8 commits into from
May 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions _packages/ast/src/syntaxKind.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,10 @@ export enum SyntaxKind {
JSDocSatisfiesTag,
JSDocImportTag,
SyntaxList,
JSTypeAliasDeclaration,
JSExportAssignment,
CommonJSExport,
JSImportDeclaration,
NotEmittedStatement,
PartiallyEmittedExpression,
CommaListExpression,
Expand Down
14 changes: 9 additions & 5 deletions _packages/ast/src/syntaxKind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,13 @@ export var SyntaxKind: any;
SyntaxKind[SyntaxKind["JSDocSatisfiesTag"] = 342] = "JSDocSatisfiesTag";
SyntaxKind[SyntaxKind["JSDocImportTag"] = 343] = "JSDocImportTag";
SyntaxKind[SyntaxKind["SyntaxList"] = 344] = "SyntaxList";
SyntaxKind[SyntaxKind["NotEmittedStatement"] = 345] = "NotEmittedStatement";
SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 346] = "PartiallyEmittedExpression";
SyntaxKind[SyntaxKind["CommaListExpression"] = 347] = "CommaListExpression";
SyntaxKind[SyntaxKind["SyntheticReferenceExpression"] = 348] = "SyntheticReferenceExpression";
SyntaxKind[SyntaxKind["Count"] = 349] = "Count";
SyntaxKind[SyntaxKind["JSTypeAliasDeclaration"] = 345] = "JSTypeAliasDeclaration";
SyntaxKind[SyntaxKind["JSExportAssignment"] = 346] = "JSExportAssignment";
SyntaxKind[SyntaxKind["CommonJSExport"] = 347] = "CommonJSExport";
SyntaxKind[SyntaxKind["JSImportDeclaration"] = 348] = "JSImportDeclaration";
SyntaxKind[SyntaxKind["NotEmittedStatement"] = 349] = "NotEmittedStatement";
SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 350] = "PartiallyEmittedExpression";
SyntaxKind[SyntaxKind["CommaListExpression"] = 351] = "CommaListExpression";
SyntaxKind[SyntaxKind["SyntheticReferenceExpression"] = 352] = "SyntheticReferenceExpression";
SyntaxKind[SyntaxKind["Count"] = 353] = "Count";
})(SyntaxKind || (SyntaxKind = {}));
4 changes: 2 additions & 2 deletions internal/api/encoder/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ func getChildrenPropertyMask(node *ast.Node) uint8 {
case ast.KindImportEqualsDeclaration:
n := node.AsImportEqualsDeclaration()
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.ModuleReference != nil) << 2)
case ast.KindImportDeclaration:
case ast.KindImportDeclaration, ast.KindJSImportDeclaration:
n := node.AsImportDeclaration()
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.ImportClause != nil) << 1) | (boolToByte(n.ModuleSpecifier != nil) << 2) | (boolToByte(n.Attributes != nil) << 3)
case ast.KindImportSpecifier:
Expand All @@ -468,7 +468,7 @@ func getChildrenPropertyMask(node *ast.Node) uint8 {
case ast.KindImportClause:
n := node.AsImportClause()
return (boolToByte(n.Name() != nil) << 0) | (boolToByte(n.NamedBindings != nil) << 1)
case ast.KindExportAssignment:
case ast.KindExportAssignment, ast.KindJSExportAssignment:
n := node.AsExportAssignment()
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Expression != nil) << 1)
case ast.KindNamespaceExportDeclaration:
Expand Down
40 changes: 18 additions & 22 deletions internal/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -771,12 +771,10 @@ func (n *Node) Children() *NodeList {

func (n *Node) ModuleSpecifier() *Expression {
switch n.Kind {
case KindImportDeclaration:
case KindImportDeclaration, KindJSImportDeclaration:
return n.AsImportDeclaration().ModuleSpecifier
case KindExportDeclaration:
return n.AsExportDeclaration().ModuleSpecifier
case KindJSDocImportTag:
return n.AsJSDocImportTag().ModuleSpecifier
}
panic("Unhandled case in Node.ModuleSpecifier: " + n.Kind.String())
}
Expand Down Expand Up @@ -3689,7 +3687,7 @@ type TypeAliasDeclaration struct {
Type *TypeNode // TypeNode
}

func (f *NodeFactory) newTypeOrJSTypeAliasDeclaration(kind Kind, modifiers *ModifierList, name *IdentifierNode, typeParameters *NodeList, typeNode *TypeNode) *Node {
func (f *NodeFactory) newTypeAliasOrJSTypeAliasDeclaration(kind Kind, modifiers *ModifierList, name *IdentifierNode, typeParameters *NodeList, typeNode *TypeNode) *Node {
data := &TypeAliasDeclaration{}
data.modifiers = modifiers
data.name = name
Expand All @@ -3699,12 +3697,12 @@ func (f *NodeFactory) newTypeOrJSTypeAliasDeclaration(kind Kind, modifiers *Modi
}

func (f *NodeFactory) NewTypeAliasDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *NodeList, typeNode *TypeNode) *Node {
return f.newTypeOrJSTypeAliasDeclaration(KindTypeAliasDeclaration, modifiers, name, typeParameters, typeNode)
return f.newTypeAliasOrJSTypeAliasDeclaration(KindTypeAliasDeclaration, modifiers, name, typeParameters, typeNode)
}

func (f *NodeFactory) UpdateTypeAliasDeclaration(node *TypeAliasDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, typeNode *TypeNode) *Node {
if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || typeNode != node.Type {
return updateNode(f.NewTypeAliasDeclaration(modifiers, name, typeParameters, typeNode), node.AsNode(), f.hooks)
return updateNode(f.newTypeAliasOrJSTypeAliasDeclaration(node.Kind, modifiers, name, typeParameters, typeNode), node.AsNode(), f.hooks)
}
return node.AsNode()
}
Expand All @@ -3714,14 +3712,11 @@ func (node *TypeAliasDeclaration) ForEachChild(v Visitor) bool {
}

func (node *TypeAliasDeclaration) VisitEachChild(v *NodeVisitor) *Node {
if node.Kind == KindJSTypeAliasDeclaration {
return v.Factory.UpdateJSTypeAliasDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitNode(node.Type))
}
return v.Factory.UpdateTypeAliasDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitNode(node.Type))
}

func (node *TypeAliasDeclaration) Clone(f NodeFactoryCoercible) *Node {
return cloneNode(f.AsNodeFactory().NewTypeAliasDeclaration(node.Modifiers(), node.Name(), node.TypeParameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
return cloneNode(f.AsNodeFactory().newTypeAliasOrJSTypeAliasDeclaration(node.Kind, node.Modifiers(), node.Name(), node.TypeParameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *TypeAliasDeclaration) Name() *DeclarationName { return node.name }
Expand All @@ -3735,14 +3730,7 @@ func IsTypeOrJSTypeAliasDeclaration(node *Node) bool {
}

func (f *NodeFactory) NewJSTypeAliasDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *NodeList, typeNode *TypeNode) *Node {
return f.newTypeOrJSTypeAliasDeclaration(KindJSTypeAliasDeclaration, modifiers, name, typeParameters, typeNode)
}

func (f *NodeFactory) UpdateJSTypeAliasDeclaration(node *TypeAliasDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, typeNode *TypeNode) *Node {
if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || typeNode != node.Type {
return updateNode(f.NewJSTypeAliasDeclaration(modifiers, name, typeParameters, typeNode), node.AsNode(), f.hooks)
}
return node.AsNode()
return f.newTypeAliasOrJSTypeAliasDeclaration(KindJSTypeAliasDeclaration, modifiers, name, typeParameters, typeNode)
}

func IsJSTypeAliasDeclaration(node *Node) bool {
Expand Down Expand Up @@ -4056,18 +4044,26 @@ type ImportDeclaration struct {
Attributes *ImportAttributesNode // ImportAttributesNode. Optional
}

func (f *NodeFactory) NewImportDeclaration(modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node {
func (f *NodeFactory) newImportOrJSImportDeclaration(kind Kind, modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node {
data := &ImportDeclaration{}
data.modifiers = modifiers
data.ImportClause = importClause
data.ModuleSpecifier = moduleSpecifier
data.Attributes = attributes
return f.newNode(KindImportDeclaration, data)
return f.newNode(kind, data)
}

func (f *NodeFactory) NewImportDeclaration(modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node {
return f.newImportOrJSImportDeclaration(KindImportDeclaration, modifiers, importClause, moduleSpecifier, attributes)
}

func (f *NodeFactory) NewJSImportDeclaration(modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node {
return f.newImportOrJSImportDeclaration(KindJSImportDeclaration, modifiers, importClause, moduleSpecifier, attributes)
}

func (f *NodeFactory) UpdateImportDeclaration(node *ImportDeclaration, modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node {
if modifiers != node.modifiers || importClause != node.ImportClause || moduleSpecifier != node.ModuleSpecifier || attributes != node.Attributes {
return updateNode(f.NewImportDeclaration(modifiers, importClause, moduleSpecifier, attributes), node.AsNode(), f.hooks)
return updateNode(f.newImportOrJSImportDeclaration(node.Kind, modifiers, importClause, moduleSpecifier, attributes), node.AsNode(), f.hooks)
}
return node.AsNode()
}
Expand All @@ -4081,7 +4077,7 @@ func (node *ImportDeclaration) VisitEachChild(v *NodeVisitor) *Node {
}

func (node *ImportDeclaration) Clone(f NodeFactoryCoercible) *Node {
return cloneNode(f.AsNodeFactory().NewImportDeclaration(node.Modifiers(), node.ImportClause, node.ModuleSpecifier, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks)
return cloneNode(f.AsNodeFactory().newImportOrJSImportDeclaration(node.Kind, node.Modifiers(), node.ImportClause, node.ModuleSpecifier, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ImportDeclaration) computeSubtreeFacts() SubtreeFacts {
Expand Down
1 change: 1 addition & 0 deletions internal/ast/kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ const (
KindJSTypeAliasDeclaration
KindJSExportAssignment
KindCommonJSExport
KindJSImportDeclaration
Copy link
Member

@andrewbranch andrewbranch May 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don’t yet have codegen in place, can you update _packages/ast/src/syntaxKind.ts and _packages/ast/src/syntaxKind.enum.ts?

// Transformation nodes
KindNotEmittedStatement
KindPartiallyEmittedExpression
Expand Down
Loading