diff --git a/Herebyfile.mjs b/Herebyfile.mjs index f1dedaa84903f..2a93e6116eb8a 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -805,6 +805,9 @@ function goTestFlags(taskName) { ...goBuildFlags, ...goBuildTags(), ...(options.tests ? [`-run=${options.tests}`] : []), + // Go 1.27 duplicates promoted AST wrappers, exhausting CI disk under coverage. + // Tests strip DWARF when linking; omit it earlier to shrink temporary and cached archives. + ...(options.coverage && !options.debug ? ["-gcflags=all=-dwarf=false"] : []), ...(options.coverage ? [`-coverprofile=${path.join(coverageDir, "coverage." + taskName + ".out")}`, "-coverpkg=./..."] : []), ]; } diff --git a/tools/customlint/plugin.go b/tools/customlint/plugin.go index fd9c5b9e7dfce..677f1a0d9012a 100644 --- a/tools/customlint/plugin.go +++ b/tools/customlint/plugin.go @@ -22,6 +22,7 @@ func (f *plugin) BuildAnalyzers() ([]*analysis.Analyzer, error) { forbidParentAccessAnalyzer, shadowAnalyzer, typedPathsAnalyzer, + unsafeLayoutAnalyzer, unexportedAPIAnalyzer, }, nil } diff --git a/tools/customlint/testdata/unsafelayout/consumer/consumer.go b/tools/customlint/testdata/unsafelayout/consumer/consumer.go new file mode 100644 index 0000000000000..17e3ccd569881 --- /dev/null +++ b/tools/customlint/testdata/unsafelayout/consumer/consumer.go @@ -0,0 +1,45 @@ +package consumer + +import ( + "unsafe" + + "testdata/unsafelayout/internal/ast" + "testdata/unsafelayout/internal/checker" +) + +type BadNode ast.Node + +type NodeAlias = ast.Node + +type BorrowedNode struct { + *ast.Node +} + +func uses(node *ast.Node, declaration *ast.ImportDeclaration, kind ast.Kind, typ *checker.Type) { + node.Kind = ast.KindIdentifier + declaration.Kind = ast.KindImportDeclaration + declaration.Kind = ast.KindJSImportDeclaration + node.AsImportDeclaration().Kind = ast.KindImportDeclaration + declaration.Kind = ast.KindIdentifier + declaration.Kind = kind + declaration.Kind++ + _ = &node.Kind + _ = &ast.Node{Kind: ast.KindIdentifier} + _ = &ast.Identifier{} + _ = new(ast.Node) + _ = new(ast.Identifier) + _ = new(NodeAlias) + _ = unsafe.Sizeof(ast.Node{}) + _ = unsafe.Offsetof(ast.Identifier{}.Node) + _ = (*ast.Identifier)(unsafe.Pointer(node)) + _ = *node + _ = *declaration + _ = *typ + copy := *node + _ = copy + pointer := unsafe.Pointer(node) + _ = pointer + borrowed := BorrowedNode{Node: node} + borrowed.Kind = ast.KindIdentifier + _ = &borrowed.Kind +} diff --git a/tools/customlint/testdata/unsafelayout/consumer/consumer.go.golden b/tools/customlint/testdata/unsafelayout/consumer/consumer.go.golden new file mode 100644 index 0000000000000..496120266c21f --- /dev/null +++ b/tools/customlint/testdata/unsafelayout/consumer/consumer.go.golden @@ -0,0 +1,102 @@ + package consumer + + import ( + "unsafe" + + "testdata/unsafelayout/internal/ast" + "testdata/unsafelayout/internal/checker" + ) + + type BadNode ast.Node + ~ +!!! unsafelayout: defining a new compiler-record type bypasses checked construction; use a type alias + + type NodeAlias = ast.Node + + type BorrowedNode struct { + *ast.Node + } + + func uses(node *ast.Node, declaration *ast.ImportDeclaration, kind ast.Kind, typ *checker.Type) { + node.Kind = ast.KindIdentifier + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + declaration.Kind = ast.KindImportDeclaration + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + declaration.Kind = ast.KindJSImportDeclaration + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + node.AsImportDeclaration().Kind = ast.KindImportDeclaration + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + declaration.Kind = ast.KindIdentifier + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + declaration.Kind = kind + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + declaration.Kind++ + ~ +!!! unsafelayout: incrementing a compiler tag bypasses checked tag assignment + _ = &node.Kind + ~ +!!! unsafelayout: taking a compiler tag's address bypasses checked tag assignment + _ = &ast.Node{Kind: ast.KindIdentifier} + ~ +!!! unsafelayout: a bare compiler header has no concrete payload; use a concrete factory + ~ +!!! unsafelayout: construct compiler records through their owning factories, not struct literals + ~ +!!! unsafelayout: compiler tags must be assigned by checked construction, not struct literals + _ = &ast.Identifier{} + ~ +!!! unsafelayout: construct compiler records through their owning factories, not struct literals + _ = new(ast.Node) + ~ +!!! unsafelayout: a bare compiler header has no concrete payload; use a concrete factory + ~ +!!! unsafelayout: allocate compiler records through their owning factories + _ = new(ast.Identifier) + ~ +!!! unsafelayout: allocate compiler records through their owning factories + _ = new(NodeAlias) + ~ +!!! unsafelayout: a bare compiler header has no concrete payload; use a concrete factory + ~ +!!! unsafelayout: allocate compiler records through their owning factories + _ = unsafe.Sizeof(ast.Node{}) + _ = unsafe.Offsetof(ast.Identifier{}.Node) + _ = (*ast.Identifier)(unsafe.Pointer(node)) + ~ +!!! unsafelayout: reinterpret compiler records only through checked casts or generated AST dispatch + ~ +!!! unsafelayout: reinterpret compiler records only through checked casts or generated AST dispatch + _ = *node + ~ +!!! unsafelayout: copying a compiler record by value can detach its tagged header; keep a pointer + _ = *declaration + ~ +!!! unsafelayout: copying a compiler record by value can detach its tagged header; keep a pointer + _ = *typ + ~ +!!! unsafelayout: copying a compiler record by value can detach its tagged header; keep a pointer + copy := *node + ~ +!!! unsafelayout: copying a compiler record by value can detach its tagged header; keep a pointer + _ = copy + ~ +!!! unsafelayout: copying a compiler record by value can detach its tagged header; keep a pointer + pointer := unsafe.Pointer(node) + ~ +!!! unsafelayout: reinterpret compiler records only through checked casts or generated AST dispatch + _ = pointer + borrowed := BorrowedNode{Node: node} + borrowed.Kind = ast.KindIdentifier + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + _ = &borrowed.Kind + ~ +!!! unsafelayout: taking a compiler tag's address bypasses checked tag assignment + } + diff --git a/tools/customlint/testdata/unsafelayout/internal/ast/ast.go b/tools/customlint/testdata/unsafelayout/internal/ast/ast.go new file mode 100644 index 0000000000000..82a96cf19a39f --- /dev/null +++ b/tools/customlint/testdata/unsafelayout/internal/ast/ast.go @@ -0,0 +1,94 @@ +package ast + +type Kind int16 + +const ( + KindIdentifier Kind = iota + KindImportDeclaration + KindJSImportDeclaration +) + +type Node struct { + Kind Kind +} + +type Identifier struct { + Node + Text string +} + +type ImportDeclaration struct { + Node +} + +func (n *Node) AsNode() *Node { return n } + +func (n *Node) AsIdentifier() *Identifier { + if n.Kind != KindIdentifier { + panic("Invalid node cast") + } + return nil +} + +func (n *Node) AsImportDeclaration() *ImportDeclaration { + switch n.Kind { + case KindImportDeclaration, KindJSImportDeclaration: + return nil + default: + panic("Invalid node cast") + } +} + +func newNode(kind Kind, node *Node) *Node { + node.Kind = kind + return node +} + +func NewIdentifier(text string) *Node { + data := &Identifier{Text: text} + return newNode(KindIdentifier, data.AsNode()) +} + +func badFactory() *Node { + data := &ImportDeclaration{} + return newNode(KindIdentifier, data.AsNode()) +} + +func escapes(kind Kind) *Node { + data := &Identifier{} + _ = newNode + return newNode(kind, data.AsNode()) +} + +type PretendIdentifier struct { + Identifier +} + +func (n *PretendIdentifier) AsNode() *Node { return &n.Node } + +func shadowedUpcast() *Node { + data := &PretendIdentifier{} + return newNode(KindIdentifier, data.AsNode()) +} + +func illegalWrites(node *Node, identifier *Identifier, declaration *ImportDeclaration, kind Kind) { + node.Kind = KindIdentifier + identifier.Kind = KindIdentifier + identifier.Kind = KindImportDeclaration + declaration.Kind = KindImportDeclaration + declaration.Kind = KindJSImportDeclaration + declaration.Kind = kind + declaration.Kind += KindImportDeclaration + node.Kind++ + _ = &node.Kind + (node.Kind) = KindIdentifier + (node.Kind)++ + _ = &(node.Kind) +} + +func freshNodes() *Node { + tagged := &Identifier{} + tagged.Text = "x" + _ = newNode(KindIdentifier, tagged.AsNode()) + return (&Identifier{}).AsNode() +} diff --git a/tools/customlint/testdata/unsafelayout/internal/ast/ast.go.golden b/tools/customlint/testdata/unsafelayout/internal/ast/ast.go.golden new file mode 100644 index 0000000000000..99174158187e6 --- /dev/null +++ b/tools/customlint/testdata/unsafelayout/internal/ast/ast.go.golden @@ -0,0 +1,129 @@ + package ast + + type Kind int16 + + const ( + KindIdentifier Kind = iota + KindImportDeclaration + KindJSImportDeclaration + ) + + type Node struct { + Kind Kind + } + + type Identifier struct { + Node + Text string + } + + type ImportDeclaration struct { + Node + } + + func (n *Node) AsNode() *Node { return n } + + func (n *Node) AsIdentifier() *Identifier { + if n.Kind != KindIdentifier { + panic("Invalid node cast") + } + return nil + } + + func (n *Node) AsImportDeclaration() *ImportDeclaration { + switch n.Kind { + case KindImportDeclaration, KindJSImportDeclaration: + return nil + default: + panic("Invalid node cast") + } + } + + func newNode(kind Kind, node *Node) *Node { + node.Kind = kind + return node + } + + func NewIdentifier(text string) *Node { + data := &Identifier{Text: text} + return newNode(KindIdentifier, data.AsNode()) + } + + func badFactory() *Node { + data := &ImportDeclaration{} + return newNode(KindIdentifier, data.AsNode()) + ~ +!!! unsafelayout: newNode must pair a concrete AsNode() receiver with a compatible kind + } + + func escapes(kind Kind) *Node { + data := &Identifier{} + _ = newNode + ~ +!!! unsafelayout: checked construction must be called directly so its allocation/tag pairing can be verified + return newNode(kind, data.AsNode()) + ~ +!!! unsafelayout: newNode must pair a concrete AsNode() receiver with a compatible kind + } + + type PretendIdentifier struct { + Identifier + } + + func (n *PretendIdentifier) AsNode() *Node { return &n.Node } + + func shadowedUpcast() *Node { + data := &PretendIdentifier{} + return newNode(KindIdentifier, data.AsNode()) + ~ +!!! unsafelayout: newNode must pair a concrete AsNode() receiver with a compatible kind + } + + func illegalWrites(node *Node, identifier *Identifier, declaration *ImportDeclaration, kind Kind) { + node.Kind = KindIdentifier + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + identifier.Kind = KindIdentifier + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + identifier.Kind = KindImportDeclaration + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + declaration.Kind = KindImportDeclaration + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + declaration.Kind = KindJSImportDeclaration + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + declaration.Kind = kind + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + declaration.Kind += KindImportDeclaration + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + node.Kind++ + ~ +!!! unsafelayout: incrementing a compiler tag bypasses checked tag assignment + _ = &node.Kind + ~ +!!! unsafelayout: taking a compiler tag's address bypasses checked tag assignment + (node.Kind) = KindIdentifier + ~ +!!! unsafelayout: AST kind is immutable outside checked construction; create a new node + (node.Kind)++ + ~ +!!! unsafelayout: incrementing a compiler tag bypasses checked tag assignment + _ = &(node.Kind) + ~ +!!! unsafelayout: taking a compiler tag's address bypasses checked tag assignment + } + + func freshNodes() *Node { + tagged := &Identifier{} + tagged.Text = "x" + _ = newNode(KindIdentifier, tagged.AsNode()) + return (&Identifier{}).AsNode() + ~ +!!! unsafelayout: a fresh compiler record must be checked-constructed before it escapes + } + diff --git a/tools/customlint/testdata/unsafelayout/internal/checker/checker.go b/tools/customlint/testdata/unsafelayout/internal/checker/checker.go new file mode 100644 index 0000000000000..4fb4c6e485363 --- /dev/null +++ b/tools/customlint/testdata/unsafelayout/internal/checker/checker.go @@ -0,0 +1,141 @@ +package checker + +import "unsafe" + +type typeKind uint8 + +const ( + typeKindLiteral typeKind = iota + typeKindObject +) + +type Type struct { + kind typeKind +} + +type LiteralType struct { + TypeBase +} + +type ObjectType struct { + TypeBase +} + +type TypeBase struct { + Type +} + +func (t *TypeBase) AsType() *Type { return &t.Type } + +type Checker struct{} + +func (c *Checker) newType(flags, objectFlags int, typ *Type, kind typeKind) *Type { + typ.kind = kind + return typ +} + +func castType[T any](t *Type, kind typeKind) *T { + if t.kind != kind { + panic("Invalid type cast") + } + return (*T)(unsafe.Pointer(t)) +} + +func calls(c *Checker, literal *LiteralType, typ *Type, kind typeKind) { + c.newType(0, 0, literal.AsType(), typeKindLiteral) + c.newType(0, 0, literal.AsType(), typeKindObject) + c.newType(0, 0, literal.AsType(), kind) + c.newType(0, 0, typ, typeKindLiteral) + _ = c.newType + _ = castType[LiteralType](typ, typeKindLiteral) + _ = castType[LiteralType](typ, typeKindObject) + _ = castType[ObjectType](typ, typeKindLiteral) + _ = castType[LiteralType](typ, kind) + _ = castType[*LiteralType](typ, typeKindLiteral) + _ = castType[LiteralType] + typ.kind = typeKindLiteral + typ.kind++ + _ = &typ.kind + _ = (*LiteralType)(unsafe.Pointer(typ)) +} + +type PretendLiteralType struct { + LiteralType +} + +func (t *PretendLiteralType) AsType() *Type { return &t.Type } + +func shadowedUpcast(c *Checker) { + data := &PretendLiteralType{} + c.newType(0, 0, data.AsType(), typeKindLiteral) +} + +type typeMapperKind uint8 + +const ( + typeMapperSimple typeMapperKind = iota + typeMapperArray +) + +type TypeMapper struct { + kind typeMapperKind +} + +type SimpleTypeMapper struct { + TypeMapper +} + +type ArrayTypeMapper struct { + TypeMapper +} + +func castTypeMapper[T any](m *TypeMapper, kind typeMapperKind) *T { + if m.kind != kind { + panic("Invalid type mapper cast") + } + return (*T)(unsafe.Pointer(m)) +} + +func mapperCalls(simple *SimpleTypeMapper, header *TypeMapper) { + simple.kind = typeMapperSimple + simple.kind = typeMapperArray + header.kind = typeMapperSimple + _ = castTypeMapper[SimpleTypeMapper](header, typeMapperSimple) + _ = castTypeMapper[SimpleTypeMapper](header, typeMapperArray) + _ = (*SimpleTypeMapper)(unsafe.Pointer(header)) +} + +func freshRecords(c *Checker) *Type { + tagged := &LiteralType{} + c.newType(0, 0, tagged.AsType(), typeKindLiteral) + _ = (&LiteralType{}).AsType() + escaped := &LiteralType{} + c.newType(0, 0, escaped.AsType(), typeKindLiteral) + _ = escaped.AsType() + header := &ObjectType{} + _ = &header.TypeBase + c.newType(0, 0, header.AsType(), typeKindObject) + unused := &ObjectType{} + _ = unused + value := LiteralType{} + _ = value + return new(LiteralType).AsType() +} + +func freshMappers() (*TypeMapper, *TypeMapper) { + tagged := &SimpleTypeMapper{} + tagged.kind = typeMapperSimple + untagged := &ArrayTypeMapper{} + return &tagged.TypeMapper, &untagged.TypeMapper +} + +type arena[T any] struct{} + +func (a *arena[T]) New() *T { return new(T) } + +func arenaRecords(c *Checker, literals *arena[LiteralType]) *LiteralType { + c.newType(0, 0, literals.New().AsType(), typeKindLiteral) + data := literals.New() + c.newType(0, 0, data.AsType(), typeKindLiteral) + return literals.New() +} diff --git a/tools/customlint/testdata/unsafelayout/internal/checker/checker.go.golden b/tools/customlint/testdata/unsafelayout/internal/checker/checker.go.golden new file mode 100644 index 0000000000000..b34837639a324 --- /dev/null +++ b/tools/customlint/testdata/unsafelayout/internal/checker/checker.go.golden @@ -0,0 +1,200 @@ + package checker + + import "unsafe" + + type typeKind uint8 + + const ( + typeKindLiteral typeKind = iota + typeKindObject + ) + + type Type struct { + kind typeKind + } + + type LiteralType struct { + TypeBase + } + + type ObjectType struct { + TypeBase + } + + type TypeBase struct { + Type + } + + func (t *TypeBase) AsType() *Type { return &t.Type } + + type Checker struct{} + + func (c *Checker) newType(flags, objectFlags int, typ *Type, kind typeKind) *Type { + typ.kind = kind + return typ + } + + func castType[T any](t *Type, kind typeKind) *T { + if t.kind != kind { + panic("Invalid type cast") + } + return (*T)(unsafe.Pointer(t)) + } + + func calls(c *Checker, literal *LiteralType, typ *Type, kind typeKind) { + c.newType(0, 0, literal.AsType(), typeKindLiteral) + c.newType(0, 0, literal.AsType(), typeKindObject) + ~ +!!! unsafelayout: newType must directly pair a concrete AsType() receiver with its matching constant kind + c.newType(0, 0, literal.AsType(), kind) + ~ +!!! unsafelayout: newType must directly pair a concrete AsType() receiver with its matching constant kind + c.newType(0, 0, typ, typeKindLiteral) + ~ +!!! unsafelayout: newType must directly pair a concrete AsType() receiver with its matching constant kind + _ = c.newType + ~ +!!! unsafelayout: checked construction must be called directly so its allocation/tag pairing can be verified + _ = castType[LiteralType](typ, typeKindLiteral) + _ = castType[LiteralType](typ, typeKindObject) + ~ +!!! unsafelayout: checked cast must directly pair its concrete target type with its matching constant kind + _ = castType[ObjectType](typ, typeKindLiteral) + ~ +!!! unsafelayout: checked cast must directly pair its concrete target type with its matching constant kind + _ = castType[LiteralType](typ, kind) + ~ +!!! unsafelayout: checked cast must directly pair its concrete target type with its matching constant kind + _ = castType[*LiteralType](typ, typeKindLiteral) + ~ +!!! unsafelayout: checked cast must directly pair its concrete target type with its matching constant kind + _ = castType[LiteralType] + ~ +!!! unsafelayout: checked cast must directly pair its concrete target type with its matching constant kind + typ.kind = typeKindLiteral + ~ +!!! unsafelayout: type kind is immutable outside checked construction + typ.kind++ + ~ +!!! unsafelayout: incrementing a compiler tag bypasses checked tag assignment + _ = &typ.kind + ~ +!!! unsafelayout: taking a compiler tag's address bypasses checked tag assignment + _ = (*LiteralType)(unsafe.Pointer(typ)) + ~ +!!! unsafelayout: reinterpret compiler records only through checked casts or generated AST dispatch + ~ +!!! unsafelayout: reinterpret compiler records only through checked casts or generated AST dispatch + } + + type PretendLiteralType struct { + LiteralType + } + + func (t *PretendLiteralType) AsType() *Type { return &t.Type } + + func shadowedUpcast(c *Checker) { + data := &PretendLiteralType{} + c.newType(0, 0, data.AsType(), typeKindLiteral) + ~ +!!! unsafelayout: newType must directly pair a concrete AsType() receiver with its matching constant kind + } + + type typeMapperKind uint8 + + const ( + typeMapperSimple typeMapperKind = iota + typeMapperArray + ) + + type TypeMapper struct { + kind typeMapperKind + } + + type SimpleTypeMapper struct { + TypeMapper + } + + type ArrayTypeMapper struct { + TypeMapper + } + + func castTypeMapper[T any](m *TypeMapper, kind typeMapperKind) *T { + if m.kind != kind { + panic("Invalid type mapper cast") + } + return (*T)(unsafe.Pointer(m)) + } + + func mapperCalls(simple *SimpleTypeMapper, header *TypeMapper) { + simple.kind = typeMapperSimple + simple.kind = typeMapperArray + ~ +!!! unsafelayout: mapper tag must match the concrete mapper allocation + header.kind = typeMapperSimple + ~ +!!! unsafelayout: mapper tag must match the concrete mapper allocation + _ = castTypeMapper[SimpleTypeMapper](header, typeMapperSimple) + _ = castTypeMapper[SimpleTypeMapper](header, typeMapperArray) + ~ +!!! unsafelayout: checked cast must directly pair its concrete target type with its matching constant kind + _ = (*SimpleTypeMapper)(unsafe.Pointer(header)) + ~ +!!! unsafelayout: reinterpret compiler records only through checked casts or generated AST dispatch + ~ +!!! unsafelayout: reinterpret compiler records only through checked casts or generated AST dispatch + } + + func freshRecords(c *Checker) *Type { + tagged := &LiteralType{} + c.newType(0, 0, tagged.AsType(), typeKindLiteral) + _ = (&LiteralType{}).AsType() + ~ +!!! unsafelayout: a fresh compiler record must be checked-constructed before it escapes + escaped := &LiteralType{} + ~ +!!! unsafelayout: a fresh compiler record must be checked-constructed before it escapes + c.newType(0, 0, escaped.AsType(), typeKindLiteral) + _ = escaped.AsType() + header := &ObjectType{} + ~ +!!! unsafelayout: a fresh compiler record must be checked-constructed before it escapes + _ = &header.TypeBase + c.newType(0, 0, header.AsType(), typeKindObject) + unused := &ObjectType{} + ~ +!!! unsafelayout: a fresh compiler record must be checked-constructed before it escapes + _ = unused + value := LiteralType{} + ~ +!!! unsafelayout: allocate compiler records by pointer so checked construction can tag them + _ = value + ~ +!!! unsafelayout: copying a compiler record by value can detach its tagged header; keep a pointer + return new(LiteralType).AsType() + ~ +!!! unsafelayout: a fresh compiler record must be checked-constructed before it escapes + } + + func freshMappers() (*TypeMapper, *TypeMapper) { + tagged := &SimpleTypeMapper{} + tagged.kind = typeMapperSimple + untagged := &ArrayTypeMapper{} + ~ +!!! unsafelayout: a fresh mapper must be tagged by the statement after its allocation + return &tagged.TypeMapper, &untagged.TypeMapper + } + + type arena[T any] struct{} + + func (a *arena[T]) New() *T { return new(T) } + + func arenaRecords(c *Checker, literals *arena[LiteralType]) *LiteralType { + c.newType(0, 0, literals.New().AsType(), typeKindLiteral) + data := literals.New() + c.newType(0, 0, data.AsType(), typeKindLiteral) + return literals.New() + ~ +!!! unsafelayout: a fresh compiler record must be checked-constructed before it escapes + } + diff --git a/tools/customlint/unsafelayout.go b/tools/customlint/unsafelayout.go new file mode 100644 index 0000000000000..69f410a600620 --- /dev/null +++ b/tools/customlint/unsafelayout.go @@ -0,0 +1,636 @@ +package customlint + +import ( + "go/ast" + "go/constant" + "go/token" + "go/types" + "path/filepath" + "slices" + "strings" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/ast/inspector" +) + +var unsafeLayoutAnalyzer = &analysis.Analyzer{ + Name: "unsafelayout", + Doc: "enforces construction, immutable tags, and checked casts for compiler records", + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: func(pass *analysis.Pass) (any, error) { + in := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + p := unsafeLayoutPass{pass: pass} + p.collectNodeLayouts() + for c := range in.Root().Preorder( + (*ast.AssignStmt)(nil), (*ast.IncDecStmt)(nil), (*ast.UnaryExpr)(nil), (*ast.CompositeLit)(nil), + (*ast.CallExpr)(nil), (*ast.IndexExpr)(nil), (*ast.TypeSpec)(nil), + (*ast.StarExpr)(nil), (*ast.SelectorExpr)(nil), (*ast.Ident)(nil), + ) { + p.check(c) + } + return nil, nil + }, +} + +type unsafeLayoutPass struct { + pass *analysis.Pass + nodeLayouts map[*types.TypeName][]int64 +} + +func (p *unsafeLayoutPass) collectNodeLayouts() { + if !strings.HasSuffix(p.pass.Pkg.Path(), "/internal/ast") { + return + } + p.nodeLayouts = make(map[*types.TypeName][]int64) + for _, file := range p.pass.Files { + for _, declaration := range file.Decls { + fn, ok := declaration.(*ast.FuncDecl) + if !ok || fn.Recv == nil || !strings.HasPrefix(fn.Name.Name, "As") { + continue + } + function, _ := p.pass.TypesInfo.Defs[fn.Name].(*types.Func) + if function == nil { + continue + } + signature := function.Type().(*types.Signature) + if signature.Results().Len() != 1 { + continue + } + target := layoutNamedType(signature.Results().At(0).Type()) + if target == nil || layoutFamily(target) != "Node" || fn.Name.Name != "As"+target.Obj().Name() { + continue + } + var kinds []int64 + ast.Inspect(fn.Body, func(node ast.Node) bool { + if expr, isIdentifier := node.(*ast.Ident); isIdentifier { + if value, isConstant := p.pass.TypesInfo.Uses[expr].(*types.Const); isConstant && + value.Pkg() == p.pass.Pkg && layoutNamedType(value.Type()) != nil && + layoutNamedType(value.Type()).Obj().Name() == "Kind" { + if kind, isInteger := constant.Int64Val(value.Val()); isInteger { + kinds = append(kinds, kind) + } + } + } + return true + }) + if len(kinds) != 0 { + p.nodeLayouts[target.Obj()] = kinds + } + } + } +} + +func (p *unsafeLayoutPass) matchingNodeKind(typ types.Type, expr ast.Expr) bool { + named := layoutNamedType(typ) + if named == nil { + return false + } + value := p.pass.TypesInfo.Types[expr].Value + if value == nil || value.Kind() != constant.Int { + return false + } + kind, ok := constant.Int64Val(value) + if !ok { + return false + } + return slices.Contains(p.nodeLayouts[named.Obj()], kind) +} + +func layoutNamedType(typ types.Type) *types.Named { + if typ == nil { + return nil + } + if pointer, ok := types.Unalias(typ).(*types.Pointer); ok { + typ = pointer.Elem() + } + return namedType(typ) +} + +func layoutFamily(typ types.Type) string { + named := layoutNamedType(typ) + if named == nil || named.Obj().Pkg() == nil { + return "" + } + path := named.Obj().Pkg().Path() + if strings.HasSuffix(path, "/internal/ast") && (named.Obj().Name() == "Node" || named.Obj().Name() == "MutableNode") { + return "Node" + } + if strings.HasSuffix(path, "/internal/checker") { + switch named.Obj().Name() { + case "Type", "TypeMapper": + return named.Obj().Name() + } + } + if structure, ok := named.Underlying().(*types.Struct); ok && structure.NumFields() != 0 && structure.Field(0).Embedded() { + if _, pointer := types.Unalias(structure.Field(0).Type()).(*types.Pointer); !pointer { + return layoutFamily(structure.Field(0).Type()) + } + } + return "" +} + +func layoutKind(typ types.Type) *types.Const { + named := layoutNamedType(typ) + if named == nil || named.Obj().Pkg() == nil { + return nil + } + var name string + switch layoutFamily(typ) { + case "Type": + name = "typeKind" + strings.TrimSuffix(named.Obj().Name(), "Type") + case "TypeMapper": + name = "typeMapper" + strings.TrimSuffix(named.Obj().Name(), "TypeMapper") + default: + return nil + } + kind, _ := named.Obj().Pkg().Scope().Lookup(name).(*types.Const) + return kind +} + +func (p *unsafeLayoutPass) matchingKind(typ types.Type, expr ast.Expr) bool { + kind := layoutKind(typ) + value := p.pass.TypesInfo.Types[expr].Value + return kind != nil && value != nil && types.Identical(kind.Type(), p.pass.TypesInfo.TypeOf(expr)) && + constant.Compare(kind.Val(), token.EQL, value) +} + +func layoutFunction(c inspector.Cursor) *ast.FuncDecl { + for parent := c.Parent(); parent.Node() != nil; parent = parent.Parent() { + switch node := parent.Node().(type) { + case *ast.FuncLit: + return nil + case *ast.FuncDecl: + return node + } + } + return nil +} + +func (p *unsafeLayoutPass) ownerFunction(c inspector.Cursor, family, name string) bool { + fn := layoutFunction(c) + if fn == nil || fn.Name.Name != name { + return false + } + pkg := "/internal/checker" + if family == "Node" { + pkg = "/internal/ast" + } + if !strings.HasSuffix(p.pass.Pkg.Path(), pkg) { + return false + } + function, _ := p.pass.TypesInfo.Defs[fn.Name].(*types.Func) + if function == nil { + return false + } + signature := function.Type().(*types.Signature) + switch name { + case "castType", "castTypeMapper": + return signature.Recv() == nil + case "newNode": + return signature.Recv() == nil || + layoutNamedType(signature.Recv().Type()).Obj().Name() == "NodeFactory" + case "newType": + return signature.Recv() != nil && + layoutNamedType(signature.Recv().Type()).Obj().Name() == "Checker" + default: + return signature.Recv() != nil && layoutNamedType(signature.Recv().Type()).Obj().Name() == family + } +} + +func (p *unsafeLayoutPass) check(c inspector.Cursor) { + node := c.Node() + // Tests use detached metadata stubs; checked-cast pairing still applies. + test := strings.HasSuffix(p.pass.Fset.Position(node.Pos()).Filename, "_test.go") + switch node := node.(type) { + case *ast.TypeSpec: + if !node.Assign.IsValid() && layoutFamily(p.pass.TypesInfo.TypeOf(node.Type)) != "" { + // MutableNode changes the method set without changing the header layout. + if node.Name.Name != "MutableNode" || !strings.HasSuffix(p.pass.Pkg.Path(), "/internal/ast") { + p.pass.Reportf(node.Pos(), "defining a new compiler-record type bypasses checked construction; use a type alias") + } + } + case *ast.IndexExpr: + if function, ok := node.X.(*ast.Ident); ok { + object, _ := p.pass.TypesInfo.Uses[function].(*types.Func) + if object != nil && strings.HasSuffix(object.Pkg().Path(), "/internal/checker") && + (object.Name() == "castType" || object.Name() == "castTypeMapper") { + call, ok := c.Parent().Node().(*ast.CallExpr) + if !ok || call.Fun != node || len(call.Args) != 2 || namedType(p.pass.TypesInfo.TypeOf(node.Index)) == nil || + !p.matchingKind(p.pass.TypesInfo.TypeOf(node.Index), call.Args[1]) { + p.pass.Reportf(node.Pos(), "checked cast must directly pair its concrete target type with its matching constant kind") + } + } + } + case *ast.AssignStmt: + if test { + return + } + for _, lhs := range node.Lhs { + if selector, ok := ast.Unparen(lhs).(*ast.SelectorExpr); ok { + p.checkTagWrite(c, selector, node) + } + } + case *ast.IncDecStmt: + if selector, ok := ast.Unparen(node.X).(*ast.SelectorExpr); ok && p.protectedTag(selector) && !test { + p.pass.Reportf(node.Pos(), "incrementing a compiler tag bypasses checked tag assignment") + } + case *ast.UnaryExpr: + if node.Op == token.AND { + if selector, ok := ast.Unparen(node.X).(*ast.SelectorExpr); ok && p.protectedTag(selector) && !test { + p.pass.Reportf(node.Pos(), "taking a compiler tag's address bypasses checked tag assignment") + } + } + case *ast.CompositeLit: + if test || layoutFamily(p.pass.TypesInfo.TypeOf(node)) == "" || p.layoutConstant(c) { + return + } + family := layoutFamily(p.pass.TypesInfo.TypeOf(node)) + named := layoutNamedType(p.pass.TypesInfo.TypeOf(node)) + if named.Obj().Name() == family || named.Obj().Name() == "MutableNode" { + p.pass.Reportf(node.Pos(), "a bare compiler header has no concrete payload; use a concrete factory") + } + owner := "/internal/checker" + if family == "Node" { + owner = "/internal/ast" + } + if !strings.HasSuffix(p.pass.Pkg.Path(), owner) { + p.pass.Reportf(node.Pos(), "construct compiler records through their owning factories, not struct literals") + } else if unary, ok := c.Parent().Node().(*ast.UnaryExpr); ok && unary.Op == token.AND { + p.checkFreshRecord(c.Parent(), family) + } else { + p.pass.Reportf(node.Pos(), "allocate compiler records by pointer so checked construction can tag them") + } + for _, element := range node.Elts { + if field, ok := element.(*ast.KeyValueExpr); ok { + if key, ok := field.Key.(*ast.Ident); ok && (key.Name == "kind" || key.Name == "Kind") { + p.pass.Reportf(field.Pos(), "compiler tags must be assigned by checked construction, not struct literals") + } + } + } + case *ast.CallExpr: + p.checkCall(c, node, test) + case *ast.StarExpr, *ast.SelectorExpr, *ast.Ident: + var object *types.Func + switch expr := node.(type) { + case *ast.SelectorExpr: + object, _ = p.pass.TypesInfo.Uses[expr.Sel].(*types.Func) + case *ast.Ident: + object, _ = p.pass.TypesInfo.Uses[expr].(*types.Func) + } + if object != nil && object.Pkg() != nil && + ((strings.HasSuffix(object.Pkg().Path(), "/internal/checker") && object.Name() == "newType") || + (strings.HasSuffix(object.Pkg().Path(), "/internal/ast") && object.Name() == "newNode")) { + call, ok := c.Parent().Node().(*ast.CallExpr) + if !ok || call.Fun != node { + // The selector's identifier is visited separately. + if selector, ok := c.Parent().Node().(*ast.SelectorExpr); !ok || selector.Sel != node { + p.pass.Reportf(node.Pos(), "checked construction must be called directly so its allocation/tag pairing can be verified") + } + } + } + if test { + return + } + expr := node.(ast.Expr) + value := p.pass.TypesInfo.Types[expr] + if value.IsType() || value.Type == nil { + return + } + if _, pointer := types.Unalias(value.Type).(*types.Pointer); pointer || layoutFamily(value.Type) == "" || p.layoutConstant(c) { + return + } + switch parent := c.Parent().Node().(type) { + case *ast.SelectorExpr: + if parent.X == expr { + return + } + case *ast.UnaryExpr: + if parent.Op == token.AND { + return + } + } + p.pass.Reportf(expr.Pos(), "copying a compiler record by value can detach its tagged header; keep a pointer") + } +} + +func (p *unsafeLayoutPass) protectedTag(selector *ast.SelectorExpr) bool { + return p.tagFamily(selector) != "" +} + +func (p *unsafeLayoutPass) tagFamily(selector *ast.SelectorExpr) string { + selection := p.pass.TypesInfo.Selections[selector] + if selection == nil || selection.Obj().Pkg() == nil { + return "" + } + field := selection.Obj() + if field.Name() != "Kind" && field.Name() != "kind" { + return "" + } + for _, family := range []string{"Node", "Type", "TypeMapper"} { + object := field.Pkg().Scope().Lookup(family) + if object == nil || layoutFamily(object.Type()) != family { + continue + } + structure := object.Type().Underlying().(*types.Struct) + for variable := range structure.Fields() { + if variable == field { + return family + } + } + } + return "" +} + +func (p *unsafeLayoutPass) checkTagWrite(c inspector.Cursor, selector *ast.SelectorExpr, assignment *ast.AssignStmt) { + if !p.protectedTag(selector) { + return + } + family := p.tagFamily(selector) + switch family { + case "Node": + if p.ownerFunction(c, family, "newNode") && layoutFunction(c).Recv == nil { + p.checkInitializer(selector, assignment) + return + } + p.pass.Reportf(selector.Pos(), "AST kind is immutable outside checked construction; create a new node") + case "Type": + if p.ownerFunction(c, family, "newType") { + p.checkInitializer(selector, assignment) + return + } + p.pass.Reportf(selector.Pos(), "type kind is immutable outside checked construction") + case "TypeMapper": + if assignment.Tok == token.ASSIGN && len(assignment.Lhs) == 1 && len(assignment.Rhs) == 1 && + p.matchingKind(p.pass.TypesInfo.TypeOf(selector.X), assignment.Rhs[0]) { + return + } + p.pass.Reportf(selector.Pos(), "mapper tag must match the concrete mapper allocation") + } +} + +func (p *unsafeLayoutPass) checkInitializer(selector *ast.SelectorExpr, assignment *ast.AssignStmt) { + if assignment.Tok == token.ASSIGN && len(assignment.Lhs) == 1 && len(assignment.Rhs) == 1 { + if kind, ok := assignment.Rhs[0].(*ast.Ident); ok && kind.Name == "kind" { + return + } + } + p.pass.Reportf(selector.Pos(), "checked construction must initialize the tag from its kind parameter") +} + +func (p *unsafeLayoutPass) layoutConstant(c inspector.Cursor) bool { + for parent := c.Parent(); parent.Node() != nil; parent = parent.Parent() { + if call, ok := parent.Node().(*ast.CallExpr); ok { + if selector, ok := call.Fun.(*ast.SelectorExpr); ok { + object := p.pass.TypesInfo.Uses[selector.Sel] + if object != nil && object.Pkg() != nil && object.Pkg().Path() == "unsafe" && + (object.Name() == "Offsetof" || object.Name() == "Sizeof") { + return true + } + } + } + } + return false +} + +func (p *unsafeLayoutPass) checkCall(c inspector.Cursor, call *ast.CallExpr, test bool) { + var function *types.Func + switch expr := call.Fun.(type) { + case *ast.SelectorExpr: + function, _ = p.pass.TypesInfo.Uses[expr.Sel].(*types.Func) + case *ast.Ident: + function, _ = p.pass.TypesInfo.Uses[expr].(*types.Func) + } + if function != nil && function.Pkg() != nil && !test { + if strings.HasSuffix(function.Pkg().Path(), "/internal/checker") && function.Name() == "newType" { + valid := len(call.Args) == 4 && p.matchingUpcast(call.Args[2], call.Args[3], "Type", false) + if !valid { + p.pass.Reportf(call.Pos(), "newType must directly pair a concrete AsType() receiver with its matching constant kind") + } + } + if strings.HasSuffix(function.Pkg().Path(), "/internal/ast") && function.Name() == "newNode" && + !p.ownerFunction(c, "Node", "newNode") { + valid := len(call.Args) >= 2 && p.matchingUpcast(call.Args[1], call.Args[0], "Node", p.generatedAST(c)) + if !valid { + p.pass.Reportf(call.Pos(), "newNode must pair a concrete AsNode() receiver with a compatible kind") + } + } + } + if selector, ok := call.Fun.(*ast.SelectorExpr); ok && selector.Sel.Name == "New" && len(call.Args) == 0 && !test { + if family := layoutFamily(p.pass.TypesInfo.TypeOf(call)); family != "" { + p.checkFreshRecord(c, family) + } + } + if len(call.Args) != 1 { + return + } + if builtin, ok := call.Fun.(*ast.Ident); ok && builtin.Name == "new" { + family := layoutFamily(p.pass.TypesInfo.TypeOf(call)) + if family != "" && !test { + named := layoutNamedType(p.pass.TypesInfo.TypeOf(call)) + if named.Obj().Name() == family || named.Obj().Name() == "MutableNode" { + p.pass.Reportf(call.Pos(), "a bare compiler header has no concrete payload; use a concrete factory") + } + owner := "/internal/checker" + if family == "Node" { + owner = "/internal/ast" + } + if !strings.HasSuffix(p.pass.Pkg.Path(), owner) { + p.pass.Reportf(call.Pos(), "allocate compiler records through their owning factories") + } else { + p.checkFreshRecord(c, family) + } + } + } + source := p.pass.TypesInfo.TypeOf(call.Args[0]) + target := p.pass.TypesInfo.TypeOf(call) + isUnsafePointer := func(typ types.Type) bool { + basic, ok := typ.(*types.Basic) + return ok && basic.Kind() == types.UnsafePointer + } + if !isUnsafePointer(source) && !isUnsafePointer(target) { + return + } + family := layoutFamily(target) + if family == "" { + family = layoutFamily(source) + } + if family == "" { + if pointer, ok := call.Args[0].(*ast.CallExpr); ok && len(pointer.Args) == 1 { + family = layoutFamily(p.pass.TypesInfo.TypeOf(pointer.Args[0])) + } + } + if family == "" { + return + } + allowed := false + switch family { + case "Node": + allowed = p.generatedAST(c) || p.ownerFunction(c, family, "AsFlowSwitchClauseData") || + p.ownerFunction(c, family, "AsFlowReduceLabelData") + case "Type": + allowed = p.ownerFunction(c, family, "castType") + for _, base := range []string{"ConstrainedType", "StructuredType", "ObjectType", "TypeReference", "InterfaceType", "UnionOrIntersectionType"} { + allowed = allowed || p.ownerFunction(c, family, "As"+base) + } + case "TypeMapper": + allowed = p.ownerFunction(c, family, "castTypeMapper") + } + if !allowed { + p.pass.Reportf(call.Pos(), "reinterpret compiler records only through checked casts or generated AST dispatch") + } +} + +func (p *unsafeLayoutPass) generatedAST(c inspector.Cursor) bool { + for parent := c; parent.Node() != nil; parent = parent.Parent() { + if file, ok := parent.Node().(*ast.File); ok { + return filepath.Base(p.pass.Fset.Position(file.Pos()).Filename) == "ast_generated.go" && ast.IsGenerated(file) && + strings.HasSuffix(p.pass.Pkg.Path(), "/internal/ast") + } + } + return false +} + +func (p *unsafeLayoutPass) matchingUpcast(expr, kind ast.Expr, family string, generated bool) bool { + call, ok := expr.(*ast.CallExpr) + if !ok || len(call.Args) != 0 { + return false + } + method, ok := call.Fun.(*ast.SelectorExpr) + if !ok || method.Sel.Name != "As"+family { + return false + } + selection := p.pass.TypesInfo.Selections[method] + if selection == nil { + return false + } + signature := selection.Obj().Type().(*types.Signature) + receiver := layoutNamedType(signature.Recv().Type()) + if receiver == nil || layoutFamily(receiver) != family || + (receiver.Obj().Name() != family && !(family == "Type" && receiver.Obj().Name() == "TypeBase")) { + return false + } + if family == "Node" { + return p.matchingNodeKind(p.pass.TypesInfo.TypeOf(method.X), kind) || + (generated && p.pass.TypesInfo.Types[kind].Value == nil) + } + return p.matchingKind(p.pass.TypesInfo.TypeOf(method.X), kind) +} + +// A fresh record has a zero tag until checked construction assigns one, so it +// must not escape before then. Types and nodes must be upcast straight into +// newType or newNode, or held in a local that is only used through its own +// fields until that upcast. Mappers must be tagged by the next statement. +func (p *unsafeLayoutPass) checkFreshRecord(alloc inspector.Cursor, family string) { + parent := alloc.Parent() + for { + if _, ok := parent.Node().(*ast.ParenExpr); !ok { + break + } + alloc, parent = parent, parent.Parent() + } + if p.constructorUpcast(alloc, family) { + return + } + assignment, ok := parent.Node().(*ast.AssignStmt) + if !ok || assignment.Tok != token.DEFINE || len(assignment.Lhs) != 1 || len(assignment.Rhs) != 1 { + p.pass.Reportf(alloc.Node().Pos(), "a fresh compiler record must be checked-constructed before it escapes") + return + } + name, _ := assignment.Lhs[0].(*ast.Ident) + variable := p.pass.TypesInfo.Defs[name] + if variable == nil { + p.pass.Reportf(alloc.Node().Pos(), "a fresh compiler record must be checked-constructed before it escapes") + return + } + if family == "TypeMapper" { + if next, ok := parent.NextSibling(); ok { + if tag, ok := next.Node().(*ast.AssignStmt); ok && len(tag.Lhs) == 1 { + if selector, ok := tag.Lhs[0].(*ast.SelectorExpr); ok && p.protectedTag(selector) { + if x, ok := selector.X.(*ast.Ident); ok && p.pass.TypesInfo.Uses[x] == variable { + return + } + } + } + } + p.pass.Reportf(alloc.Node().Pos(), "a fresh mapper must be tagged by the statement after its allocation") + return + } + scope := parent.Parent() + for scope.Node() != nil { + if _, ok := scope.Node().(*ast.BlockStmt); ok { + if _, ok := scope.Parent().Node().(*ast.FuncDecl); ok { + break + } + if _, ok := scope.Parent().Node().(*ast.FuncLit); ok { + break + } + } + scope = scope.Parent() + } + constructed := false + escaped := false + for use := range scope.Preorder((*ast.Ident)(nil)) { + if p.pass.TypesInfo.Uses[use.Node().(*ast.Ident)] != variable { + continue + } + selector, ok := use.Parent().Node().(*ast.SelectorExpr) + if !ok || selector.X != use.Node() { + escaped = true + continue + } + selection := p.pass.TypesInfo.Selections[selector] + switch { + case selection == nil: + escaped = true + case selection.Kind() == types.FieldVal: + if field := selection.Obj().(*types.Var); field.Embedded() { + escaped = true + } + case p.constructorUpcast(use, family): + constructed = true + default: + escaped = true + } + } + if escaped || !constructed { + p.pass.Reportf(alloc.Node().Pos(), "a fresh compiler record must be checked-constructed before it escapes") + } +} + +// Reports whether receiver is upcast directly into the record argument of +// newType or newNode. checkCall separately verifies the kind pairing. +func (p *unsafeLayoutPass) constructorUpcast(receiver inspector.Cursor, family string) bool { + method, ok := receiver.Parent().Node().(*ast.SelectorExpr) + if !ok || method.X != receiver.Node() || method.Sel.Name != "As"+family { + return false + } + upcast, ok := receiver.Parent().Parent().Node().(*ast.CallExpr) + if !ok || upcast.Fun != method { + return false + } + constructor, ok := receiver.Parent().Parent().Parent().Node().(*ast.CallExpr) + if !ok { + return false + } + var name *ast.Ident + switch fun := constructor.Fun.(type) { + case *ast.SelectorExpr: + name = fun.Sel + case *ast.Ident: + name = fun + } + function, _ := p.pass.TypesInfo.Uses[name].(*types.Func) + if function == nil || function.Pkg() == nil { + return false + } + switch family { + case "Type": + return strings.HasSuffix(function.Pkg().Path(), "/internal/checker") && function.Name() == "newType" && + len(constructor.Args) == 4 && constructor.Args[2] == upcast + case "Node": + return strings.HasSuffix(function.Pkg().Path(), "/internal/ast") && function.Name() == "newNode" && + len(constructor.Args) >= 2 && constructor.Args[1] == upcast + } + return false +} diff --git a/tools/scripts/tsc/generate-go-ast.ts b/tools/scripts/tsc/generate-go-ast.ts index c2c7ca98a2570..db4d110de8f8a 100644 --- a/tools/scripts/tsc/generate-go-ast.ts +++ b/tools/scripts/tsc/generate-go-ast.ts @@ -11,6 +11,7 @@ * - VisitEachChild() implementations * - Clone() implementations * - Polymorphic accessor switch statements (Expression(), Type(), etc.) + * - Compact kind-indexed dispatch for shared node accessors * - Is*() type guard functions */ @@ -129,6 +130,7 @@ function generateHeader(w: CodeWriter) { w.write("import ("); w.push(); w.write('"sync/atomic"'); + w.write('"unsafe"'); w.write(""); w.write('"github.com/microsoft/TypeScript/tsc/internal/core"'); w.pop(); @@ -372,11 +374,32 @@ function generateBaseStructDefs(w: CodeWriter) { // ── Generate As*() cast methods ──────────────────────────────────────────── -function generateAsCast(w: CodeWriter, name: string) { - const structName = name; - w.write(`func (n *Node) As${name}() *${structName} {`); +function generateKindCheck(w: CodeWriter, node: NodeType, expression: string, message: string) { + const kinds = canonicalNodesByKind().get(node) ?? []; + if (kinds.length === 1) { + w.write(`if ${expression} != ${kinds[0]} {`); + w.push(); + w.write(`panic("${message}")`); + w.pop(); + w.write("}"); + } + else { + w.write(`switch ${expression} {`); + w.write(`case ${kinds.join(", ")}:`); + w.write("default:"); + w.push(); + w.write(`panic("${message}")`); + w.pop(); + w.write("}"); + } +} + +function generateAsCast(w: CodeWriter, node: NodeType) { + const structName = node.name; + w.write(`func (n *Node) As${structName}() *${structName} {`); w.push(); - w.write(`return n.data.(*${structName})`); + generateKindCheck(w, node, "n.Kind", `Invalid node cast to ${structName}`); + w.write(`return (*${structName})(unsafe.Pointer(n))`); w.pop(); w.write("}"); w.write(""); @@ -389,6 +412,27 @@ function isNodeFlagsMember(m: MemberInfo): boolean { return type.kind === "primitive" && type.name === "NodeFlags"; } +function canonicalNodesByKind(): Map { + const nodeByKind = new Map(); + for (const node of api.nodes()) { + for (const kind of node.allKinds()) { + nodeByKind.set(kind.formatGoConstant(), node); + } + } + + const kindsByNode = new Map(); + for (const [kind, node] of nodeByKind) { + const kinds = kindsByNode.get(node); + if (kinds) { + kinds.push(kind); + } + else { + kindsByNode.set(node, [kind]); + } + } + return kindsByNode; +} + function emitNewFactory( w: CodeWriter, funcName: string, @@ -404,6 +448,10 @@ function emitNewFactory( w.write(`func (f *NodeFactory) ${funcName}(${params}) *Node {`); w.push(); + if (kindMember) { + generateKindCheck(w, node, kindMember.goParamName(), `Invalid node kind for ${structName}`); + } + if (node.arena) { w.write(`data := f.${api.uncapitalize(structName)}Arena.New()`); } @@ -425,7 +473,7 @@ function emitNewFactory( const kindArg = kindMember ? kindMember.goParamName() : `Kind${kindName}`; if (nodeFlagsMembers.length > 0) { - w.write(`node := f.newNode(${kindArg}, data)`); + w.write(`node := f.newNode(${kindArg}, data.AsNode())`); for (const m of nodeFlagsMembers) { const param = m.goParamName(); if (m.bitmask) { @@ -438,7 +486,7 @@ function emitNewFactory( w.write("return node"); } else { - w.write(`return f.newNode(${kindArg}, data)`); + w.write(`return f.newNode(${kindArg}, data.AsNode())`); } w.pop(); @@ -451,7 +499,40 @@ function generateNewFactory(w: CodeWriter, node: NodeType) { const members = schemaMembers(node); const kindMember = members.find(m => m.isKindParam()); const nodeFlagsMembers = members.filter(m => isNodeFlagsMember(m)); - emitNewFactory(w, `New${node.name}`, node.syntaxKindName, structName, node, members, kindMember, nodeFlagsMembers); + if (node.name === "Token") { + const tokenKinds = new Set(node.allKinds().map(kind => kind.formatGoConstant())); + w.write("func (f *NodeFactory) NewToken(kind TokenSyntaxKind) *Node {"); + w.push(); + w.write('if !IsTokenKind(kind) { panic("Invalid token kind") }'); + w.write("switch kind {"); + for (const [canonicalNode, kinds] of canonicalNodesByKind()) { + if (canonicalNode === node) continue; + const overlappingKinds = kinds.filter(kind => tokenKinds.has(kind)); + if (overlappingKinds.length === 0) continue; + w.write(`case ${overlappingKinds.join(", ")}:`); + w.push(); + if (canonicalNode.arena) { + w.write(`data := f.${api.uncapitalize(canonicalNode.name)}Arena.New()`); + } + else { + w.write(`data := &${canonicalNode.name}{}`); + } + w.write("return f.newNode(kind, data.AsNode())"); + w.pop(); + } + w.write("default:"); + w.push(); + w.write("data := f.tokenArena.New()"); + w.write("return f.newNode(kind, data.AsNode())"); + w.pop(); + w.write("}"); + w.pop(); + w.write("}"); + w.write(""); + } + else { + emitNewFactory(w, `New${node.name}`, node.syntaxKindName, structName, node, members, kindMember, nodeFlagsMembers); + } for (const alias of node.kindAliases) { emitNewFactory(w, `New${alias}`, alias, structName, node, members, kindMember, nodeFlagsMembers); } @@ -604,14 +685,12 @@ function hasForEachChild(node: NodeType): boolean { // Generates a (*Node).ForEachChild method that dispatches on node.Kind to the // concrete node type's ForEachChild method. // -// This deliberately avoids calling node.data.ForEachChild(v) through the -// nodeData interface. An interface (or other indirect) call is opaque to escape -// analysis, which must then assume the visitor `v` escapes; that forces caller -// closures — and any locals they capture — onto the heap. Dispatching through a -// Kind switch to a statically-resolved concrete method lets escape analysis -// prove the visitor does not escape, keeping caller closures on the stack. The -// integer switch over Kind also compiles to a jump table, making dispatch -// cheaper than the interface call it replaces. +// An indirect call is opaque to escape analysis, which must then assume the +// visitor `v` escapes; that forces caller closures — and any locals they +// capture — onto the heap. Dispatching through a Kind switch to a +// statically-resolved concrete method lets escape analysis prove the visitor +// does not escape, keeping caller closures on the stack. The integer switch +// over Kind also compiles to a jump table. // // Kinds whose node has no children fall through to `default` and return false, // matching NodeDefault.ForEachChild. @@ -625,7 +704,7 @@ function generateForEachChildDispatch(w: CodeWriter) { if (kinds.length === 0) continue; w.write(`case ${kinds.join(", ")}:`); w.push(); - w.write(`return n.data.(*${node.name}).ForEachChild(v)`); + w.write(`return (*${node.name})(unsafe.Pointer(n)).ForEachChild(v)`); w.pop(); } w.write("default:"); @@ -638,6 +717,237 @@ function generateForEachChildDispatch(w: CodeWriter) { w.write(""); } +function generateVisitEachChildDispatch(w: CodeWriter) { + w.write("func (n *Node) VisitEachChild(v *NodeVisitor) *Node {"); + w.push(); + w.write("switch n.Kind {"); + for (const node of api.nodes()) { + if (!hasForEachChild(node)) continue; + const kinds = node.allKinds().map(kind => kind.formatGoConstant()); + if (kinds.length === 0) continue; + w.write(`case ${kinds.join(", ")}:`); + w.push(); + w.write(`return (*${node.name})(unsafe.Pointer(n)).VisitEachChild(v)`); + w.pop(); + } + w.write("default:"); + w.push(); + w.write("return n"); + w.pop(); + w.write("}"); + w.pop(); + w.write("}"); + w.write(""); +} + +function generateCloneDispatch(w: CodeWriter) { + w.write("func (n *Node) Clone(f NodeFactoryCoercible) *Node {"); + w.push(); + w.write("switch n.Kind {"); + w.write("case kindFlowSwitchClauseData, kindFlowReduceLabelData:"); + w.push(); + w.write("return nil"); + w.pop(); + for (const [node, kinds] of canonicalNodesByKind()) { + w.write(`case ${kinds.join(", ")}:`); + w.push(); + w.write(`return (*${node.name})(unsafe.Pointer(n)).Clone(f)`); + w.pop(); + } + w.write("default:"); + w.push(); + w.write("return nil"); + w.pop(); + w.write("}"); + w.pop(); + w.write("}"); + w.write(""); +} + +function generateSubtreeFactsDispatch(w: CodeWriter) { + w.write("func (n *Node) SubtreeFacts() SubtreeFacts {"); + w.push(); + w.write("switch n.Kind {"); + w.write("case kindFlowSwitchClauseData, kindFlowReduceLabelData:"); + w.push(); + w.write("return SubtreeFactsNone"); + w.pop(); + for (const [node, kinds] of canonicalNodesByKind()) { + w.write(`case ${kinds.join(", ")}:`); + w.push(); + if (transitiveBaseKeys(node).has("CompositeBase")) { + w.write(`return (*${node.name})(unsafe.Pointer(n)).subtreeFactsWorker(n)`); + } + else { + w.write("return n.computeSubtreeFacts()"); + } + w.pop(); + } + w.write("default:"); + w.push(); + w.write("return SubtreeFactsNone"); + w.pop(); + w.write("}"); + w.pop(); + w.write("}"); + w.write(""); +} + +function generateComputeSubtreeFactsDispatch(w: CodeWriter) { + w.write("func (n *Node) computeSubtreeFacts() SubtreeFacts {"); + w.push(); + w.write("switch n.Kind {"); + for (const [node, kinds] of canonicalNodesByKind()) { + w.write(`case ${kinds.join(", ")}:`); + w.push(); + w.write(`return (*${node.name})(unsafe.Pointer(n)).computeSubtreeFacts()`); + w.pop(); + } + w.write("default:"); + w.push(); + w.write("return SubtreeFactsNone"); + w.pop(); + w.write("}"); + w.pop(); + w.write("}"); + w.write(""); +} + +function generatePropagateSubtreeFactsDispatch(w: CodeWriter) { + w.write("func (n *Node) propagateSubtreeFacts() SubtreeFacts {"); + w.push(); + w.write("switch n.Kind {"); + for (const [node, kinds] of canonicalNodesByKind()) { + w.write(`case ${kinds.join(", ")}:`); + w.push(); + w.write(`return (*${node.name})(unsafe.Pointer(n)).propagateSubtreeFacts()`); + w.pop(); + } + w.write("default:"); + w.push(); + w.write("return SubtreeFactsNone"); + w.pop(); + w.write("}"); + w.pop(); + w.write("}"); + w.write(""); +} + +const NODE_ACCESSORS: { method: string; ret: string; base: string; }[] = [ + { method: "FlowNodeData", ret: "*FlowNodeBase", base: "FlowNodeBase" }, + { method: "DeclarationData", ret: "*DeclarationBase", base: "DeclarationBase" }, + { method: "ExportableData", ret: "*ExportableBase", base: "ExportableBase" }, + { method: "LocalsContainerData", ret: "*LocalsContainerBase", base: "LocalsContainerBase" }, + { method: "FunctionLikeData", ret: "*FunctionLikeBase", base: "FunctionLikeBase" }, + { method: "ClassLikeData", ret: "*ClassLikeBase", base: "ClassLikeBase" }, + { method: "BodyData", ret: "*BodyBase", base: "BodyBase" }, + { method: "LiteralLikeData", ret: "*LiteralLikeNodeBase", base: "LiteralLikeNodeBase" }, + { method: "TemplateLiteralLikeData", ret: "*TemplateLiteralLikeNodeBase", base: "TemplateLiteralLikeNodeBase" }, +]; + +function transitiveBaseKeys(node: NodeType): Set { + const seen = new Set(); + const visit = (n: NodeType) => { + for (const base of n.extends) { + if (!seen.has(base.key)) { + seen.add(base.key); + visit(base); + } + } + }; + visit(node); + return seen; +} + +function generateNodeAccessorDispatch(w: CodeWriter, method: string, ret: string, hasAccessor: (node: NodeType) => boolean) { + const cases: { node: NodeType; kinds: string[]; }[] = []; + for (const node of api.nodes()) { + if (!hasAccessor(node)) continue; + const kinds = node.allKinds().map(kind => kind.formatGoConstant()); + if (kinds.length !== 0) cases.push({ node, kinds }); + } + + // Large sparse Kind switches become comparison trees. Dense indices let Go + // emit jump tables; zero is reserved for kinds without the accessor. + const useDispatchTable = cases.length >= 8; + const table = `node${method}Dispatch`; + if (useDispatchTable) { + if (cases.length > 255) { + throw new Error(`${method} dispatch exceeds the uint8 index range`); + } + w.write(`var ${table} = [kindFlowReduceLabelData + 1]uint8{`); + w.push(); + for (const [index, { kinds }] of cases.entries()) { + for (const kind of kinds) { + w.write(`${kind}: ${index + 1},`); + } + } + w.pop(); + w.write("}"); + w.write(""); + } + + w.write(`func (n *Node) ${method}() ${ret} {`); + w.push(); + if (useDispatchTable) { + w.write(`switch ${table}[n.Kind] {`); + } + else { + w.write("switch n.Kind {"); + } + for (const [index, { node, kinds }] of cases.entries()) { + w.write(`case ${useDispatchTable ? index + 1 : kinds.join(", ")}:`); + w.push(); + w.write(`return (*${node.name})(unsafe.Pointer(n)).${method}()`); + w.pop(); + } + w.write("default:"); + w.push(); + w.write("return nil"); + w.pop(); + w.write("}"); + w.pop(); + w.write("}"); + w.write(""); +} + +function generateNodeAccessors(w: CodeWriter) { + for (const { method, ret, base } of NODE_ACCESSORS) { + generateNodeAccessorDispatch(w, method, ret, node => transitiveBaseKeys(node).has(base)); + } +} + +function hasMember(node: NodeType, name: string): boolean { + return schemaMembers(node).some(member => member.name === name); +} + +function generateNameDispatch(w: CodeWriter) { + generateNodeAccessorDispatch(w, "Name", "*DeclarationName", node => hasMember(node, "name")); +} + +function generateModifiersDispatch(w: CodeWriter) { + generateNodeAccessorDispatch(w, "Modifiers", "*ModifierList", node => hasMember(node, "modifiers")); +} + +function generateSetModifiersDispatch(w: CodeWriter) { + w.write("func (n *MutableNode) SetModifiers(modifiers *ModifierList) {"); + w.push(); + w.write("switch n.Kind {"); + for (const node of api.nodes()) { + if (!hasMember(node, "modifiers")) continue; + const kinds = node.allKinds().map(kind => kind.formatGoConstant()); + if (kinds.length === 0) continue; + w.write(`case ${kinds.join(", ")}:`); + w.push(); + w.write(`(*${node.name})(unsafe.Pointer(n)).setModifiers(modifiers)`); + w.pop(); + } + w.write("}"); + w.pop(); + w.write("}"); + w.write(""); +} + // ── Generate VisitEachChild() ────────────────────────────────────────────── function generateVisitEachChild(w: CodeWriter, node: NodeType) { @@ -986,13 +1296,61 @@ function generate(): string { w.write(""); generateForEachChildDispatch(w); + // VisitEachChild dispatch + w.write("// ──────────────────────────────────────────────────────────────────────"); + w.write("// VisitEachChild dispatch"); + w.write("// ──────────────────────────────────────────────────────────────────────"); + w.write(""); + generateVisitEachChildDispatch(w); + + // Clone dispatch + w.write("// ──────────────────────────────────────────────────────────────────────"); + w.write("// Clone dispatch"); + w.write("// ──────────────────────────────────────────────────────────────────────"); + w.write(""); + generateCloneDispatch(w); + + // Subtree facts dispatch + w.write("// ──────────────────────────────────────────────────────────────────────"); + w.write("// Subtree facts dispatch"); + w.write("// ──────────────────────────────────────────────────────────────────────"); + w.write(""); + generateSubtreeFactsDispatch(w); + generateComputeSubtreeFactsDispatch(w); + generatePropagateSubtreeFactsDispatch(w); + + // Node accessor dispatch + w.write("// ──────────────────────────────────────────────────────────────────────"); + w.write("// Node accessor dispatch"); + w.write("// ──────────────────────────────────────────────────────────────────────"); + w.write(""); + generateNodeAccessors(w); + + // Common node accessor dispatch + w.write("// ──────────────────────────────────────────────────────────────────────"); + w.write("// Common node accessor dispatch"); + w.write("// ──────────────────────────────────────────────────────────────────────"); + w.write(""); + generateNameDispatch(w); + generateModifiersDispatch(w); + generateSetModifiersDispatch(w); + // As*() casts w.write("// ──────────────────────────────────────────────────────────────────────"); w.write("// As*() cast methods"); w.write("// ──────────────────────────────────────────────────────────────────────"); w.write(""); + w.write("// Every concrete node embeds its header at offset zero."); + w.write("var ("); + w.push(); + for (const node of api.nodes()) { + w.write(`_ [0 - unsafe.Offsetof(${node.name}{}.Node)]byte`); + } + w.pop(); + w.write(")"); + w.write(""); for (const node of api.nodes()) { - generateAsCast(w, node.name); + generateAsCast(w, node); } // Kind alias guards diff --git a/tsc/internal/ast/ast.go b/tsc/internal/ast/ast.go index 9b08428dd9d4a..e996287c91792 100644 --- a/tsc/internal/ast/ast.go +++ b/tsc/internal/ast/ast.go @@ -6,6 +6,7 @@ import ( "strings" "sync" "sync/atomic" + "unsafe" "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/core" @@ -72,20 +73,18 @@ func NewNodeFactory(hooks NodeFactoryHooks) *NodeFactory { return &NodeFactory{hooks: hooks} } -func newNode(kind Kind, data nodeData, hooks NodeFactoryHooks) *Node { - n := data.AsNode() +func newNode(kind Kind, n *Node, hooks NodeFactoryHooks) *Node { n.Loc = core.UndefinedTextRange() n.Kind = kind - n.data = data if hooks.OnCreate != nil { hooks.OnCreate(n) } return n } -func (f *NodeFactory) newNode(kind Kind, data nodeData) *Node { +func (f *NodeFactory) newNode(kind Kind, n *Node) *Node { f.nodeCount++ - return newNode(kind, data, f.hooks) + return newNode(kind, n, f.hooks) } func (f *NodeFactory) NodeCount() int { @@ -173,9 +172,10 @@ func (list *ModifierList) Clone(f *NodeFactory) *ModifierList { return res } -// AST Node -// Interface values stored in AST nodes are never typed nil values. Construction code must ensure that -// interface valued properties either store a true nil or a reference to a non-nil struct. +// Every concrete AST node embeds Node at offset zero. Kind identifies the +// enclosing allocation, which generated accessors recover without a data pointer. +// Initialize Kind only in newNode; transformations must construct a new node +// rather than retagging one. The unsafelayout linter enforces this boundary. type Node struct { Kind Kind @@ -183,49 +183,26 @@ type Node struct { Loc core.TextRange id atomic.Uint64 Parent *Node - data nodeData } -// Node accessors. Some accessors are implemented as methods on NodeData, others are implemented though -// type switches. Either approach is fine. Interface methods are likely more performant, but have higher -// code size costs because we have hundreds of implementations of the NodeData interface. +// Shared node accessors dispatch on Kind to the enclosing concrete node. func (n *Node) AsNode() *Node { return n } func (n *Node) Pos() int { return n.Loc.Pos() } func (n *Node) End() int { return n.Loc.End() } func (n *Node) IterChildren() iter.Seq[*Node] { - // Implemented directly (rather than through the nodeData interface) so that the - // returned iterator and the visitor closure it passes to ForEachChild do not - // escape: an interface call is opaque to escape analysis. `true` stops a TS - // visitor early, whereas `false` stops a Go iterator yield, so the result is - // inverted. + // `true` stops a TS visitor early, whereas `false` stops a Go iterator yield, + // so the result is inverted. return func(yield func(*Node) bool) { n.ForEachChild(func(child *Node) bool { return !yield(child) }) } } -func (n *Node) Clone(f NodeFactoryCoercible) *Node { return n.data.Clone(f) } -func (n *Node) VisitEachChild(v *NodeVisitor) *Node { return n.data.VisitEachChild(v) } -func (n *Node) Name() *DeclarationName { return n.data.Name() } -func (n *Node) Modifiers() *ModifierList { return n.data.Modifiers() } -func (n *Node) FlowNodeData() *FlowNodeBase { return n.data.FlowNodeData() } -func (n *Node) DeclarationData() *DeclarationBase { return n.data.DeclarationData() } -func (n *Node) ExportableData() *ExportableBase { return n.data.ExportableData() } -func (n *Node) LocalsContainerData() *LocalsContainerBase { return n.data.LocalsContainerData() } -func (n *Node) FunctionLikeData() *FunctionLikeBase { return n.data.FunctionLikeData() } -func (n *Node) ParameterList() *ParameterList { return n.data.FunctionLikeData().Parameters } -func (n *Node) Parameters() []*ParameterDeclarationNode { return n.ParameterList().Nodes } -func (n *Node) ClassLikeData() *ClassLikeBase { return n.data.ClassLikeData() } -func (n *Node) BodyData() *BodyBase { return n.data.BodyData() } -func (n *Node) SubtreeFacts() SubtreeFacts { return n.data.SubtreeFacts() } -func (n *Node) propagateSubtreeFacts() SubtreeFacts { return n.data.propagateSubtreeFacts() } -func (n *Node) LiteralLikeData() *LiteralLikeNodeBase { return n.data.LiteralLikeData() } -func (n *Node) TemplateLiteralLikeData() *TemplateLiteralLikeNodeBase { - return n.data.TemplateLiteralLikeData() -} -func (n *Node) KindString() string { return n.Kind.String() } -func (n *Node) KindValue() int16 { return int16(n.Kind) } +func (n *Node) ParameterList() *ParameterList { return n.FunctionLikeData().Parameters } +func (n *Node) Parameters() []*ParameterDeclarationNode { return n.ParameterList().Nodes } +func (n *Node) KindString() string { return n.Kind.String() } +func (n *Node) KindValue() int16 { return int16(n.Kind) } func (n *Node) Decorators() []*Node { if n.Modifiers() == nil { return nil @@ -235,8 +212,7 @@ func (n *Node) Decorators() []*Node { type MutableNode Node -func (n *Node) AsMutable() *MutableNode { return (*MutableNode)(n) } -func (n *MutableNode) SetModifiers(modifiers *ModifierList) { n.data.setModifiers(modifiers) } +func (n *Node) AsMutable() *MutableNode { return (*MutableNode)(n) } func (n *Node) Symbol() *Symbol { data := n.DeclarationData() @@ -305,7 +281,7 @@ func (n *Node) Text() string { case KindJSDocLinkPlain: return strings.Join(n.AsJSDocLinkPlain().text, "") } - panic(fmt.Sprintf("Unhandled case in Node.Text: %T", n.data)) + panic(fmt.Sprintf("Unhandled case in Node.Text: %s", n.Kind)) } func (n *Node) Expression() *Node { @@ -1172,83 +1148,34 @@ func (n *Node) Contains(descendant *Node) bool { // Node casts func (n *Node) AsFlowSwitchClauseData() *FlowSwitchClauseData { - return n.data.(*FlowSwitchClauseData) + if n.Kind != kindFlowSwitchClauseData { + panic("Invalid node cast to FlowSwitchClauseData") + } + return (*FlowSwitchClauseData)(unsafe.Pointer(n)) } func (n *Node) AsFlowReduceLabelData() *FlowReduceLabelData { - return n.data.(*FlowReduceLabelData) -} - -// NodeData - -type nodeData interface { - AsNode() *Node - ForEachChild(v Visitor) bool - VisitEachChild(v *NodeVisitor) *Node - Clone(v NodeFactoryCoercible) *Node - Name() *DeclarationName - Modifiers() *ModifierList - setModifiers(modifiers *ModifierList) - FlowNodeData() *FlowNodeBase - DeclarationData() *DeclarationBase - ExportableData() *ExportableBase - LocalsContainerData() *LocalsContainerBase - FunctionLikeData() *FunctionLikeBase - ClassLikeData() *ClassLikeBase - BodyData() *BodyBase - LiteralLikeData() *LiteralLikeNodeBase - TemplateLiteralLikeData() *TemplateLiteralLikeNodeBase - SubtreeFacts() SubtreeFacts - computeSubtreeFacts() SubtreeFacts - subtreeFactsWorker(self nodeData) SubtreeFacts - propagateSubtreeFacts() SubtreeFacts -} - -// NodeDefault + if n.Kind != kindFlowReduceLabelData { + panic("Invalid node cast to FlowReduceLabelData") + } + return (*FlowReduceLabelData)(unsafe.Pointer(n)) +} +// NodeDefault keeps Node methods one promotion level below fields such as Text, +// Body, TypeParameters, and Parameters supplied by bases embedded alongside +// NodeBase. Embedding Node directly in NodeBase makes those selectors ambiguous. type NodeDefault struct { Node } -func (node *NodeDefault) AsNode() *Node { return &node.Node } -func (node *NodeDefault) ForEachChild(v Visitor) bool { return false } - -func (node *NodeDefault) VisitEachChild(v *NodeVisitor) *Node { return node.AsNode() } -func (node *NodeDefault) Clone(v NodeFactoryCoercible) *Node { return nil } -func (node *NodeDefault) Name() *DeclarationName { return nil } -func (node *NodeDefault) Modifiers() *ModifierList { return nil } -func (node *NodeDefault) setModifiers(modifiers *ModifierList) {} -func (node *NodeDefault) FlowNodeData() *FlowNodeBase { return nil } -func (node *NodeDefault) DeclarationData() *DeclarationBase { return nil } -func (node *NodeDefault) ExportableData() *ExportableBase { return nil } -func (node *NodeDefault) LocalsContainerData() *LocalsContainerBase { return nil } -func (node *NodeDefault) FunctionLikeData() *FunctionLikeBase { return nil } -func (node *NodeDefault) ClassLikeData() *ClassLikeBase { return nil } -func (node *NodeDefault) BodyData() *BodyBase { return nil } -func (node *NodeDefault) LiteralLikeData() *LiteralLikeNodeBase { return nil } -func (node *NodeDefault) TemplateLiteralLikeData() *TemplateLiteralLikeNodeBase { return nil } -func (node *NodeDefault) SubtreeFacts() SubtreeFacts { - return node.data.subtreeFactsWorker(node.data) -} - -func (node *NodeDefault) subtreeFactsWorker(self nodeData) SubtreeFacts { - // To avoid excessive conditional checks, the default implementation of subtreeFactsWorker directly invokes - // computeSubtreeFacts. More complex nodes should implement CompositeNodeBase, which overrides this - // method to cache the result. `self` is passed along to ensure we lookup `computeSubtreeFacts` on the - // correct type, as `CompositeNodeBase` does not, itself, inherit from `Node`. - return self.computeSubtreeFacts() -} - func (node *NodeDefault) computeSubtreeFacts() SubtreeFacts { return SubtreeFactsNone } func (node *NodeDefault) propagateSubtreeFacts() SubtreeFacts { - return node.data.SubtreeFacts() & ^SubtreeExclusionsNode + return node.SubtreeFacts() & ^SubtreeExclusionsNode } -// NodeBase - type NodeBase struct { NodeDefault } @@ -1599,7 +1526,7 @@ func (node *Node) EagerJSDoc(file *SourceFile) []*Node { // CompositeBase -func (node *CompositeBase) subtreeFactsWorker(self nodeData) SubtreeFacts { +func (node *CompositeBase) subtreeFactsWorker(self *Node) SubtreeFacts { // computeSubtreeFacts() is expected to be idempotent, so races will only impact time, not correctness. facts := SubtreeFacts(node.facts.Load()) if facts&SubtreeFactsComputed == 0 { @@ -2530,7 +2457,7 @@ func (f *NodeFactory) NewSourceFile(opts SourceFileParseOptions, text string, st data.text = text data.Statements = statements data.EndOfFileToken = endOfFileToken - return f.newNode(KindSourceFile, data) + return f.newNode(KindSourceFile, data.AsNode()) } func (node *SourceFile) ParseOptions() SourceFileParseOptions { diff --git a/tsc/internal/ast/ast_generated.go b/tsc/internal/ast/ast_generated.go index f1c27cfe8403e..58aef6d7bc11c 100644 --- a/tsc/internal/ast/ast_generated.go +++ b/tsc/internal/ast/ast_generated.go @@ -4,6 +4,7 @@ package ast import ( "sync/atomic" + "unsafe" "github.com/microsoft/TypeScript/tsc/internal/core" ) @@ -598,8 +599,53 @@ type Token struct { } func (f *NodeFactory) NewToken(kind TokenSyntaxKind) *Node { - data := f.tokenArena.New() - return f.newNode(kind, data) + if !IsTokenKind(kind) { + panic("Invalid token kind") + } + switch kind { + case KindNumericLiteral: + data := f.numericLiteralArena.New() + return f.newNode(kind, data.AsNode()) + case KindBigIntLiteral: + data := &BigIntLiteral{} + return f.newNode(kind, data.AsNode()) + case KindStringLiteral: + data := f.stringLiteralArena.New() + return f.newNode(kind, data.AsNode()) + case KindJsxText: + data := &JsxText{} + return f.newNode(kind, data.AsNode()) + case KindRegularExpressionLiteral: + data := &RegularExpressionLiteral{} + return f.newNode(kind, data.AsNode()) + case KindNoSubstitutionTemplateLiteral: + data := &NoSubstitutionTemplateLiteral{} + return f.newNode(kind, data.AsNode()) + case KindTemplateHead: + data := &TemplateHead{} + return f.newNode(kind, data.AsNode()) + case KindTemplateMiddle: + data := &TemplateMiddle{} + return f.newNode(kind, data.AsNode()) + case KindTemplateTail: + data := &TemplateTail{} + return f.newNode(kind, data.AsNode()) + case KindIdentifier: + data := f.identifierArena.New() + return f.newNode(kind, data.AsNode()) + case KindPrivateIdentifier: + data := &PrivateIdentifier{} + return f.newNode(kind, data.AsNode()) + case KindFalseKeyword, KindImportKeyword, KindNullKeyword, KindSuperKeyword, KindThisKeyword, KindTrueKeyword: + data := f.keywordExpressionArena.New() + return f.newNode(kind, data.AsNode()) + case KindVoidKeyword, KindAnyKeyword, KindBooleanKeyword, KindIntrinsicKeyword, KindNeverKeyword, KindNumberKeyword, KindObjectKeyword, KindStringKeyword, KindSymbolKeyword, KindUndefinedKeyword, KindUnknownKeyword, KindBigIntKeyword: + data := f.keywordTypeNodeArena.New() + return f.newNode(kind, data.AsNode()) + default: + data := f.tokenArena.New() + return f.newNode(kind, data.AsNode()) + } } func (node *Token) Clone(f NodeFactoryCoercible) *Node { @@ -628,7 +674,7 @@ func (f *NodeFactory) NewIdentifier(text string) *Node { data := f.identifierArena.New() data.Text = text f.textCount++ - return f.newNode(KindIdentifier, data) + return f.newNode(KindIdentifier, data.AsNode()) } func (node *Identifier) Clone(f NodeFactoryCoercible) *Node { @@ -652,7 +698,7 @@ func (f *NodeFactory) NewPrivateIdentifier(text string) *Node { data := &PrivateIdentifier{} data.Text = text f.textCount++ - return f.newNode(KindPrivateIdentifier, data) + return f.newNode(KindPrivateIdentifier, data.AsNode()) } func (node *PrivateIdentifier) Clone(f NodeFactoryCoercible) *Node { @@ -679,7 +725,7 @@ func (f *NodeFactory) NewQualifiedName(left *EntityName, right *MemberName) *Nod data := &QualifiedName{} data.Left = left data.Right = right - return f.newNode(KindQualifiedName, data) + return f.newNode(KindQualifiedName, data.AsNode()) } func (f *NodeFactory) UpdateQualifiedName(node *QualifiedName, left *EntityName, right *MemberName) *Node { @@ -723,7 +769,7 @@ type ComputedPropertyName struct { func (f *NodeFactory) NewComputedPropertyName(expression *Expression) *Node { data := &ComputedPropertyName{} data.Expression = expression - return f.newNode(KindComputedPropertyName, data) + return f.newNode(KindComputedPropertyName, data.AsNode()) } func (f *NodeFactory) UpdateComputedPropertyName(node *ComputedPropertyName, expression *Expression) *Node { @@ -766,7 +812,7 @@ type Decorator struct { func (f *NodeFactory) NewDecorator(expression *LeftHandSideExpression) *Node { data := &Decorator{} data.Expression = expression - return f.newNode(KindDecorator, data) + return f.newNode(KindDecorator, data.AsNode()) } func (f *NodeFactory) UpdateDecorator(node *Decorator, expression *LeftHandSideExpression) *Node { @@ -802,7 +848,7 @@ type EmptyStatement struct { func (f *NodeFactory) NewEmptyStatement() *Node { data := &EmptyStatement{} - return f.newNode(KindEmptyStatement, data) + return f.newNode(KindEmptyStatement, data.AsNode()) } func (node *EmptyStatement) Clone(f NodeFactoryCoercible) *Node { @@ -830,7 +876,7 @@ func (f *NodeFactory) NewIfStatement(expression *Expression, thenStatement *Stat data.Expression = expression data.ThenStatement = thenStatement data.ElseStatement = elseStatement - return f.newNode(KindIfStatement, data) + return f.newNode(KindIfStatement, data.AsNode()) } func (f *NodeFactory) UpdateIfStatement(node *IfStatement, expression *Expression, thenStatement *Statement, elseStatement *Statement) *Node { @@ -876,7 +922,7 @@ func (f *NodeFactory) NewDoStatement(statement *Statement, expression *Expressio data := &DoStatement{} data.Statement = statement data.Expression = expression - return f.newNode(KindDoStatement, data) + return f.newNode(KindDoStatement, data.AsNode()) } func (f *NodeFactory) UpdateDoStatement(node *DoStatement, statement *Statement, expression *Expression) *Node { @@ -921,7 +967,7 @@ func (f *NodeFactory) NewWhileStatement(expression *Expression, statement *State data := &WhileStatement{} data.Expression = expression data.Statement = statement - return f.newNode(KindWhileStatement, data) + return f.newNode(KindWhileStatement, data.AsNode()) } func (f *NodeFactory) UpdateWhileStatement(node *WhileStatement, expression *Expression, statement *Statement) *Node { @@ -971,7 +1017,7 @@ func (f *NodeFactory) NewForStatement(initializer *ForInitializer, condition *Ex data.Condition = condition data.Incrementor = incrementor data.Statement = statement - return f.newNode(KindForStatement, data) + return f.newNode(KindForStatement, data.AsNode()) } func (f *NodeFactory) UpdateForStatement(node *ForStatement, initializer *ForInitializer, condition *Expression, incrementor *Expression, statement *Statement) *Node { @@ -1022,12 +1068,17 @@ type ForInOrOfStatement struct { } func (f *NodeFactory) NewForInOrOfStatement(kind Kind, awaitModifier *AwaitKeyword, initializer *ForInitializer, expression *Expression, statement *Statement) *Node { + switch kind { + case KindForInStatement, KindForOfStatement: + default: + panic("Invalid node kind for ForInOrOfStatement") + } data := &ForInOrOfStatement{} data.AwaitModifier = awaitModifier data.Initializer = initializer data.Expression = expression data.Statement = statement - return f.newNode(kind, data) + return f.newNode(kind, data.AsNode()) } func (f *NodeFactory) UpdateForInOrOfStatement(node *ForInOrOfStatement, awaitModifier *AwaitKeyword, initializer *ForInitializer, expression *Expression, statement *Statement) *Node { @@ -1072,7 +1123,7 @@ type BreakStatement struct { func (f *NodeFactory) NewBreakStatement(label *IdentifierNode) *Node { data := &BreakStatement{} data.Label = label - return f.newNode(KindBreakStatement, data) + return f.newNode(KindBreakStatement, data.AsNode()) } func (f *NodeFactory) UpdateBreakStatement(node *BreakStatement, label *IdentifierNode) *Node { @@ -1110,7 +1161,7 @@ type ContinueStatement struct { func (f *NodeFactory) NewContinueStatement(label *IdentifierNode) *Node { data := &ContinueStatement{} data.Label = label - return f.newNode(KindContinueStatement, data) + return f.newNode(KindContinueStatement, data.AsNode()) } func (f *NodeFactory) UpdateContinueStatement(node *ContinueStatement, label *IdentifierNode) *Node { @@ -1149,7 +1200,7 @@ type ReturnStatement struct { func (f *NodeFactory) NewReturnStatement(expression *Expression) *Node { data := f.returnStatementArena.New() data.Expression = expression - return f.newNode(KindReturnStatement, data) + return f.newNode(KindReturnStatement, data.AsNode()) } func (f *NodeFactory) UpdateReturnStatement(node *ReturnStatement, expression *Expression) *Node { @@ -1190,7 +1241,7 @@ func (f *NodeFactory) NewWithStatement(expression *Expression, statement *Statem data := &WithStatement{} data.Expression = expression data.Statement = statement - return f.newNode(KindWithStatement, data) + return f.newNode(KindWithStatement, data.AsNode()) } func (f *NodeFactory) UpdateWithStatement(node *WithStatement, expression *Expression, statement *Statement) *Node { @@ -1236,7 +1287,7 @@ func (f *NodeFactory) NewSwitchStatement(expression *Expression, caseBlock *Case data := &SwitchStatement{} data.Expression = expression data.CaseBlock = caseBlock - return f.newNode(KindSwitchStatement, data) + return f.newNode(KindSwitchStatement, data.AsNode()) } func (f *NodeFactory) UpdateSwitchStatement(node *SwitchStatement, expression *Expression, caseBlock *CaseBlockNode) *Node { @@ -1281,7 +1332,7 @@ type CaseBlock struct { func (f *NodeFactory) NewCaseBlock(clauses *CaseClausesList) *Node { data := &CaseBlock{} data.Clauses = clauses - return f.newNode(KindCaseBlock, data) + return f.newNode(KindCaseBlock, data.AsNode()) } func (f *NodeFactory) UpdateCaseBlock(node *CaseBlock, clauses *CaseClausesList) *Node { @@ -1324,10 +1375,15 @@ type CaseOrDefaultClause struct { } func (f *NodeFactory) NewCaseOrDefaultClause(kind Kind, expression *Expression, statements *StatementList) *Node { + switch kind { + case KindCaseClause, KindDefaultClause: + default: + panic("Invalid node kind for CaseOrDefaultClause") + } data := &CaseOrDefaultClause{} data.Expression = expression data.Statements = statements - return f.newNode(kind, data) + return f.newNode(kind, data.AsNode()) } func (f *NodeFactory) UpdateCaseOrDefaultClause(node *CaseOrDefaultClause, expression *Expression, statements *StatementList) *Node { @@ -1375,7 +1431,7 @@ type ThrowStatement struct { func (f *NodeFactory) NewThrowStatement(expression *Expression) *Node { data := &ThrowStatement{} data.Expression = expression - return f.newNode(KindThrowStatement, data) + return f.newNode(KindThrowStatement, data.AsNode()) } func (f *NodeFactory) UpdateThrowStatement(node *ThrowStatement, expression *Expression) *Node { @@ -1422,7 +1478,7 @@ func (f *NodeFactory) NewTryStatement(tryBlock *BlockNode, catchClause *CatchCla data.TryBlock = tryBlock data.CatchClause = catchClause data.FinallyBlock = finallyBlock - return f.newNode(KindTryStatement, data) + return f.newNode(KindTryStatement, data.AsNode()) } func (f *NodeFactory) UpdateTryStatement(node *TryStatement, tryBlock *BlockNode, catchClause *CatchClauseNode, finallyBlock *BlockNode) *Node { @@ -1470,7 +1526,7 @@ func (f *NodeFactory) NewCatchClause(variableDeclaration *VariableDeclarationNod data := &CatchClause{} data.VariableDeclaration = variableDeclaration data.Block = block - return f.newNode(KindCatchClause, data) + return f.newNode(KindCatchClause, data.AsNode()) } func (f *NodeFactory) UpdateCatchClause(node *CatchClause, variableDeclaration *VariableDeclarationNode, block *BlockNode) *Node { @@ -1506,7 +1562,7 @@ type DebuggerStatement struct { func (f *NodeFactory) NewDebuggerStatement() *Node { data := &DebuggerStatement{} - return f.newNode(KindDebuggerStatement, data) + return f.newNode(KindDebuggerStatement, data.AsNode()) } func (node *DebuggerStatement) Clone(f NodeFactoryCoercible) *Node { @@ -1531,7 +1587,7 @@ func (f *NodeFactory) NewLabeledStatement(label *IdentifierNode, statement *Stat data := &LabeledStatement{} data.Label = label data.Statement = statement - return f.newNode(KindLabeledStatement, data) + return f.newNode(KindLabeledStatement, data.AsNode()) } func (f *NodeFactory) UpdateLabeledStatement(node *LabeledStatement, label *IdentifierNode, statement *Statement) *Node { @@ -1574,7 +1630,7 @@ type ExpressionStatement struct { func (f *NodeFactory) NewExpressionStatement(expression *Expression) *Node { data := f.expressionStatementArena.New() data.Expression = expression - return f.newNode(KindExpressionStatement, data) + return f.newNode(KindExpressionStatement, data.AsNode()) } func (f *NodeFactory) UpdateExpressionStatement(node *ExpressionStatement, expression *Expression) *Node { @@ -1620,7 +1676,7 @@ func (f *NodeFactory) NewBlock(statements *StatementList, multiLine bool) *Node data := f.blockArena.New() data.Statements = statements data.MultiLine = multiLine - return f.newNode(KindBlock, data) + return f.newNode(KindBlock, data.AsNode()) } func (f *NodeFactory) UpdateBlock(node *Block, statements *StatementList, multiLine bool) *Node { @@ -1665,7 +1721,7 @@ func (f *NodeFactory) NewVariableStatement(modifiers *ModifierList, declarationL data := f.variableStatementArena.New() data.modifiers = modifiers data.DeclarationList = declarationList - return f.newNode(KindVariableStatement, data) + return f.newNode(KindVariableStatement, data.AsNode()) } func (f *NodeFactory) UpdateVariableStatement(node *VariableStatement, modifiers *ModifierList, declarationList *VariableDeclarationListNode) *Node { @@ -1712,7 +1768,7 @@ func (f *NodeFactory) NewVariableDeclaration(name *BindingName, exclamationToken data.ExclamationToken = exclamationToken data.Type = typeNode data.Initializer = initializer - return f.newNode(KindVariableDeclaration, data) + return f.newNode(KindVariableDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateVariableDeclaration(node *VariableDeclaration, name *BindingName, exclamationToken *ExclamationToken, typeNode *TypeNode, initializer *Expression) *Node { @@ -1758,7 +1814,7 @@ type VariableDeclarationList struct { func (f *NodeFactory) NewVariableDeclarationList(declarations *VariableDeclarationNodeList, flags NodeFlags) *Node { data := f.variableDeclarationListArena.New() data.Declarations = declarations - node := f.newNode(KindVariableDeclarationList, data) + node := f.newNode(KindVariableDeclarationList, data.AsNode()) node.Flags = flags return node } @@ -1797,9 +1853,14 @@ type BindingPattern struct { } func (f *NodeFactory) NewBindingPattern(kind Kind, elements *BindingElementList) *Node { + switch kind { + case KindObjectBindingPattern, KindArrayBindingPattern: + default: + panic("Invalid node kind for BindingPattern") + } data := &BindingPattern{} data.Elements = elements - return f.newNode(kind, data) + return f.newNode(kind, data.AsNode()) } func (f *NodeFactory) UpdateBindingPattern(node *BindingPattern, elements *BindingElementList) *Node { @@ -1853,7 +1914,7 @@ func (f *NodeFactory) NewParameterDeclaration(modifiers *ModifierList, dotDotDot data.QuestionToken = questionToken data.Type = typeNode data.Initializer = initializer - return f.newNode(KindParameter, data) + return f.newNode(KindParameter, data.AsNode()) } func (f *NodeFactory) UpdateParameterDeclaration(node *ParameterDeclaration, modifiers *ModifierList, dotDotDotToken *DotDotDotToken, name *BindingName, questionToken *QuestionToken, typeNode *TypeNode, initializer *Expression) *Node { @@ -1910,7 +1971,7 @@ func (f *NodeFactory) NewBindingElement(dotDotDotToken *DotDotDotToken, property data.PropertyName = propertyName data.name = name data.Initializer = initializer - return f.newNode(KindBindingElement, data) + return f.newNode(KindBindingElement, data.AsNode()) } func (f *NodeFactory) UpdateBindingElement(node *BindingElement, dotDotDotToken *DotDotDotToken, propertyName *PropertyName, name *BindingName, initializer *Expression) *Node { @@ -1956,7 +2017,7 @@ type MissingDeclaration struct { func (f *NodeFactory) NewMissingDeclaration(modifiers *ModifierList) *Node { data := &MissingDeclaration{} data.modifiers = modifiers - return f.newNode(KindMissingDeclaration, data) + return f.newNode(KindMissingDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateMissingDeclaration(node *MissingDeclaration, modifiers *ModifierList) *Node { @@ -2007,7 +2068,7 @@ func (f *NodeFactory) NewFunctionDeclaration(modifiers *ModifierList, asteriskTo data.Type = typeNode data.FullSignature = fullSignature data.Body = body - return f.newNode(KindFunctionDeclaration, data) + return f.newNode(KindFunctionDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateFunctionDeclaration(node *FunctionDeclaration, modifiers *ModifierList, asteriskToken *AsteriskToken, name *IdentifierNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node { @@ -2061,7 +2122,7 @@ func (f *NodeFactory) NewClassDeclaration(modifiers *ModifierList, name *Identif data.TypeParameters = typeParameters data.HeritageClauses = heritageClauses data.Members = members - return f.newNode(KindClassDeclaration, data) + return f.newNode(KindClassDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateClassDeclaration(node *ClassDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *ClassElementList) *Node { @@ -2112,7 +2173,7 @@ func (f *NodeFactory) NewClassExpression(modifiers *ModifierList, name *Identifi data.TypeParameters = typeParameters data.HeritageClauses = heritageClauses data.Members = members - return f.newNode(KindClassExpression, data) + return f.newNode(KindClassExpression, data.AsNode()) } func (f *NodeFactory) UpdateClassExpression(node *ClassExpression, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *ClassElementList) *Node { @@ -2161,7 +2222,7 @@ func (f *NodeFactory) NewHeritageClause(token Kind, types *HeritageClauseElement data := f.heritageClauseArena.New() data.Token = token data.Types = types - return f.newNode(KindHeritageClause, data) + return f.newNode(KindHeritageClause, data.AsNode()) } func (f *NodeFactory) UpdateHeritageClause(node *HeritageClause, token Kind, types *HeritageClauseElementList) *Node { @@ -2210,7 +2271,7 @@ func (f *NodeFactory) NewInterfaceDeclaration(modifiers *ModifierList, name *Ide data.TypeParameters = typeParameters data.HeritageClauses = heritageClauses data.Members = members - return f.newNode(KindInterfaceDeclaration, data) + return f.newNode(KindInterfaceDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateInterfaceDeclaration(node *InterfaceDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *TypeElementList) *Node { @@ -2266,7 +2327,7 @@ func (f *NodeFactory) NewTypeAliasDeclaration(modifiers *ModifierList, name *Ide data.name = name data.TypeParameters = typeParameters data.Type = typeNode - return f.newNode(KindTypeAliasDeclaration, data) + return f.newNode(KindTypeAliasDeclaration, data.AsNode()) } func (f *NodeFactory) NewJSTypeAliasDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, typeNode *TypeNode) *Node { @@ -2275,7 +2336,7 @@ func (f *NodeFactory) NewJSTypeAliasDeclaration(modifiers *ModifierList, name *I data.name = name data.TypeParameters = typeParameters data.Type = typeNode - return f.newNode(KindJSTypeAliasDeclaration, data) + return f.newNode(KindJSTypeAliasDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateTypeAliasDeclaration(node *TypeAliasDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, typeNode *TypeNode) *Node { @@ -2342,7 +2403,7 @@ func (f *NodeFactory) NewEnumMember(name *PropertyName, initializer *Expression) data := &EnumMember{} data.name = name data.Initializer = initializer - return f.newNode(KindEnumMember, data) + return f.newNode(KindEnumMember, data.AsNode()) } func (f *NodeFactory) UpdateEnumMember(node *EnumMember, name *PropertyName, initializer *Expression) *Node { @@ -2391,7 +2452,7 @@ func (f *NodeFactory) NewEnumDeclaration(modifiers *ModifierList, name *Identifi data.modifiers = modifiers data.name = name data.Members = members - return f.newNode(KindEnumDeclaration, data) + return f.newNode(KindEnumDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateEnumDeclaration(node *EnumDeclaration, modifiers *ModifierList, name *IdentifierNode, members *EnumMemberList) *Node { @@ -2434,7 +2495,7 @@ type ModuleBlock struct { func (f *NodeFactory) NewModuleBlock(statements *StatementList) *Node { data := &ModuleBlock{} data.Statements = statements - return f.newNode(KindModuleBlock, data) + return f.newNode(KindModuleBlock, data.AsNode()) } func (f *NodeFactory) UpdateModuleBlock(node *ModuleBlock, statements *StatementList) *Node { @@ -2474,7 +2535,7 @@ type NotEmittedStatement struct { func (f *NodeFactory) NewNotEmittedStatement() *Node { data := &NotEmittedStatement{} - return f.newNode(KindNotEmittedStatement, data) + return f.newNode(KindNotEmittedStatement, data.AsNode()) } func (node *NotEmittedStatement) Clone(f NodeFactoryCoercible) *Node { @@ -2497,7 +2558,7 @@ type NotEmittedTypeElement struct { func (f *NodeFactory) NewNotEmittedTypeElement() *Node { data := &NotEmittedTypeElement{} - return f.newNode(KindNotEmittedTypeElement, data) + return f.newNode(KindNotEmittedTypeElement, data.AsNode()) } func (node *NotEmittedTypeElement) Clone(f NodeFactoryCoercible) *Node { @@ -2528,7 +2589,7 @@ func (f *NodeFactory) NewImportDeclaration(modifiers *ModifierList, importClause data.ImportClause = importClause data.ModuleSpecifier = moduleSpecifier data.Attributes = attributes - return f.newNode(KindImportDeclaration, data) + return f.newNode(KindImportDeclaration, data.AsNode()) } func (f *NodeFactory) NewJSImportDeclaration(modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node { @@ -2537,7 +2598,7 @@ func (f *NodeFactory) NewJSImportDeclaration(modifiers *ModifierList, importClau data.ImportClause = importClause data.ModuleSpecifier = moduleSpecifier data.Attributes = attributes - return f.newNode(KindJSImportDeclaration, data) + return f.newNode(KindJSImportDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateImportDeclaration(node *ImportDeclaration, modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node { @@ -2603,7 +2664,7 @@ type ExternalModuleReference struct { func (f *NodeFactory) NewExternalModuleReference(expression *Expression) *Node { data := &ExternalModuleReference{} data.Expression = expression - return f.newNode(KindExternalModuleReference, data) + return f.newNode(KindExternalModuleReference, data.AsNode()) } func (f *NodeFactory) UpdateExternalModuleReference(node *ExternalModuleReference, expression *Expression) *Node { @@ -2647,7 +2708,7 @@ type NamespaceImport struct { func (f *NodeFactory) NewNamespaceImport(name *IdentifierNode) *Node { data := &NamespaceImport{} data.name = name - return f.newNode(KindNamespaceImport, data) + return f.newNode(KindNamespaceImport, data.AsNode()) } func (f *NodeFactory) UpdateNamespaceImport(node *NamespaceImport, name *IdentifierNode) *Node { @@ -2694,7 +2755,7 @@ type NamedImports struct { func (f *NodeFactory) NewNamedImports(elements *ImportSpecifierList) *Node { data := &NamedImports{} data.Elements = elements - return f.newNode(KindNamedImports, data) + return f.newNode(KindNamedImports, data.AsNode()) } func (f *NodeFactory) UpdateNamedImports(node *NamedImports, elements *ImportSpecifierList) *Node { @@ -2744,7 +2805,7 @@ func (f *NodeFactory) NewExportAssignment(modifiers *ModifierList, isExportEqual data.IsExportEquals = isExportEquals data.Type = typeNode data.Expression = expression - return f.newNode(KindExportAssignment, data) + return f.newNode(KindExportAssignment, data.AsNode()) } func (f *NodeFactory) UpdateExportAssignment(node *ExportAssignment, modifiers *ModifierList, isExportEquals bool, typeNode *TypeNode, expression *Expression) *Node { @@ -2786,7 +2847,7 @@ func (f *NodeFactory) NewNamespaceExportDeclaration(modifiers *ModifierList, nam data := &NamespaceExportDeclaration{} data.modifiers = modifiers data.name = name - return f.newNode(KindNamespaceExportDeclaration, data) + return f.newNode(KindNamespaceExportDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateNamespaceExportDeclaration(node *NamespaceExportDeclaration, modifiers *ModifierList, name *IdentifierNode) *Node { @@ -2829,7 +2890,7 @@ type NamespaceExport struct { func (f *NodeFactory) NewNamespaceExport(name *ModuleExportName) *Node { data := &NamespaceExport{} data.name = name - return f.newNode(KindNamespaceExport, data) + return f.newNode(KindNamespaceExport, data.AsNode()) } func (f *NodeFactory) UpdateNamespaceExport(node *NamespaceExport, name *ModuleExportName) *Node { @@ -2876,7 +2937,7 @@ type NamedExports struct { func (f *NodeFactory) NewNamedExports(elements *ExportSpecifierList) *Node { data := &NamedExports{} data.Elements = elements - return f.newNode(KindNamedExports, data) + return f.newNode(KindNamedExports, data.AsNode()) } func (f *NodeFactory) UpdateNamedExports(node *NamedExports, elements *ExportSpecifierList) *Node { @@ -2925,7 +2986,7 @@ func (f *NodeFactory) NewExportSpecifier(isTypeOnly bool, propertyName *ModuleEx data.IsTypeOnly = isTypeOnly data.PropertyName = propertyName data.name = name - return f.newNode(KindExportSpecifier, data) + return f.newNode(KindExportSpecifier, data.AsNode()) } func (f *NodeFactory) UpdateExportSpecifier(node *ExportSpecifier, isTypeOnly bool, propertyName *ModuleExportName, name *ModuleExportName) *Node { @@ -2972,7 +3033,7 @@ func (f *NodeFactory) NewCallSignatureDeclaration(typeParameters *TypeParameterL data.TypeParameters = typeParameters data.Parameters = parameters data.Type = typeNode - return f.newNode(KindCallSignature, data) + return f.newNode(KindCallSignature, data.AsNode()) } func (f *NodeFactory) UpdateCallSignatureDeclaration(node *CallSignatureDeclaration, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node { @@ -3015,7 +3076,7 @@ func (f *NodeFactory) NewConstructSignatureDeclaration(typeParameters *TypeParam data.TypeParameters = typeParameters data.Parameters = parameters data.Type = typeNode - return f.newNode(KindConstructSignature, data) + return f.newNode(KindConstructSignature, data.AsNode()) } func (f *NodeFactory) UpdateConstructSignatureDeclaration(node *ConstructSignatureDeclaration, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node { @@ -3063,7 +3124,7 @@ func (f *NodeFactory) NewConstructorDeclaration(modifiers *ModifierList, typePar data.Type = typeNode data.FullSignature = fullSignature data.Body = body - return f.newNode(KindConstructor, data) + return f.newNode(KindConstructor, data.AsNode()) } func (f *NodeFactory) UpdateConstructorDeclaration(node *ConstructorDeclaration, modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node { @@ -3111,7 +3172,7 @@ func (f *NodeFactory) NewGetAccessorDeclaration(modifiers *ModifierList, name *P data.Type = typeNode data.FullSignature = fullSignature data.Body = body - return f.newNode(KindGetAccessor, data) + return f.newNode(KindGetAccessor, data.AsNode()) } func (f *NodeFactory) UpdateGetAccessorDeclaration(node *GetAccessorDeclaration, modifiers *ModifierList, name *PropertyName, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node { @@ -3164,7 +3225,7 @@ func (f *NodeFactory) NewSetAccessorDeclaration(modifiers *ModifierList, name *P data.Type = typeNode data.FullSignature = fullSignature data.Body = body - return f.newNode(KindSetAccessor, data) + return f.newNode(KindSetAccessor, data.AsNode()) } func (f *NodeFactory) UpdateSetAccessorDeclaration(node *SetAccessorDeclaration, modifiers *ModifierList, name *PropertyName, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node { @@ -3219,7 +3280,7 @@ func (f *NodeFactory) NewIndexSignatureDeclaration(modifiers *ModifierList, para data.modifiers = modifiers data.Parameters = parameters data.Type = typeNode - return f.newNode(KindIndexSignature, data) + return f.newNode(KindIndexSignature, data.AsNode()) } func (f *NodeFactory) UpdateIndexSignatureDeclaration(node *IndexSignatureDeclaration, modifiers *ModifierList, parameters *ParameterList, typeNode *TypeNode) *Node { @@ -3266,7 +3327,7 @@ func (f *NodeFactory) NewMethodSignatureDeclaration(modifiers *ModifierList, nam data.TypeParameters = typeParameters data.Parameters = parameters data.Type = typeNode - return f.newNode(KindMethodSignature, data) + return f.newNode(KindMethodSignature, data.AsNode()) } func (f *NodeFactory) UpdateMethodSignatureDeclaration(node *MethodSignatureDeclaration, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node { @@ -3327,7 +3388,7 @@ func (f *NodeFactory) NewMethodDeclaration(modifiers *ModifierList, asteriskToke data.Type = typeNode data.FullSignature = fullSignature data.Body = body - return f.newNode(KindMethodDeclaration, data) + return f.newNode(KindMethodDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateMethodDeclaration(node *MethodDeclaration, modifiers *ModifierList, asteriskToken *AsteriskToken, name *PropertyName, postfixToken *TokenNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node { @@ -3386,7 +3447,7 @@ func (f *NodeFactory) NewPropertySignatureDeclaration(modifiers *ModifierList, n data.PostfixToken = postfixToken data.Type = typeNode data.Initializer = initializer - return f.newNode(KindPropertySignature, data) + return f.newNode(KindPropertySignature, data.AsNode()) } func (f *NodeFactory) UpdatePropertySignatureDeclaration(node *PropertySignatureDeclaration, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { @@ -3441,7 +3502,7 @@ func (f *NodeFactory) NewPropertyDeclaration(modifiers *ModifierList, name *Prop data.PostfixToken = postfixToken data.Type = typeNode data.Initializer = initializer - return f.newNode(KindPropertyDeclaration, data) + return f.newNode(KindPropertyDeclaration, data.AsNode()) } func (f *NodeFactory) UpdatePropertyDeclaration(node *PropertyDeclaration, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { @@ -3487,7 +3548,7 @@ type SemicolonClassElement struct { func (f *NodeFactory) NewSemicolonClassElement() *Node { data := &SemicolonClassElement{} - return f.newNode(KindSemicolonClassElement, data) + return f.newNode(KindSemicolonClassElement, data.AsNode()) } func (node *SemicolonClassElement) Clone(f NodeFactoryCoercible) *Node { @@ -3517,7 +3578,7 @@ func (f *NodeFactory) NewClassStaticBlockDeclaration(modifiers *ModifierList, bo data := &ClassStaticBlockDeclaration{} data.modifiers = modifiers data.Body = body - return f.newNode(KindClassStaticBlockDeclaration, data) + return f.newNode(KindClassStaticBlockDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateClassStaticBlockDeclaration(node *ClassStaticBlockDeclaration, modifiers *ModifierList, body *BlockNode) *Node { @@ -3553,7 +3614,7 @@ type OmittedExpression struct { func (f *NodeFactory) NewOmittedExpression() *Node { data := &OmittedExpression{} - return f.newNode(KindOmittedExpression, data) + return f.newNode(KindOmittedExpression, data.AsNode()) } func (node *OmittedExpression) Clone(f NodeFactoryCoercible) *Node { @@ -3574,8 +3635,13 @@ type KeywordExpression struct { } func (f *NodeFactory) NewKeywordExpression(kind KeywordExpressionSyntaxKind) *Node { + switch kind { + case KindFalseKeyword, KindImportKeyword, KindNullKeyword, KindSuperKeyword, KindThisKeyword, KindTrueKeyword: + default: + panic("Invalid node kind for KeywordExpression") + } data := f.keywordExpressionArena.New() - return f.newNode(kind, data) + return f.newNode(kind, data.AsNode()) } func (node *KeywordExpression) Clone(f NodeFactoryCoercible) *Node { @@ -3603,7 +3669,7 @@ func (f *NodeFactory) NewStringLiteral(text string, tokenFlags TokenFlags) *Node data.Text = text data.TokenFlags = tokenFlags & TokenFlagsStringLiteralFlags f.textCount++ - return f.newNode(KindStringLiteral, data) + return f.newNode(KindStringLiteral, data.AsNode()) } func (node *StringLiteral) Clone(f NodeFactoryCoercible) *Node { @@ -3627,7 +3693,7 @@ func (f *NodeFactory) NewNumericLiteral(text string, tokenFlags TokenFlags) *Nod data.Text = text data.TokenFlags = tokenFlags & TokenFlagsNumericLiteralFlags f.textCount++ - return f.newNode(KindNumericLiteral, data) + return f.newNode(KindNumericLiteral, data.AsNode()) } func (node *NumericLiteral) Clone(f NodeFactoryCoercible) *Node { @@ -3651,7 +3717,7 @@ func (f *NodeFactory) NewBigIntLiteral(text string, tokenFlags TokenFlags) *Node data.Text = text data.TokenFlags = tokenFlags & TokenFlagsNumericLiteralFlags f.textCount++ - return f.newNode(KindBigIntLiteral, data) + return f.newNode(KindBigIntLiteral, data.AsNode()) } func (node *BigIntLiteral) Clone(f NodeFactoryCoercible) *Node { @@ -3675,7 +3741,7 @@ func (f *NodeFactory) NewRegularExpressionLiteral(text string, tokenFlags TokenF data.Text = text data.TokenFlags = tokenFlags & TokenFlagsRegularExpressionLiteralFlags f.textCount++ - return f.newNode(KindRegularExpressionLiteral, data) + return f.newNode(KindRegularExpressionLiteral, data.AsNode()) } func (node *RegularExpressionLiteral) Clone(f NodeFactoryCoercible) *Node { @@ -3701,7 +3767,7 @@ func (f *NodeFactory) NewNoSubstitutionTemplateLiteral(text string, templateFlag data.Text = text data.TemplateFlags = templateFlags & TokenFlagsTemplateLiteralLikeFlags f.textCount++ - return f.newNode(KindNoSubstitutionTemplateLiteral, data) + return f.newNode(KindNoSubstitutionTemplateLiteral, data.AsNode()) } func (node *NoSubstitutionTemplateLiteral) Clone(f NodeFactoryCoercible) *Node { @@ -3734,7 +3800,7 @@ func (f *NodeFactory) NewBinaryExpression(modifiers *ModifierList, left *Express data.Type = typeNode data.OperatorToken = operatorToken data.Right = right - return f.newNode(KindBinaryExpression, data) + return f.newNode(KindBinaryExpression, data.AsNode()) } func (f *NodeFactory) UpdateBinaryExpression(node *BinaryExpression, modifiers *ModifierList, left *Expression, typeNode *TypeNode, operatorToken *BinaryOperatorToken, right *Expression) *Node { @@ -3778,7 +3844,7 @@ func (f *NodeFactory) NewPrefixUnaryExpression(operator Kind, operand *Expressio data := f.prefixUnaryExpressionArena.New() data.Operator = operator data.Operand = operand - return f.newNode(KindPrefixUnaryExpression, data) + return f.newNode(KindPrefixUnaryExpression, data.AsNode()) } func (f *NodeFactory) UpdatePrefixUnaryExpression(node *PrefixUnaryExpression, operator Kind, operand *Expression) *Node { @@ -3822,7 +3888,7 @@ func (f *NodeFactory) NewPostfixUnaryExpression(operand *Expression, operator Ki data := &PostfixUnaryExpression{} data.Operand = operand data.Operator = operator - return f.newNode(KindPostfixUnaryExpression, data) + return f.newNode(KindPostfixUnaryExpression, data.AsNode()) } func (f *NodeFactory) UpdatePostfixUnaryExpression(node *PostfixUnaryExpression, operand *Expression, operator Kind) *Node { @@ -3866,7 +3932,7 @@ func (f *NodeFactory) NewYieldExpression(asteriskToken *AsteriskToken, expressio data := &YieldExpression{} data.AsteriskToken = asteriskToken data.Expression = expression - return f.newNode(KindYieldExpression, data) + return f.newNode(KindYieldExpression, data.AsNode()) } func (f *NodeFactory) UpdateYieldExpression(node *YieldExpression, asteriskToken *AsteriskToken, expression *Expression) *Node { @@ -3915,7 +3981,7 @@ func (f *NodeFactory) NewArrowFunction(modifiers *ModifierList, typeParameters * data.FullSignature = fullSignature data.EqualsGreaterThanToken = equalsGreaterThanToken data.Body = body - return f.newNode(KindArrowFunction, data) + return f.newNode(KindArrowFunction, data.AsNode()) } func (f *NodeFactory) UpdateArrowFunction(node *ArrowFunction, modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, equalsGreaterThanToken *EqualsGreaterThanToken, body *ConciseBody) *Node { @@ -3972,7 +4038,7 @@ func (f *NodeFactory) NewFunctionExpression(modifiers *ModifierList, asteriskTok data.Type = typeNode data.FullSignature = fullSignature data.Body = body - return f.newNode(KindFunctionExpression, data) + return f.newNode(KindFunctionExpression, data.AsNode()) } func (f *NodeFactory) UpdateFunctionExpression(node *FunctionExpression, modifiers *ModifierList, asteriskToken *AsteriskToken, name *IdentifierNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node { @@ -4023,7 +4089,7 @@ func (f *NodeFactory) NewAsExpression(expression *Expression, typeNode *TypeNode data := &AsExpression{} data.Expression = expression data.Type = typeNode - return f.newNode(KindAsExpression, data) + return f.newNode(KindAsExpression, data.AsNode()) } func (f *NodeFactory) UpdateAsExpression(node *AsExpression, expression *Expression, typeNode *TypeNode) *Node { @@ -4063,7 +4129,7 @@ func (f *NodeFactory) NewSatisfiesExpression(expression *Expression, typeNode *T data := &SatisfiesExpression{} data.Expression = expression data.Type = typeNode - return f.newNode(KindSatisfiesExpression, data) + return f.newNode(KindSatisfiesExpression, data.AsNode()) } func (f *NodeFactory) UpdateSatisfiesExpression(node *SatisfiesExpression, expression *Expression, typeNode *TypeNode) *Node { @@ -4110,7 +4176,7 @@ func (f *NodeFactory) NewConditionalExpression(condition *Expression, questionTo data.WhenTrue = whenTrue data.ColonToken = colonToken data.WhenFalse = whenFalse - return f.newNode(KindConditionalExpression, data) + return f.newNode(KindConditionalExpression, data.AsNode()) } func (f *NodeFactory) UpdateConditionalExpression(node *ConditionalExpression, condition *Expression, questionToken *QuestionToken, whenTrue *Expression, colonToken *ColonToken, whenFalse *Expression) *Node { @@ -4166,7 +4232,7 @@ func (f *NodeFactory) NewPropertyAccessExpression(expression *Expression, questi data.Expression = expression data.QuestionDotToken = questionDotToken data.name = name - node := f.newNode(KindPropertyAccessExpression, data) + node := f.newNode(KindPropertyAccessExpression, data.AsNode()) node.Flags |= flags & NodeFlagsOptionalChain return node } @@ -4216,7 +4282,7 @@ func (f *NodeFactory) NewElementAccessExpression(expression *Expression, questio data.Expression = expression data.QuestionDotToken = questionDotToken data.ArgumentExpression = argumentExpression - node := f.newNode(KindElementAccessExpression, data) + node := f.newNode(KindElementAccessExpression, data.AsNode()) node.Flags |= flags & NodeFlagsOptionalChain return node } @@ -4270,7 +4336,7 @@ func (f *NodeFactory) NewCallExpression(expression *Expression, questionDotToken data.QuestionDotToken = questionDotToken data.TypeArguments = typeArguments data.Arguments = arguments - node := f.newNode(KindCallExpression, data) + node := f.newNode(KindCallExpression, data.AsNode()) node.Flags |= flags & NodeFlagsOptionalChain return node } @@ -4318,7 +4384,7 @@ func (f *NodeFactory) NewNewExpression(expression *Expression, typeArguments *Ty data.Expression = expression data.TypeArguments = typeArguments data.Arguments = arguments - return f.newNode(KindNewExpression, data) + return f.newNode(KindNewExpression, data.AsNode()) } func (f *NodeFactory) UpdateNewExpression(node *NewExpression, expression *Expression, typeArguments *TypeList, arguments *ElementList) *Node { @@ -4360,7 +4426,7 @@ func (f *NodeFactory) NewMetaProperty(keywordToken Kind, name *IdentifierNode) * data := &MetaProperty{} data.KeywordToken = keywordToken data.name = name - return f.newNode(KindMetaProperty, data) + return f.newNode(KindMetaProperty, data.AsNode()) } func (f *NodeFactory) UpdateMetaProperty(node *MetaProperty, keywordToken Kind, name *IdentifierNode) *Node { @@ -4402,7 +4468,7 @@ type NonNullExpression struct { func (f *NodeFactory) NewNonNullExpression(expression *Expression, flags NodeFlags) *Node { data := &NonNullExpression{} data.Expression = expression - node := f.newNode(KindNonNullExpression, data) + node := f.newNode(KindNonNullExpression, data.AsNode()) node.Flags |= flags & NodeFlagsOptionalChain return node } @@ -4442,7 +4508,7 @@ type SpreadElement struct { func (f *NodeFactory) NewSpreadElement(expression *Expression) *Node { data := &SpreadElement{} data.Expression = expression - return f.newNode(KindSpreadElement, data) + return f.newNode(KindSpreadElement, data.AsNode()) } func (f *NodeFactory) UpdateSpreadElement(node *SpreadElement, expression *Expression) *Node { @@ -4483,7 +4549,7 @@ func (f *NodeFactory) NewTemplateExpression(head *TemplateHeadNode, templateSpan data := &TemplateExpression{} data.Head = head data.TemplateSpans = templateSpans - return f.newNode(KindTemplateExpression, data) + return f.newNode(KindTemplateExpression, data.AsNode()) } func (f *NodeFactory) UpdateTemplateExpression(node *TemplateExpression, head *TemplateHeadNode, templateSpans *TemplateSpanList) *Node { @@ -4528,7 +4594,7 @@ func (f *NodeFactory) NewTemplateSpan(expression *Expression, literal *TemplateM data := &TemplateSpan{} data.Expression = expression data.Literal = literal - return f.newNode(KindTemplateSpan, data) + return f.newNode(KindTemplateSpan, data.AsNode()) } func (f *NodeFactory) UpdateTemplateSpan(node *TemplateSpan, expression *Expression, literal *TemplateMiddleOrTail) *Node { @@ -4578,7 +4644,7 @@ func (f *NodeFactory) NewTaggedTemplateExpression(tag *Expression, questionDotTo data.QuestionDotToken = questionDotToken data.TypeArguments = typeArguments data.Template = template - node := f.newNode(KindTaggedTemplateExpression, data) + node := f.newNode(KindTaggedTemplateExpression, data.AsNode()) node.Flags |= flags & NodeFlagsOptionalChain return node } @@ -4621,7 +4687,7 @@ type ParenthesizedExpression struct { func (f *NodeFactory) NewParenthesizedExpression(expression *Expression) *Node { data := f.parenthesizedExpressionArena.New() data.Expression = expression - return f.newNode(KindParenthesizedExpression, data) + return f.newNode(KindParenthesizedExpression, data.AsNode()) } func (f *NodeFactory) UpdateParenthesizedExpression(node *ParenthesizedExpression, expression *Expression) *Node { @@ -4666,7 +4732,7 @@ func (f *NodeFactory) NewArrayLiteralExpression(elements *ElementList, multiLine data := &ArrayLiteralExpression{} data.Elements = elements data.MultiLine = multiLine - return f.newNode(KindArrayLiteralExpression, data) + return f.newNode(KindArrayLiteralExpression, data.AsNode()) } func (f *NodeFactory) UpdateArrayLiteralExpression(node *ArrayLiteralExpression, elements *ElementList, multiLine bool) *Node { @@ -4712,7 +4778,7 @@ func (f *NodeFactory) NewObjectLiteralExpression(properties *NodeList, multiLine data := &ObjectLiteralExpression{} data.Properties = properties data.MultiLine = multiLine - return f.newNode(KindObjectLiteralExpression, data) + return f.newNode(KindObjectLiteralExpression, data.AsNode()) } func (f *NodeFactory) UpdateObjectLiteralExpression(node *ObjectLiteralExpression, properties *NodeList, multiLine bool) *Node { @@ -4756,7 +4822,7 @@ type SpreadAssignment struct { func (f *NodeFactory) NewSpreadAssignment(expression *Expression) *Node { data := &SpreadAssignment{} data.Expression = expression - return f.newNode(KindSpreadAssignment, data) + return f.newNode(KindSpreadAssignment, data.AsNode()) } func (f *NodeFactory) UpdateSpreadAssignment(node *SpreadAssignment, expression *Expression) *Node { @@ -4803,7 +4869,7 @@ func (f *NodeFactory) NewPropertyAssignment(modifiers *ModifierList, name *Prope data.PostfixToken = postfixToken data.Type = typeNode data.Initializer = initializer - return f.newNode(KindPropertyAssignment, data) + return f.newNode(KindPropertyAssignment, data.AsNode()) } func (f *NodeFactory) UpdatePropertyAssignment(node *PropertyAssignment, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { @@ -4860,7 +4926,7 @@ func (f *NodeFactory) NewShorthandPropertyAssignment(modifiers *ModifierList, na data.Type = typeNode data.EqualsToken = equalsToken data.ObjectAssignmentInitializer = objectAssignmentInitializer - return f.newNode(KindShorthandPropertyAssignment, data) + return f.newNode(KindShorthandPropertyAssignment, data.AsNode()) } func (f *NodeFactory) UpdateShorthandPropertyAssignment(node *ShorthandPropertyAssignment, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, equalsToken *EqualsToken, objectAssignmentInitializer *Expression) *Node { @@ -4907,7 +4973,7 @@ type DeleteExpression struct { func (f *NodeFactory) NewDeleteExpression(expression *Expression) *Node { data := &DeleteExpression{} data.Expression = expression - return f.newNode(KindDeleteExpression, data) + return f.newNode(KindDeleteExpression, data.AsNode()) } func (f *NodeFactory) UpdateDeleteExpression(node *DeleteExpression, expression *Expression) *Node { @@ -4949,7 +5015,7 @@ type TypeOfExpression struct { func (f *NodeFactory) NewTypeOfExpression(expression *Expression) *Node { data := &TypeOfExpression{} data.Expression = expression - return f.newNode(KindTypeOfExpression, data) + return f.newNode(KindTypeOfExpression, data.AsNode()) } func (f *NodeFactory) UpdateTypeOfExpression(node *TypeOfExpression, expression *Expression) *Node { @@ -4991,7 +5057,7 @@ type VoidExpression struct { func (f *NodeFactory) NewVoidExpression(expression *Expression) *Node { data := &VoidExpression{} data.Expression = expression - return f.newNode(KindVoidExpression, data) + return f.newNode(KindVoidExpression, data.AsNode()) } func (f *NodeFactory) UpdateVoidExpression(node *VoidExpression, expression *Expression) *Node { @@ -5033,7 +5099,7 @@ type AwaitExpression struct { func (f *NodeFactory) NewAwaitExpression(expression *Expression) *Node { data := &AwaitExpression{} data.Expression = expression - return f.newNode(KindAwaitExpression, data) + return f.newNode(KindAwaitExpression, data.AsNode()) } func (f *NodeFactory) UpdateAwaitExpression(node *AwaitExpression, expression *Expression) *Node { @@ -5073,7 +5139,7 @@ func (f *NodeFactory) NewTypeAssertion(typeNode *TypeNode, expression *Expressio data := &TypeAssertion{} data.Type = typeNode data.Expression = expression - return f.newNode(KindTypeAssertionExpression, data) + return f.newNode(KindTypeAssertionExpression, data.AsNode()) } func (f *NodeFactory) UpdateTypeAssertion(node *TypeAssertion, typeNode *TypeNode, expression *Expression) *Node { @@ -5108,8 +5174,13 @@ type KeywordTypeNode struct { } func (f *NodeFactory) NewKeywordTypeNode(kind KeywordTypeSyntaxKind) *Node { + switch kind { + case KindVoidKeyword, KindAnyKeyword, KindBooleanKeyword, KindIntrinsicKeyword, KindNeverKeyword, KindNumberKeyword, KindObjectKeyword, KindStringKeyword, KindSymbolKeyword, KindUndefinedKeyword, KindUnknownKeyword, KindBigIntKeyword: + default: + panic("Invalid node kind for KeywordTypeNode") + } data := f.keywordTypeNodeArena.New() - return f.newNode(kind, data) + return f.newNode(kind, data.AsNode()) } func (node *KeywordTypeNode) Clone(f NodeFactoryCoercible) *Node { @@ -5135,7 +5206,7 @@ type UnionTypeNode struct { func (f *NodeFactory) NewUnionTypeNode(types *TypeList) *Node { data := f.unionTypeNodeArena.New() data.Types = types - return f.newNode(KindUnionType, data) + return f.newNode(KindUnionType, data.AsNode()) } func (f *NodeFactory) UpdateUnionTypeNode(node *UnionTypeNode, types *TypeList) *Node { @@ -5172,7 +5243,7 @@ type IntersectionTypeNode struct { func (f *NodeFactory) NewIntersectionTypeNode(types *TypeList) *Node { data := f.intersectionTypeNodeArena.New() data.Types = types - return f.newNode(KindIntersectionType, data) + return f.newNode(KindIntersectionType, data.AsNode()) } func (f *NodeFactory) UpdateIntersectionTypeNode(node *IntersectionTypeNode, types *TypeList) *Node { @@ -5217,7 +5288,7 @@ func (f *NodeFactory) NewConditionalTypeNode(checkType *TypeNode, extendsType *T data.ExtendsType = extendsType data.TrueType = trueType data.FalseType = falseType - return f.newNode(KindConditionalType, data) + return f.newNode(KindConditionalType, data.AsNode()) } func (f *NodeFactory) UpdateConditionalTypeNode(node *ConditionalTypeNode, checkType *TypeNode, extendsType *TypeNode, trueType *TypeNode, falseType *TypeNode) *Node { @@ -5260,7 +5331,7 @@ func (f *NodeFactory) NewTypeOperatorNode(operator Kind, typeNode *TypeNode) *No data := f.typeOperatorNodeArena.New() data.Operator = operator data.Type = typeNode - return f.newNode(KindTypeOperator, data) + return f.newNode(KindTypeOperator, data.AsNode()) } func (f *NodeFactory) UpdateTypeOperatorNode(node *TypeOperatorNode, operator Kind, typeNode *TypeNode) *Node { @@ -5298,7 +5369,7 @@ type InferTypeNode struct { func (f *NodeFactory) NewInferTypeNode(typeParameter *TypeParameterDeclarationNode) *Node { data := &InferTypeNode{} data.TypeParameter = typeParameter - return f.newNode(KindInferType, data) + return f.newNode(KindInferType, data.AsNode()) } func (f *NodeFactory) UpdateInferTypeNode(node *InferTypeNode, typeParameter *TypeParameterDeclarationNode) *Node { @@ -5336,7 +5407,7 @@ type ArrayTypeNode struct { func (f *NodeFactory) NewArrayTypeNode(elementType *TypeNode) *Node { data := f.arrayTypeNodeArena.New() data.ElementType = elementType - return f.newNode(KindArrayType, data) + return f.newNode(KindArrayType, data.AsNode()) } func (f *NodeFactory) UpdateArrayTypeNode(node *ArrayTypeNode, elementType *TypeNode) *Node { @@ -5376,7 +5447,7 @@ func (f *NodeFactory) NewIndexedAccessTypeNode(objectType *TypeNode, indexType * data := f.indexedAccessTypeNodeArena.New() data.ObjectType = objectType data.IndexType = indexType - return f.newNode(KindIndexedAccessType, data) + return f.newNode(KindIndexedAccessType, data.AsNode()) } func (f *NodeFactory) UpdateIndexedAccessTypeNode(node *IndexedAccessTypeNode, objectType *TypeNode, indexType *TypeNode) *Node { @@ -5415,7 +5486,7 @@ func (f *NodeFactory) NewTypeReferenceNode(typeName *EntityName, typeArguments * data := f.typeReferenceNodeArena.New() data.TypeName = typeName data.TypeArguments = typeArguments - return f.newNode(KindTypeReference, data) + return f.newNode(KindTypeReference, data.AsNode()) } func (f *NodeFactory) UpdateTypeReferenceNode(node *TypeReferenceNode, typeName *EntityName, typeArguments *TypeList) *Node { @@ -5456,7 +5527,7 @@ func (f *NodeFactory) NewExpressionWithTypeArguments(expression *Expression, typ data := f.expressionWithTypeArgumentsArena.New() data.Expression = expression data.TypeArguments = typeArguments - return f.newNode(KindExpressionWithTypeArguments, data) + return f.newNode(KindExpressionWithTypeArguments, data.AsNode()) } func (f *NodeFactory) UpdateExpressionWithTypeArguments(node *ExpressionWithTypeArguments, expression *Expression, typeArguments *TypeList) *Node { @@ -5494,7 +5565,7 @@ type LiteralTypeNode struct { func (f *NodeFactory) NewLiteralTypeNode(literal *Node) *Node { data := f.literalTypeNodeArena.New() data.Literal = literal - return f.newNode(KindLiteralType, data) + return f.newNode(KindLiteralType, data.AsNode()) } func (f *NodeFactory) UpdateLiteralTypeNode(node *LiteralTypeNode, literal *Node) *Node { @@ -5530,7 +5601,7 @@ type ThisTypeNode struct { func (f *NodeFactory) NewThisTypeNode() *Node { data := &ThisTypeNode{} - return f.newNode(KindThisType, data) + return f.newNode(KindThisType, data.AsNode()) } func (node *ThisTypeNode) Clone(f NodeFactoryCoercible) *Node { @@ -5557,7 +5628,7 @@ func (f *NodeFactory) NewTypePredicateNode(assertsModifier *AssertsKeyword, para data.AssertsModifier = assertsModifier data.ParameterName = parameterName data.Type = typeNode - return f.newNode(KindTypePredicate, data) + return f.newNode(KindTypePredicate, data.AsNode()) } func (f *NodeFactory) UpdateTypePredicateNode(node *TypePredicateNode, assertsModifier *AssertsKeyword, parameterName *TypePredicateParameterName, typeNode *TypeNode) *Node { @@ -5598,7 +5669,7 @@ func (f *NodeFactory) NewImportAttribute(name *ImportAttributeName, value *Expre data := &ImportAttribute{} data.name = name data.Value = value - return f.newNode(KindImportAttribute, data) + return f.newNode(KindImportAttribute, data.AsNode()) } func (f *NodeFactory) UpdateImportAttribute(node *ImportAttribute, name *ImportAttributeName, value *Expression) *Node { @@ -5650,7 +5721,7 @@ func (f *NodeFactory) NewImportAttributes(token Kind, attributes *ImportAttribut data.Token = token data.Attributes = attributes data.MultiLine = multiLine - return f.newNode(KindImportAttributes, data) + return f.newNode(KindImportAttributes, data.AsNode()) } func (f *NodeFactory) UpdateImportAttributes(node *ImportAttributes, token Kind, attributes *ImportAttributeList, multiLine bool) *Node { @@ -5693,7 +5764,7 @@ func (f *NodeFactory) NewTypeQueryNode(exprName *EntityName, typeArguments *Type data := &TypeQueryNode{} data.ExprName = exprName data.TypeArguments = typeArguments - return f.newNode(KindTypeQuery, data) + return f.newNode(KindTypeQuery, data.AsNode()) } func (f *NodeFactory) UpdateTypeQueryNode(node *TypeQueryNode, exprName *EntityName, typeArguments *TypeList) *Node { @@ -5743,7 +5814,7 @@ func (f *NodeFactory) NewMappedTypeNode(readonlyToken *TokenNode, typeParameter data.QuestionToken = questionToken data.Type = typeNode data.Members = members - return f.newNode(KindMappedType, data) + return f.newNode(KindMappedType, data.AsNode()) } func (f *NodeFactory) UpdateMappedTypeNode(node *MappedTypeNode, readonlyToken *TokenNode, typeParameter *TypeParameterDeclarationNode, nameType *TypeNode, questionToken *TokenNode, typeNode *TypeNode, members *TypeElementList) *Node { @@ -5787,7 +5858,7 @@ type TypeLiteralNode struct { func (f *NodeFactory) NewTypeLiteralNode(members *TypeElementList) *Node { data := f.typeLiteralNodeArena.New() data.Members = members - return f.newNode(KindTypeLiteral, data) + return f.newNode(KindTypeLiteral, data.AsNode()) } func (f *NodeFactory) UpdateTypeLiteralNode(node *TypeLiteralNode, members *TypeElementList) *Node { @@ -5825,7 +5896,7 @@ type TupleTypeNode struct { func (f *NodeFactory) NewTupleTypeNode(elements *TypeList) *Node { data := &TupleTypeNode{} data.Elements = elements - return f.newNode(KindTupleType, data) + return f.newNode(KindTupleType, data.AsNode()) } func (f *NodeFactory) UpdateTupleTypeNode(node *TupleTypeNode, elements *TypeList) *Node { @@ -5870,7 +5941,7 @@ func (f *NodeFactory) NewNamedTupleMember(dotDotDotToken *DotDotDotToken, name * data.name = name data.QuestionToken = questionToken data.Type = typeNode - return f.newNode(KindNamedTupleMember, data) + return f.newNode(KindNamedTupleMember, data.AsNode()) } func (f *NodeFactory) UpdateNamedTupleMember(node *NamedTupleMember, dotDotDotToken *DotDotDotToken, name *IdentifierNode, questionToken *QuestionToken, typeNode *TypeNode) *Node { @@ -5915,7 +5986,7 @@ type OptionalTypeNode struct { func (f *NodeFactory) NewOptionalTypeNode(typeNode *TypeNode) *Node { data := &OptionalTypeNode{} data.Type = typeNode - return f.newNode(KindOptionalType, data) + return f.newNode(KindOptionalType, data.AsNode()) } func (f *NodeFactory) UpdateOptionalTypeNode(node *OptionalTypeNode, typeNode *TypeNode) *Node { @@ -5953,7 +6024,7 @@ type RestTypeNode struct { func (f *NodeFactory) NewRestTypeNode(typeNode *TypeNode) *Node { data := &RestTypeNode{} data.Type = typeNode - return f.newNode(KindRestType, data) + return f.newNode(KindRestType, data.AsNode()) } func (f *NodeFactory) UpdateRestTypeNode(node *RestTypeNode, typeNode *TypeNode) *Node { @@ -5991,7 +6062,7 @@ type ParenthesizedTypeNode struct { func (f *NodeFactory) NewParenthesizedTypeNode(typeNode *TypeNode) *Node { data := f.parenthesizedTypeNodeArena.New() data.Type = typeNode - return f.newNode(KindParenthesizedType, data) + return f.newNode(KindParenthesizedType, data.AsNode()) } func (f *NodeFactory) UpdateParenthesizedTypeNode(node *ParenthesizedTypeNode, typeNode *TypeNode) *Node { @@ -6030,7 +6101,7 @@ func (f *NodeFactory) NewFunctionTypeNode(typeParameters *TypeParameterList, par data.TypeParameters = typeParameters data.Parameters = parameters data.Type = typeNode - return f.newNode(KindFunctionType, data) + return f.newNode(KindFunctionType, data.AsNode()) } func (f *NodeFactory) UpdateFunctionTypeNode(node *FunctionTypeNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node { @@ -6070,7 +6141,7 @@ func (f *NodeFactory) NewConstructorTypeNode(modifiers *ModifierList, typeParame data.TypeParameters = typeParameters data.Parameters = parameters data.Type = typeNode - return f.newNode(KindConstructorType, data) + return f.newNode(KindConstructorType, data.AsNode()) } func (f *NodeFactory) UpdateConstructorTypeNode(node *ConstructorTypeNode, modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node { @@ -6114,7 +6185,7 @@ func (f *NodeFactory) NewTemplateHead(text string, rawText string, templateFlags data.RawText = rawText data.TemplateFlags = templateFlags & TokenFlagsTemplateLiteralLikeFlags f.textCount++ - return f.newNode(KindTemplateHead, data) + return f.newNode(KindTemplateHead, data.AsNode()) } func (node *TemplateHead) Clone(f NodeFactoryCoercible) *Node { @@ -6140,7 +6211,7 @@ func (f *NodeFactory) NewTemplateMiddle(text string, rawText string, templateFla data.RawText = rawText data.TemplateFlags = templateFlags & TokenFlagsTemplateLiteralLikeFlags f.textCount++ - return f.newNode(KindTemplateMiddle, data) + return f.newNode(KindTemplateMiddle, data.AsNode()) } func (node *TemplateMiddle) Clone(f NodeFactoryCoercible) *Node { @@ -6166,7 +6237,7 @@ func (f *NodeFactory) NewTemplateTail(text string, rawText string, templateFlags data.RawText = rawText data.TemplateFlags = templateFlags & TokenFlagsTemplateLiteralLikeFlags f.textCount++ - return f.newNode(KindTemplateTail, data) + return f.newNode(KindTemplateTail, data.AsNode()) } func (node *TemplateTail) Clone(f NodeFactoryCoercible) *Node { @@ -6191,7 +6262,7 @@ func (f *NodeFactory) NewTemplateLiteralTypeNode(head *TemplateHeadNode, templat data := &TemplateLiteralTypeNode{} data.Head = head data.TemplateSpans = templateSpans - return f.newNode(KindTemplateLiteralType, data) + return f.newNode(KindTemplateLiteralType, data.AsNode()) } func (f *NodeFactory) UpdateTemplateLiteralTypeNode(node *TemplateLiteralTypeNode, head *TemplateHeadNode, templateSpans *TemplateLiteralTypeSpanList) *Node { @@ -6231,7 +6302,7 @@ func (f *NodeFactory) NewTemplateLiteralTypeSpan(typeNode *TypeNode, literal *Te data := &TemplateLiteralTypeSpan{} data.Type = typeNode data.Literal = literal - return f.newNode(KindTemplateLiteralTypeSpan, data) + return f.newNode(KindTemplateLiteralTypeSpan, data.AsNode()) } func (f *NodeFactory) UpdateTemplateLiteralTypeSpan(node *TemplateLiteralTypeSpan, typeNode *TypeNode, literal *TemplateMiddleOrTail) *Node { @@ -6273,7 +6344,7 @@ func (f *NodeFactory) NewSyntheticExpression(typeNode any, isSpread bool, tupleN data.Type = typeNode data.IsSpread = isSpread data.TupleNameSource = tupleNameSource - return f.newNode(KindSyntheticExpression, data) + return f.newNode(KindSyntheticExpression, data.AsNode()) } func (f *NodeFactory) UpdateSyntheticExpression(node *SyntheticExpression, typeNode any, isSpread bool, tupleNameSource *Node) *Node { @@ -6311,7 +6382,7 @@ type PartiallyEmittedExpression struct { func (f *NodeFactory) NewPartiallyEmittedExpression(expression *Expression) *Node { data := &PartiallyEmittedExpression{} data.Expression = expression - return f.newNode(KindPartiallyEmittedExpression, data) + return f.newNode(KindPartiallyEmittedExpression, data.AsNode()) } func (f *NodeFactory) UpdatePartiallyEmittedExpression(node *PartiallyEmittedExpression, expression *Expression) *Node { @@ -6358,7 +6429,7 @@ func (f *NodeFactory) NewJsxElement(openingElement *JsxOpeningElementNode, child data.OpeningElement = openingElement data.Children = children data.ClosingElement = closingElement - return f.newNode(KindJsxElement, data) + return f.newNode(KindJsxElement, data.AsNode()) } func (f *NodeFactory) UpdateJsxElement(node *JsxElement, openingElement *JsxOpeningElementNode, children *JsxChildList, closingElement *JsxClosingElementNode) *Node { @@ -6398,7 +6469,7 @@ type JsxAttributes struct { func (f *NodeFactory) NewJsxAttributes(properties *JsxAttributeList) *Node { data := &JsxAttributes{} data.Properties = properties - return f.newNode(KindJsxAttributes, data) + return f.newNode(KindJsxAttributes, data.AsNode()) } func (f *NodeFactory) UpdateJsxAttributes(node *JsxAttributes, properties *JsxAttributeList) *Node { @@ -6439,7 +6510,7 @@ func (f *NodeFactory) NewJsxNamespacedName(namespace *IdentifierNode, name *Iden data := &JsxNamespacedName{} data.Namespace = namespace data.name = name - return f.newNode(KindJsxNamespacedName, data) + return f.newNode(KindJsxNamespacedName, data.AsNode()) } func (f *NodeFactory) UpdateJsxNamespacedName(node *JsxNamespacedName, namespace *IdentifierNode, name *IdentifierNode) *Node { @@ -6486,7 +6557,7 @@ func (f *NodeFactory) NewJsxOpeningElement(tagName *JsxTagNameExpression, typeAr data.TagName = tagName data.TypeArguments = typeArguments data.Attributes = attributes - return f.newNode(KindJsxOpeningElement, data) + return f.newNode(KindJsxOpeningElement, data.AsNode()) } func (f *NodeFactory) UpdateJsxOpeningElement(node *JsxOpeningElement, tagName *JsxTagNameExpression, typeArguments *TypeList, attributes *JsxAttributesNode) *Node { @@ -6529,7 +6600,7 @@ func (f *NodeFactory) NewJsxSelfClosingElement(tagName *JsxTagNameExpression, ty data.TagName = tagName data.TypeArguments = typeArguments data.Attributes = attributes - return f.newNode(KindJsxSelfClosingElement, data) + return f.newNode(KindJsxSelfClosingElement, data.AsNode()) } func (f *NodeFactory) UpdateJsxSelfClosingElement(node *JsxSelfClosingElement, tagName *JsxTagNameExpression, typeArguments *TypeList, attributes *JsxAttributesNode) *Node { @@ -6572,7 +6643,7 @@ func (f *NodeFactory) NewJsxFragment(openingFragment *JsxOpeningFragmentNode, ch data.OpeningFragment = openingFragment data.Children = children data.ClosingFragment = closingFragment - return f.newNode(KindJsxFragment, data) + return f.newNode(KindJsxFragment, data.AsNode()) } func (f *NodeFactory) UpdateJsxFragment(node *JsxFragment, openingFragment *JsxOpeningFragmentNode, children *JsxChildList, closingFragment *JsxClosingFragmentNode) *Node { @@ -6608,7 +6679,7 @@ type JsxOpeningFragment struct { func (f *NodeFactory) NewJsxOpeningFragment() *Node { data := &JsxOpeningFragment{} - return f.newNode(KindJsxOpeningFragment, data) + return f.newNode(KindJsxOpeningFragment, data.AsNode()) } func (node *JsxOpeningFragment) Clone(f NodeFactoryCoercible) *Node { @@ -6629,7 +6700,7 @@ type JsxClosingFragment struct { func (f *NodeFactory) NewJsxClosingFragment() *Node { data := &JsxClosingFragment{} - return f.newNode(KindJsxClosingFragment, data) + return f.newNode(KindJsxClosingFragment, data.AsNode()) } func (node *JsxClosingFragment) Clone(f NodeFactoryCoercible) *Node { @@ -6656,7 +6727,7 @@ func (f *NodeFactory) NewJsxAttribute(name *JsxAttributeName, initializer *JsxAt data := &JsxAttribute{} data.name = name data.Initializer = initializer - return f.newNode(KindJsxAttribute, data) + return f.newNode(KindJsxAttribute, data.AsNode()) } func (f *NodeFactory) UpdateJsxAttribute(node *JsxAttribute, name *JsxAttributeName, initializer *JsxAttributeValue) *Node { @@ -6700,7 +6771,7 @@ type JsxSpreadAttribute struct { func (f *NodeFactory) NewJsxSpreadAttribute(expression *Expression) *Node { data := &JsxSpreadAttribute{} data.Expression = expression - return f.newNode(KindJsxSpreadAttribute, data) + return f.newNode(KindJsxSpreadAttribute, data.AsNode()) } func (f *NodeFactory) UpdateJsxSpreadAttribute(node *JsxSpreadAttribute, expression *Expression) *Node { @@ -6738,7 +6809,7 @@ type JsxClosingElement struct { func (f *NodeFactory) NewJsxClosingElement(tagName *JsxTagNameExpression) *Node { data := &JsxClosingElement{} data.TagName = tagName - return f.newNode(KindJsxClosingElement, data) + return f.newNode(KindJsxClosingElement, data.AsNode()) } func (f *NodeFactory) UpdateJsxClosingElement(node *JsxClosingElement, tagName *JsxTagNameExpression) *Node { @@ -6778,7 +6849,7 @@ func (f *NodeFactory) NewJsxExpression(dotDotDotToken *DotDotDotToken, expressio data := &JsxExpression{} data.DotDotDotToken = dotDotDotToken data.Expression = expression - return f.newNode(KindJsxExpression, data) + return f.newNode(KindJsxExpression, data.AsNode()) } func (f *NodeFactory) UpdateJsxExpression(node *JsxExpression, dotDotDotToken *DotDotDotToken, expression *Expression) *Node { @@ -6819,7 +6890,7 @@ func (f *NodeFactory) NewJsxText(text string, containsOnlyTriviaWhiteSpaces bool data.Text = text data.ContainsOnlyTriviaWhiteSpaces = containsOnlyTriviaWhiteSpaces f.textCount++ - return f.newNode(KindJsxText, data) + return f.newNode(KindJsxText, data.AsNode()) } func (node *JsxText) Clone(f NodeFactoryCoercible) *Node { @@ -6842,7 +6913,7 @@ type SyntaxList struct { func (f *NodeFactory) NewSyntaxList(children []*Node) *Node { data := &SyntaxList{} data.Children = children - return f.newNode(KindSyntaxList, data) + return f.newNode(KindSyntaxList, data.AsNode()) } func (f *NodeFactory) UpdateSyntaxList(node *SyntaxList, children []*Node) *Node { @@ -6883,7 +6954,7 @@ func (f *NodeFactory) NewJSDoc(comment *NodeList, tags *NodeList) *Node { data := f.jsdocArena.New() data.Comment = comment data.Tags = tags - return f.newNode(KindJSDoc, data) + return f.newNode(KindJSDoc, data.AsNode()) } func (f *NodeFactory) UpdateJSDoc(node *JSDoc, comment *NodeList, tags *NodeList) *Node { @@ -6921,7 +6992,7 @@ type JSDocTypeExpression struct { func (f *NodeFactory) NewJSDocTypeExpression(typeNode *TypeNode) *Node { data := &JSDocTypeExpression{} data.Type = typeNode - return f.newNode(KindJSDocTypeExpression, data) + return f.newNode(KindJSDocTypeExpression, data.AsNode()) } func (f *NodeFactory) UpdateJSDocTypeExpression(node *JSDocTypeExpression, typeNode *TypeNode) *Node { @@ -6959,7 +7030,7 @@ type JSDocNonNullableType struct { func (f *NodeFactory) NewJSDocNonNullableType(typeNode *TypeNode) *Node { data := &JSDocNonNullableType{} data.Type = typeNode - return f.newNode(KindJSDocNonNullableType, data) + return f.newNode(KindJSDocNonNullableType, data.AsNode()) } func (f *NodeFactory) UpdateJSDocNonNullableType(node *JSDocNonNullableType, typeNode *TypeNode) *Node { @@ -6997,7 +7068,7 @@ type JSDocNullableType struct { func (f *NodeFactory) NewJSDocNullableType(typeNode *TypeNode) *Node { data := &JSDocNullableType{} data.Type = typeNode - return f.newNode(KindJSDocNullableType, data) + return f.newNode(KindJSDocNullableType, data.AsNode()) } func (f *NodeFactory) UpdateJSDocNullableType(node *JSDocNullableType, typeNode *TypeNode) *Node { @@ -7033,7 +7104,7 @@ type JSDocAllType struct { func (f *NodeFactory) NewJSDocAllType() *Node { data := &JSDocAllType{} - return f.newNode(KindJSDocAllType, data) + return f.newNode(KindJSDocAllType, data.AsNode()) } func (node *JSDocAllType) Clone(f NodeFactoryCoercible) *Node { @@ -7056,7 +7127,7 @@ type JSDocVariadicType struct { func (f *NodeFactory) NewJSDocVariadicType(typeNode *TypeNode) *Node { data := &JSDocVariadicType{} data.Type = typeNode - return f.newNode(KindJSDocVariadicType, data) + return f.newNode(KindJSDocVariadicType, data.AsNode()) } func (f *NodeFactory) UpdateJSDocVariadicType(node *JSDocVariadicType, typeNode *TypeNode) *Node { @@ -7094,7 +7165,7 @@ type JSDocOptionalType struct { func (f *NodeFactory) NewJSDocOptionalType(typeNode *TypeNode) *Node { data := &JSDocOptionalType{} data.Type = typeNode - return f.newNode(KindJSDocOptionalType, data) + return f.newNode(KindJSDocOptionalType, data.AsNode()) } func (f *NodeFactory) UpdateJSDocOptionalType(node *JSDocOptionalType, typeNode *TypeNode) *Node { @@ -7134,7 +7205,7 @@ func (f *NodeFactory) NewJSDocTypeTag(tagName *IdentifierNode, typeExpression *N data.TagName = tagName data.TypeExpression = typeExpression data.Comment = comment - return f.newNode(KindJSDocTypeTag, data) + return f.newNode(KindJSDocTypeTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocTypeTag(node *JSDocTypeTag, tagName *IdentifierNode, typeExpression *Node, comment *NodeList) *Node { @@ -7172,7 +7243,7 @@ func (f *NodeFactory) NewJSDocUnknownTag(tagName *IdentifierNode, comment *NodeL data := f.jsdocUnknownTagArena.New() data.TagName = tagName data.Comment = comment - return f.newNode(KindJSDocUnknownTag, data) + return f.newNode(KindJSDocUnknownTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocUnknownTag(node *JSDocUnknownTag, tagName *IdentifierNode, comment *NodeList) *Node { @@ -7214,7 +7285,7 @@ func (f *NodeFactory) NewJSDocTemplateTag(tagName *IdentifierNode, constraint *N data.Constraint = constraint data.TypeParameters = typeParameters data.Comment = comment - return f.newNode(KindJSDocTemplateTag, data) + return f.newNode(KindJSDocTemplateTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocTemplateTag(node *JSDocTemplateTag, tagName *IdentifierNode, constraint *Node, typeParameters *TypeParameterList, comment *NodeList) *Node { @@ -7257,7 +7328,7 @@ func (f *NodeFactory) NewJSDocReturnTag(tagName *IdentifierNode, typeExpression data.TagName = tagName data.TypeExpression = typeExpression data.Comment = comment - return f.newNode(KindJSDocReturnTag, data) + return f.newNode(KindJSDocReturnTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocReturnTag(node *JSDocReturnTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { @@ -7295,7 +7366,7 @@ func (f *NodeFactory) NewJSDocPublicTag(tagName *IdentifierNode, comment *NodeLi data := &JSDocPublicTag{} data.TagName = tagName data.Comment = comment - return f.newNode(KindJSDocPublicTag, data) + return f.newNode(KindJSDocPublicTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocPublicTag(node *JSDocPublicTag, tagName *IdentifierNode, comment *NodeList) *Node { @@ -7333,7 +7404,7 @@ func (f *NodeFactory) NewJSDocPrivateTag(tagName *IdentifierNode, comment *NodeL data := &JSDocPrivateTag{} data.TagName = tagName data.Comment = comment - return f.newNode(KindJSDocPrivateTag, data) + return f.newNode(KindJSDocPrivateTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocPrivateTag(node *JSDocPrivateTag, tagName *IdentifierNode, comment *NodeList) *Node { @@ -7371,7 +7442,7 @@ func (f *NodeFactory) NewJSDocProtectedTag(tagName *IdentifierNode, comment *Nod data := &JSDocProtectedTag{} data.TagName = tagName data.Comment = comment - return f.newNode(KindJSDocProtectedTag, data) + return f.newNode(KindJSDocProtectedTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocProtectedTag(node *JSDocProtectedTag, tagName *IdentifierNode, comment *NodeList) *Node { @@ -7409,7 +7480,7 @@ func (f *NodeFactory) NewJSDocReadonlyTag(tagName *IdentifierNode, comment *Node data := &JSDocReadonlyTag{} data.TagName = tagName data.Comment = comment - return f.newNode(KindJSDocReadonlyTag, data) + return f.newNode(KindJSDocReadonlyTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocReadonlyTag(node *JSDocReadonlyTag, tagName *IdentifierNode, comment *NodeList) *Node { @@ -7447,7 +7518,7 @@ func (f *NodeFactory) NewJSDocOverrideTag(tagName *IdentifierNode, comment *Node data := &JSDocOverrideTag{} data.TagName = tagName data.Comment = comment - return f.newNode(KindJSDocOverrideTag, data) + return f.newNode(KindJSDocOverrideTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocOverrideTag(node *JSDocOverrideTag, tagName *IdentifierNode, comment *NodeList) *Node { @@ -7485,7 +7556,7 @@ func (f *NodeFactory) NewJSDocDeprecatedTag(tagName *IdentifierNode, comment *No data := f.jsdocDeprecatedTagArena.New() data.TagName = tagName data.Comment = comment - return f.newNode(KindJSDocDeprecatedTag, data) + return f.newNode(KindJSDocDeprecatedTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocDeprecatedTag(node *JSDocDeprecatedTag, tagName *IdentifierNode, comment *NodeList) *Node { @@ -7525,7 +7596,7 @@ func (f *NodeFactory) NewJSDocSeeTag(tagName *IdentifierNode, nameExpression *Ty data.TagName = tagName data.NameExpression = nameExpression data.Comment = comment - return f.newNode(KindJSDocSeeTag, data) + return f.newNode(KindJSDocSeeTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocSeeTag(node *JSDocSeeTag, tagName *IdentifierNode, nameExpression *TypeNode, comment *NodeList) *Node { @@ -7565,7 +7636,7 @@ func (f *NodeFactory) NewJSDocImplementsTag(tagName *IdentifierNode, className * data.TagName = tagName data.ClassName = className data.Comment = comment - return f.newNode(KindJSDocImplementsTag, data) + return f.newNode(KindJSDocImplementsTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocImplementsTag(node *JSDocImplementsTag, tagName *IdentifierNode, className *ExpressionWithTypeArgumentsNode, comment *NodeList) *Node { @@ -7605,7 +7676,7 @@ func (f *NodeFactory) NewJSDocAugmentsTag(tagName *IdentifierNode, className *Ex data.TagName = tagName data.ClassName = className data.Comment = comment - return f.newNode(KindJSDocAugmentsTag, data) + return f.newNode(KindJSDocAugmentsTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocAugmentsTag(node *JSDocAugmentsTag, tagName *IdentifierNode, className *ExpressionWithTypeArgumentsNode, comment *NodeList) *Node { @@ -7645,7 +7716,7 @@ func (f *NodeFactory) NewJSDocSatisfiesTag(tagName *IdentifierNode, typeExpressi data.TagName = tagName data.TypeExpression = typeExpression data.Comment = comment - return f.newNode(KindJSDocSatisfiesTag, data) + return f.newNode(KindJSDocSatisfiesTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocSatisfiesTag(node *JSDocSatisfiesTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { @@ -7685,7 +7756,7 @@ func (f *NodeFactory) NewJSDocThrowsTag(tagName *IdentifierNode, typeExpression data.TagName = tagName data.TypeExpression = typeExpression data.Comment = comment - return f.newNode(KindJSDocThrowsTag, data) + return f.newNode(KindJSDocThrowsTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocThrowsTag(node *JSDocThrowsTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { @@ -7725,7 +7796,7 @@ func (f *NodeFactory) NewJSDocThisTag(tagName *IdentifierNode, typeExpression *T data.TagName = tagName data.TypeExpression = typeExpression data.Comment = comment - return f.newNode(KindJSDocThisTag, data) + return f.newNode(KindJSDocThisTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocThisTag(node *JSDocThisTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { @@ -7769,7 +7840,7 @@ func (f *NodeFactory) NewJSDocImportTag(tagName *IdentifierNode, importClause *I data.ModuleSpecifier = moduleSpecifier data.Attributes = attributes data.Comment = comment - return f.newNode(KindJSDocImportTag, data) + return f.newNode(KindJSDocImportTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocImportTag(node *JSDocImportTag, tagName *IdentifierNode, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode, comment *NodeList) *Node { @@ -7815,7 +7886,7 @@ func (f *NodeFactory) NewJSDocCallbackTag(tagName *IdentifierNode, typeExpressio data.TypeExpression = typeExpression data.name = name data.Comment = comment - return f.newNode(KindJSDocCallbackTag, data) + return f.newNode(KindJSDocCallbackTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocCallbackTag(node *JSDocCallbackTag, tagName *IdentifierNode, typeExpression *TypeNode, name *JSDocFullName, comment *NodeList) *Node { @@ -7862,7 +7933,7 @@ func (f *NodeFactory) NewJSDocOverloadTag(tagName *IdentifierNode, typeExpressio data.TagName = tagName data.TypeExpression = typeExpression data.Comment = comment - return f.newNode(KindJSDocOverloadTag, data) + return f.newNode(KindJSDocOverloadTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocOverloadTag(node *JSDocOverloadTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { @@ -7904,7 +7975,7 @@ func (f *NodeFactory) NewJSDocTypedefTag(tagName *IdentifierNode, typeExpression data.TypeExpression = typeExpression data.name = name data.Comment = comment - return f.newNode(KindJSDocTypedefTag, data) + return f.newNode(KindJSDocTypedefTag, data.AsNode()) } func (f *NodeFactory) UpdateJSDocTypedefTag(node *JSDocTypedefTag, tagName *IdentifierNode, typeExpression *Node, name *JSDocFullName, comment *NodeList) *Node { @@ -7952,7 +8023,7 @@ func (f *NodeFactory) NewJSDocSignature(typeParameters *TypeParameterList, param data.TypeParameters = typeParameters data.Parameters = parameters data.Type = typeNode - return f.newNode(KindJSDocSignature, data) + return f.newNode(KindJSDocSignature, data.AsNode()) } func (f *NodeFactory) UpdateJSDocSignature(node *JSDocSignature, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node { @@ -7990,7 +8061,7 @@ type JSDocNameReference struct { func (f *NodeFactory) NewJSDocNameReference(name *EntityName) *Node { data := &JSDocNameReference{} data.name = name - return f.newNode(KindJSDocNameReference, data) + return f.newNode(KindJSDocNameReference, data.AsNode()) } func (f *NodeFactory) UpdateJSDocNameReference(node *JSDocNameReference, name *EntityName) *Node { @@ -8053,7 +8124,7 @@ func (f *NodeFactory) NewModuleDeclaration(modifiers *ModifierList, keyword Kind data.name = name data.Attributes = attributes data.Body = body - return f.newNode(KindModuleDeclaration, data) + return f.newNode(KindModuleDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateModuleDeclaration(node *ModuleDeclaration, modifiers *ModifierList, keyword Kind, name *ModuleName, attributes *TypeLiteralNodeNode, body *ModuleBody) *Node { @@ -8107,7 +8178,7 @@ func (f *NodeFactory) NewImportEqualsDeclaration(modifiers *ModifierList, isType data.IsTypeOnly = isTypeOnly data.name = name data.ModuleReference = moduleReference - return f.newNode(KindImportEqualsDeclaration, data) + return f.newNode(KindImportEqualsDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateImportEqualsDeclaration(node *ImportEqualsDeclaration, modifiers *ModifierList, isTypeOnly bool, name *IdentifierNode, moduleReference *ModuleReference) *Node { @@ -8159,7 +8230,7 @@ func (f *NodeFactory) NewExportDeclaration(modifiers *ModifierList, isTypeOnly b data.ExportClause = exportClause data.ModuleSpecifier = moduleSpecifier data.Attributes = attributes - return f.newNode(KindExportDeclaration, data) + return f.newNode(KindExportDeclaration, data.AsNode()) } func (f *NodeFactory) UpdateExportDeclaration(node *ExportDeclaration, modifiers *ModifierList, isTypeOnly bool, exportClause *NamedExportBindings, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node { @@ -8207,7 +8278,7 @@ func (f *NodeFactory) NewImportTypeNode(isTypeOf bool, argument *TypeNode, attri data.Attributes = attributes data.Qualifier = qualifier data.TypeArguments = typeArguments - return f.newNode(KindImportType, data) + return f.newNode(KindImportType, data.AsNode()) } func (f *NodeFactory) UpdateImportTypeNode(node *ImportTypeNode, isTypeOf bool, argument *TypeNode, attributes *ImportAttributesNode, qualifier *EntityName, typeArguments *TypeList) *Node { @@ -8255,7 +8326,7 @@ func (f *NodeFactory) NewImportClause(phaseModifier ImportPhaseModifierSyntaxKin data.PhaseModifier = phaseModifier data.name = name data.NamedBindings = namedBindings - return f.newNode(KindImportClause, data) + return f.newNode(KindImportClause, data.AsNode()) } func (f *NodeFactory) UpdateImportClause(node *ImportClause, phaseModifier ImportPhaseModifierSyntaxKind, name *IdentifierNode, namedBindings *NamedImportBindings) *Node { @@ -8304,7 +8375,7 @@ func (f *NodeFactory) NewImportSpecifier(isTypeOnly bool, propertyName *ModuleEx data.IsTypeOnly = isTypeOnly data.PropertyName = propertyName data.name = name - return f.newNode(KindImportSpecifier, data) + return f.newNode(KindImportSpecifier, data.AsNode()) } func (f *NodeFactory) UpdateImportSpecifier(node *ImportSpecifier, isTypeOnly bool, propertyName *ModuleExportName, name *IdentifierNode) *Node { @@ -8346,7 +8417,7 @@ func (f *NodeFactory) NewJSDocText(text []string) *Node { data := f.jsdocTextArena.New() data.text = text f.textCount++ - return f.newNode(KindJSDocText, data) + return f.newNode(KindJSDocText, data.AsNode()) } func (node *JSDocText) Clone(f NodeFactoryCoercible) *Node { @@ -8371,7 +8442,7 @@ func (f *NodeFactory) NewJSDocLink(name *EntityName, text []string) *Node { data.name = name data.text = text f.textCount++ - return f.newNode(KindJSDocLink, data) + return f.newNode(KindJSDocLink, data.AsNode()) } func (f *NodeFactory) UpdateJSDocLink(node *JSDocLink, name *EntityName, text []string) *Node { @@ -8415,7 +8486,7 @@ func (f *NodeFactory) NewJSDocLinkPlain(name *EntityName, text []string) *Node { data.name = name data.text = text f.textCount++ - return f.newNode(KindJSDocLinkPlain, data) + return f.newNode(KindJSDocLinkPlain, data.AsNode()) } func (f *NodeFactory) UpdateJSDocLinkPlain(node *JSDocLinkPlain, name *EntityName, text []string) *Node { @@ -8459,7 +8530,7 @@ func (f *NodeFactory) NewJSDocLinkCode(name *EntityName, text []string) *Node { data.name = name data.text = text f.textCount++ - return f.newNode(KindJSDocLinkCode, data) + return f.newNode(KindJSDocLinkCode, data.AsNode()) } func (f *NodeFactory) UpdateJSDocLinkCode(node *JSDocLinkCode, name *EntityName, text []string) *Node { @@ -8511,7 +8582,7 @@ func (f *NodeFactory) NewTypeParameterDeclaration(modifiers *ModifierList, name data.Constraint = constraint data.Expression = expression data.DefaultType = defaultType - return f.newNode(KindTypeParameter, data) + return f.newNode(KindTypeParameter, data.AsNode()) } func (f *NodeFactory) UpdateTypeParameterDeclaration(node *TypeParameterDeclaration, modifiers *ModifierList, name *IdentifierNode, constraint *TypeNode, expression *Expression, defaultType *TypeNode) *Node { @@ -8559,7 +8630,7 @@ func (f *NodeFactory) NewSyntheticReferenceExpression(expression *Expression, th data := &SyntheticReferenceExpression{} data.Expression = expression data.ThisArg = thisArg - return f.newNode(KindSyntheticReferenceExpression, data) + return f.newNode(KindSyntheticReferenceExpression, data.AsNode()) } func (f *NodeFactory) UpdateSyntheticReferenceExpression(node *SyntheticReferenceExpression, expression *Expression, thisArg *Expression) *Node { @@ -8605,7 +8676,7 @@ func (f *NodeFactory) NewJSDocTypeLiteral(jsdocPropertyTags []*Node, isArrayType data := &JSDocTypeLiteral{} data.JSDocPropertyTags = jsdocPropertyTags data.IsArrayType = isArrayType - return f.newNode(KindJSDocTypeLiteral, data) + return f.newNode(KindJSDocTypeLiteral, data.AsNode()) } func (f *NodeFactory) UpdateJSDocTypeLiteral(node *JSDocTypeLiteral, jsdocPropertyTags []*Node, isArrayType bool) *Node { @@ -8645,6 +8716,11 @@ type JSDocParameterOrPropertyTag struct { } func (f *NodeFactory) NewJSDocParameterOrPropertyTag(kind Kind, tagName *IdentifierNode, name *EntityName, isBracketed bool, typeExpression *TypeNode, isNameFirst bool, comment *NodeList) *Node { + switch kind { + case KindJSDocParameterTag, KindJSDocPropertyTag: + default: + panic("Invalid node kind for JSDocParameterOrPropertyTag") + } data := &JSDocParameterOrPropertyTag{} data.TagName = tagName data.name = name @@ -8652,7 +8728,7 @@ func (f *NodeFactory) NewJSDocParameterOrPropertyTag(kind Kind, tagName *Identif data.TypeExpression = typeExpression data.IsNameFirst = isNameFirst data.Comment = comment - return f.newNode(kind, data) + return f.newNode(kind, data.AsNode()) } func (f *NodeFactory) UpdateJSDocParameterOrPropertyTag(node *JSDocParameterOrPropertyTag, tagName *IdentifierNode, name *EntityName, isBracketed bool, typeExpression *TypeNode, isNameFirst bool, comment *NodeList) *Node { @@ -8693,1114 +8769,4765 @@ func IsJSDocPropertyTag(node *Node) bool { func (n *Node) ForEachChild(v Visitor) bool { switch n.Kind { case KindQualifiedName: - return n.data.(*QualifiedName).ForEachChild(v) + return (*QualifiedName)(unsafe.Pointer(n)).ForEachChild(v) case KindComputedPropertyName: - return n.data.(*ComputedPropertyName).ForEachChild(v) + return (*ComputedPropertyName)(unsafe.Pointer(n)).ForEachChild(v) case KindDecorator: - return n.data.(*Decorator).ForEachChild(v) + return (*Decorator)(unsafe.Pointer(n)).ForEachChild(v) case KindIfStatement: - return n.data.(*IfStatement).ForEachChild(v) + return (*IfStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindDoStatement: - return n.data.(*DoStatement).ForEachChild(v) + return (*DoStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindWhileStatement: - return n.data.(*WhileStatement).ForEachChild(v) + return (*WhileStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindForStatement: - return n.data.(*ForStatement).ForEachChild(v) + return (*ForStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindForInStatement, KindForOfStatement: - return n.data.(*ForInOrOfStatement).ForEachChild(v) + return (*ForInOrOfStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindBreakStatement: - return n.data.(*BreakStatement).ForEachChild(v) + return (*BreakStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindContinueStatement: - return n.data.(*ContinueStatement).ForEachChild(v) + return (*ContinueStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindReturnStatement: - return n.data.(*ReturnStatement).ForEachChild(v) + return (*ReturnStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindWithStatement: - return n.data.(*WithStatement).ForEachChild(v) + return (*WithStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindSwitchStatement: - return n.data.(*SwitchStatement).ForEachChild(v) + return (*SwitchStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindCaseBlock: - return n.data.(*CaseBlock).ForEachChild(v) + return (*CaseBlock)(unsafe.Pointer(n)).ForEachChild(v) case KindCaseClause, KindDefaultClause: - return n.data.(*CaseOrDefaultClause).ForEachChild(v) + return (*CaseOrDefaultClause)(unsafe.Pointer(n)).ForEachChild(v) case KindThrowStatement: - return n.data.(*ThrowStatement).ForEachChild(v) + return (*ThrowStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindTryStatement: - return n.data.(*TryStatement).ForEachChild(v) + return (*TryStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindCatchClause: - return n.data.(*CatchClause).ForEachChild(v) + return (*CatchClause)(unsafe.Pointer(n)).ForEachChild(v) case KindLabeledStatement: - return n.data.(*LabeledStatement).ForEachChild(v) + return (*LabeledStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindExpressionStatement: - return n.data.(*ExpressionStatement).ForEachChild(v) + return (*ExpressionStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindBlock: - return n.data.(*Block).ForEachChild(v) + return (*Block)(unsafe.Pointer(n)).ForEachChild(v) case KindVariableStatement: - return n.data.(*VariableStatement).ForEachChild(v) + return (*VariableStatement)(unsafe.Pointer(n)).ForEachChild(v) case KindVariableDeclaration: - return n.data.(*VariableDeclaration).ForEachChild(v) + return (*VariableDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindVariableDeclarationList: - return n.data.(*VariableDeclarationList).ForEachChild(v) + return (*VariableDeclarationList)(unsafe.Pointer(n)).ForEachChild(v) case KindObjectBindingPattern, KindArrayBindingPattern: - return n.data.(*BindingPattern).ForEachChild(v) + return (*BindingPattern)(unsafe.Pointer(n)).ForEachChild(v) case KindParameter: - return n.data.(*ParameterDeclaration).ForEachChild(v) + return (*ParameterDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindBindingElement: - return n.data.(*BindingElement).ForEachChild(v) + return (*BindingElement)(unsafe.Pointer(n)).ForEachChild(v) case KindMissingDeclaration: - return n.data.(*MissingDeclaration).ForEachChild(v) + return (*MissingDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindFunctionDeclaration: - return n.data.(*FunctionDeclaration).ForEachChild(v) + return (*FunctionDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindClassDeclaration: - return n.data.(*ClassDeclaration).ForEachChild(v) + return (*ClassDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindClassExpression: - return n.data.(*ClassExpression).ForEachChild(v) + return (*ClassExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindHeritageClause: - return n.data.(*HeritageClause).ForEachChild(v) + return (*HeritageClause)(unsafe.Pointer(n)).ForEachChild(v) case KindInterfaceDeclaration: - return n.data.(*InterfaceDeclaration).ForEachChild(v) + return (*InterfaceDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: - return n.data.(*TypeAliasDeclaration).ForEachChild(v) + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindEnumMember: - return n.data.(*EnumMember).ForEachChild(v) + return (*EnumMember)(unsafe.Pointer(n)).ForEachChild(v) case KindEnumDeclaration: - return n.data.(*EnumDeclaration).ForEachChild(v) + return (*EnumDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindModuleBlock: - return n.data.(*ModuleBlock).ForEachChild(v) + return (*ModuleBlock)(unsafe.Pointer(n)).ForEachChild(v) case KindImportDeclaration, KindJSImportDeclaration: - return n.data.(*ImportDeclaration).ForEachChild(v) + return (*ImportDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindExternalModuleReference: - return n.data.(*ExternalModuleReference).ForEachChild(v) + return (*ExternalModuleReference)(unsafe.Pointer(n)).ForEachChild(v) case KindNamespaceImport: - return n.data.(*NamespaceImport).ForEachChild(v) + return (*NamespaceImport)(unsafe.Pointer(n)).ForEachChild(v) case KindNamedImports: - return n.data.(*NamedImports).ForEachChild(v) + return (*NamedImports)(unsafe.Pointer(n)).ForEachChild(v) case KindExportAssignment: - return n.data.(*ExportAssignment).ForEachChild(v) + return (*ExportAssignment)(unsafe.Pointer(n)).ForEachChild(v) case KindNamespaceExportDeclaration: - return n.data.(*NamespaceExportDeclaration).ForEachChild(v) + return (*NamespaceExportDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindNamespaceExport: - return n.data.(*NamespaceExport).ForEachChild(v) + return (*NamespaceExport)(unsafe.Pointer(n)).ForEachChild(v) case KindNamedExports: - return n.data.(*NamedExports).ForEachChild(v) + return (*NamedExports)(unsafe.Pointer(n)).ForEachChild(v) case KindExportSpecifier: - return n.data.(*ExportSpecifier).ForEachChild(v) + return (*ExportSpecifier)(unsafe.Pointer(n)).ForEachChild(v) case KindCallSignature: - return n.data.(*CallSignatureDeclaration).ForEachChild(v) + return (*CallSignatureDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindConstructSignature: - return n.data.(*ConstructSignatureDeclaration).ForEachChild(v) + return (*ConstructSignatureDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindConstructor: - return n.data.(*ConstructorDeclaration).ForEachChild(v) + return (*ConstructorDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindGetAccessor: - return n.data.(*GetAccessorDeclaration).ForEachChild(v) + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindSetAccessor: - return n.data.(*SetAccessorDeclaration).ForEachChild(v) + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindIndexSignature: - return n.data.(*IndexSignatureDeclaration).ForEachChild(v) + return (*IndexSignatureDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindMethodSignature: - return n.data.(*MethodSignatureDeclaration).ForEachChild(v) + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindMethodDeclaration: - return n.data.(*MethodDeclaration).ForEachChild(v) + return (*MethodDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindPropertySignature: - return n.data.(*PropertySignatureDeclaration).ForEachChild(v) + return (*PropertySignatureDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindPropertyDeclaration: - return n.data.(*PropertyDeclaration).ForEachChild(v) + return (*PropertyDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindClassStaticBlockDeclaration: - return n.data.(*ClassStaticBlockDeclaration).ForEachChild(v) + return (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindBinaryExpression: - return n.data.(*BinaryExpression).ForEachChild(v) + return (*BinaryExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindPrefixUnaryExpression: - return n.data.(*PrefixUnaryExpression).ForEachChild(v) + return (*PrefixUnaryExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindPostfixUnaryExpression: - return n.data.(*PostfixUnaryExpression).ForEachChild(v) + return (*PostfixUnaryExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindYieldExpression: - return n.data.(*YieldExpression).ForEachChild(v) + return (*YieldExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindArrowFunction: - return n.data.(*ArrowFunction).ForEachChild(v) + return (*ArrowFunction)(unsafe.Pointer(n)).ForEachChild(v) case KindFunctionExpression: - return n.data.(*FunctionExpression).ForEachChild(v) + return (*FunctionExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindAsExpression: - return n.data.(*AsExpression).ForEachChild(v) + return (*AsExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindSatisfiesExpression: - return n.data.(*SatisfiesExpression).ForEachChild(v) + return (*SatisfiesExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindConditionalExpression: - return n.data.(*ConditionalExpression).ForEachChild(v) + return (*ConditionalExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindPropertyAccessExpression: - return n.data.(*PropertyAccessExpression).ForEachChild(v) + return (*PropertyAccessExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindElementAccessExpression: - return n.data.(*ElementAccessExpression).ForEachChild(v) + return (*ElementAccessExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindCallExpression: - return n.data.(*CallExpression).ForEachChild(v) + return (*CallExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindNewExpression: - return n.data.(*NewExpression).ForEachChild(v) + return (*NewExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindMetaProperty: - return n.data.(*MetaProperty).ForEachChild(v) + return (*MetaProperty)(unsafe.Pointer(n)).ForEachChild(v) case KindNonNullExpression: - return n.data.(*NonNullExpression).ForEachChild(v) + return (*NonNullExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindSpreadElement: - return n.data.(*SpreadElement).ForEachChild(v) + return (*SpreadElement)(unsafe.Pointer(n)).ForEachChild(v) case KindTemplateExpression: - return n.data.(*TemplateExpression).ForEachChild(v) + return (*TemplateExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindTemplateSpan: - return n.data.(*TemplateSpan).ForEachChild(v) + return (*TemplateSpan)(unsafe.Pointer(n)).ForEachChild(v) case KindTaggedTemplateExpression: - return n.data.(*TaggedTemplateExpression).ForEachChild(v) + return (*TaggedTemplateExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindParenthesizedExpression: - return n.data.(*ParenthesizedExpression).ForEachChild(v) + return (*ParenthesizedExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindArrayLiteralExpression: - return n.data.(*ArrayLiteralExpression).ForEachChild(v) + return (*ArrayLiteralExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindObjectLiteralExpression: - return n.data.(*ObjectLiteralExpression).ForEachChild(v) + return (*ObjectLiteralExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindSpreadAssignment: - return n.data.(*SpreadAssignment).ForEachChild(v) + return (*SpreadAssignment)(unsafe.Pointer(n)).ForEachChild(v) case KindPropertyAssignment: - return n.data.(*PropertyAssignment).ForEachChild(v) + return (*PropertyAssignment)(unsafe.Pointer(n)).ForEachChild(v) case KindShorthandPropertyAssignment: - return n.data.(*ShorthandPropertyAssignment).ForEachChild(v) + return (*ShorthandPropertyAssignment)(unsafe.Pointer(n)).ForEachChild(v) case KindDeleteExpression: - return n.data.(*DeleteExpression).ForEachChild(v) + return (*DeleteExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindTypeOfExpression: - return n.data.(*TypeOfExpression).ForEachChild(v) + return (*TypeOfExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindVoidExpression: - return n.data.(*VoidExpression).ForEachChild(v) + return (*VoidExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindAwaitExpression: - return n.data.(*AwaitExpression).ForEachChild(v) + return (*AwaitExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindTypeAssertionExpression: - return n.data.(*TypeAssertion).ForEachChild(v) + return (*TypeAssertion)(unsafe.Pointer(n)).ForEachChild(v) case KindUnionType: - return n.data.(*UnionTypeNode).ForEachChild(v) + return (*UnionTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindIntersectionType: - return n.data.(*IntersectionTypeNode).ForEachChild(v) + return (*IntersectionTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindConditionalType: - return n.data.(*ConditionalTypeNode).ForEachChild(v) + return (*ConditionalTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindTypeOperator: - return n.data.(*TypeOperatorNode).ForEachChild(v) + return (*TypeOperatorNode)(unsafe.Pointer(n)).ForEachChild(v) case KindInferType: - return n.data.(*InferTypeNode).ForEachChild(v) + return (*InferTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindArrayType: - return n.data.(*ArrayTypeNode).ForEachChild(v) + return (*ArrayTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindIndexedAccessType: - return n.data.(*IndexedAccessTypeNode).ForEachChild(v) + return (*IndexedAccessTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindTypeReference: - return n.data.(*TypeReferenceNode).ForEachChild(v) + return (*TypeReferenceNode)(unsafe.Pointer(n)).ForEachChild(v) case KindExpressionWithTypeArguments: - return n.data.(*ExpressionWithTypeArguments).ForEachChild(v) + return (*ExpressionWithTypeArguments)(unsafe.Pointer(n)).ForEachChild(v) case KindLiteralType: - return n.data.(*LiteralTypeNode).ForEachChild(v) + return (*LiteralTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindTypePredicate: - return n.data.(*TypePredicateNode).ForEachChild(v) + return (*TypePredicateNode)(unsafe.Pointer(n)).ForEachChild(v) case KindImportAttribute: - return n.data.(*ImportAttribute).ForEachChild(v) + return (*ImportAttribute)(unsafe.Pointer(n)).ForEachChild(v) case KindImportAttributes: - return n.data.(*ImportAttributes).ForEachChild(v) + return (*ImportAttributes)(unsafe.Pointer(n)).ForEachChild(v) case KindTypeQuery: - return n.data.(*TypeQueryNode).ForEachChild(v) + return (*TypeQueryNode)(unsafe.Pointer(n)).ForEachChild(v) case KindMappedType: - return n.data.(*MappedTypeNode).ForEachChild(v) + return (*MappedTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindTypeLiteral: - return n.data.(*TypeLiteralNode).ForEachChild(v) + return (*TypeLiteralNode)(unsafe.Pointer(n)).ForEachChild(v) case KindTupleType: - return n.data.(*TupleTypeNode).ForEachChild(v) + return (*TupleTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindNamedTupleMember: - return n.data.(*NamedTupleMember).ForEachChild(v) + return (*NamedTupleMember)(unsafe.Pointer(n)).ForEachChild(v) case KindOptionalType: - return n.data.(*OptionalTypeNode).ForEachChild(v) + return (*OptionalTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindRestType: - return n.data.(*RestTypeNode).ForEachChild(v) + return (*RestTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindParenthesizedType: - return n.data.(*ParenthesizedTypeNode).ForEachChild(v) + return (*ParenthesizedTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindFunctionType: - return n.data.(*FunctionTypeNode).ForEachChild(v) + return (*FunctionTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindConstructorType: - return n.data.(*ConstructorTypeNode).ForEachChild(v) + return (*ConstructorTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindTemplateLiteralType: - return n.data.(*TemplateLiteralTypeNode).ForEachChild(v) + return (*TemplateLiteralTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindTemplateLiteralTypeSpan: - return n.data.(*TemplateLiteralTypeSpan).ForEachChild(v) + return (*TemplateLiteralTypeSpan)(unsafe.Pointer(n)).ForEachChild(v) case KindSyntheticExpression: - return n.data.(*SyntheticExpression).ForEachChild(v) + return (*SyntheticExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindPartiallyEmittedExpression: - return n.data.(*PartiallyEmittedExpression).ForEachChild(v) + return (*PartiallyEmittedExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindJsxElement: - return n.data.(*JsxElement).ForEachChild(v) + return (*JsxElement)(unsafe.Pointer(n)).ForEachChild(v) case KindJsxAttributes: - return n.data.(*JsxAttributes).ForEachChild(v) + return (*JsxAttributes)(unsafe.Pointer(n)).ForEachChild(v) case KindJsxNamespacedName: - return n.data.(*JsxNamespacedName).ForEachChild(v) + return (*JsxNamespacedName)(unsafe.Pointer(n)).ForEachChild(v) case KindJsxOpeningElement: - return n.data.(*JsxOpeningElement).ForEachChild(v) + return (*JsxOpeningElement)(unsafe.Pointer(n)).ForEachChild(v) case KindJsxSelfClosingElement: - return n.data.(*JsxSelfClosingElement).ForEachChild(v) + return (*JsxSelfClosingElement)(unsafe.Pointer(n)).ForEachChild(v) case KindJsxFragment: - return n.data.(*JsxFragment).ForEachChild(v) + return (*JsxFragment)(unsafe.Pointer(n)).ForEachChild(v) case KindJsxAttribute: - return n.data.(*JsxAttribute).ForEachChild(v) + return (*JsxAttribute)(unsafe.Pointer(n)).ForEachChild(v) case KindJsxSpreadAttribute: - return n.data.(*JsxSpreadAttribute).ForEachChild(v) + return (*JsxSpreadAttribute)(unsafe.Pointer(n)).ForEachChild(v) case KindJsxClosingElement: - return n.data.(*JsxClosingElement).ForEachChild(v) + return (*JsxClosingElement)(unsafe.Pointer(n)).ForEachChild(v) case KindJsxExpression: - return n.data.(*JsxExpression).ForEachChild(v) + return (*JsxExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindSyntaxList: - return n.data.(*SyntaxList).ForEachChild(v) + return (*SyntaxList)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDoc: - return n.data.(*JSDoc).ForEachChild(v) + return (*JSDoc)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocTypeExpression: - return n.data.(*JSDocTypeExpression).ForEachChild(v) + return (*JSDocTypeExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocNonNullableType: - return n.data.(*JSDocNonNullableType).ForEachChild(v) + return (*JSDocNonNullableType)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocNullableType: - return n.data.(*JSDocNullableType).ForEachChild(v) + return (*JSDocNullableType)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocVariadicType: - return n.data.(*JSDocVariadicType).ForEachChild(v) + return (*JSDocVariadicType)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocOptionalType: - return n.data.(*JSDocOptionalType).ForEachChild(v) + return (*JSDocOptionalType)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocTypeTag: - return n.data.(*JSDocTypeTag).ForEachChild(v) + return (*JSDocTypeTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocUnknownTag: - return n.data.(*JSDocUnknownTag).ForEachChild(v) + return (*JSDocUnknownTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocTemplateTag: - return n.data.(*JSDocTemplateTag).ForEachChild(v) + return (*JSDocTemplateTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocReturnTag: - return n.data.(*JSDocReturnTag).ForEachChild(v) + return (*JSDocReturnTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocPublicTag: - return n.data.(*JSDocPublicTag).ForEachChild(v) + return (*JSDocPublicTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocPrivateTag: - return n.data.(*JSDocPrivateTag).ForEachChild(v) + return (*JSDocPrivateTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocProtectedTag: - return n.data.(*JSDocProtectedTag).ForEachChild(v) + return (*JSDocProtectedTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocReadonlyTag: - return n.data.(*JSDocReadonlyTag).ForEachChild(v) + return (*JSDocReadonlyTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocOverrideTag: - return n.data.(*JSDocOverrideTag).ForEachChild(v) + return (*JSDocOverrideTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocDeprecatedTag: - return n.data.(*JSDocDeprecatedTag).ForEachChild(v) + return (*JSDocDeprecatedTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocSeeTag: - return n.data.(*JSDocSeeTag).ForEachChild(v) + return (*JSDocSeeTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocImplementsTag: - return n.data.(*JSDocImplementsTag).ForEachChild(v) + return (*JSDocImplementsTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocAugmentsTag: - return n.data.(*JSDocAugmentsTag).ForEachChild(v) + return (*JSDocAugmentsTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocSatisfiesTag: - return n.data.(*JSDocSatisfiesTag).ForEachChild(v) + return (*JSDocSatisfiesTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocThrowsTag: - return n.data.(*JSDocThrowsTag).ForEachChild(v) + return (*JSDocThrowsTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocThisTag: - return n.data.(*JSDocThisTag).ForEachChild(v) + return (*JSDocThisTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocImportTag: - return n.data.(*JSDocImportTag).ForEachChild(v) + return (*JSDocImportTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocCallbackTag: - return n.data.(*JSDocCallbackTag).ForEachChild(v) + return (*JSDocCallbackTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocOverloadTag: - return n.data.(*JSDocOverloadTag).ForEachChild(v) + return (*JSDocOverloadTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocTypedefTag: - return n.data.(*JSDocTypedefTag).ForEachChild(v) + return (*JSDocTypedefTag)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocSignature: - return n.data.(*JSDocSignature).ForEachChild(v) + return (*JSDocSignature)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocNameReference: - return n.data.(*JSDocNameReference).ForEachChild(v) + return (*JSDocNameReference)(unsafe.Pointer(n)).ForEachChild(v) case KindSourceFile: - return n.data.(*SourceFile).ForEachChild(v) + return (*SourceFile)(unsafe.Pointer(n)).ForEachChild(v) case KindModuleDeclaration: - return n.data.(*ModuleDeclaration).ForEachChild(v) + return (*ModuleDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindImportEqualsDeclaration: - return n.data.(*ImportEqualsDeclaration).ForEachChild(v) + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindExportDeclaration: - return n.data.(*ExportDeclaration).ForEachChild(v) + return (*ExportDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindImportType: - return n.data.(*ImportTypeNode).ForEachChild(v) + return (*ImportTypeNode)(unsafe.Pointer(n)).ForEachChild(v) case KindImportClause: - return n.data.(*ImportClause).ForEachChild(v) + return (*ImportClause)(unsafe.Pointer(n)).ForEachChild(v) case KindImportSpecifier: - return n.data.(*ImportSpecifier).ForEachChild(v) + return (*ImportSpecifier)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocLink: - return n.data.(*JSDocLink).ForEachChild(v) + return (*JSDocLink)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocLinkPlain: - return n.data.(*JSDocLinkPlain).ForEachChild(v) + return (*JSDocLinkPlain)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocLinkCode: - return n.data.(*JSDocLinkCode).ForEachChild(v) + return (*JSDocLinkCode)(unsafe.Pointer(n)).ForEachChild(v) case KindTypeParameter: - return n.data.(*TypeParameterDeclaration).ForEachChild(v) + return (*TypeParameterDeclaration)(unsafe.Pointer(n)).ForEachChild(v) case KindSyntheticReferenceExpression: - return n.data.(*SyntheticReferenceExpression).ForEachChild(v) + return (*SyntheticReferenceExpression)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocTypeLiteral: - return n.data.(*JSDocTypeLiteral).ForEachChild(v) + return (*JSDocTypeLiteral)(unsafe.Pointer(n)).ForEachChild(v) case KindJSDocParameterTag, KindJSDocPropertyTag: - return n.data.(*JSDocParameterOrPropertyTag).ForEachChild(v) + return (*JSDocParameterOrPropertyTag)(unsafe.Pointer(n)).ForEachChild(v) default: return false } } // ────────────────────────────────────────────────────────────────────── -// As*() cast methods +// VisitEachChild dispatch // ────────────────────────────────────────────────────────────────────── -func (n *Node) AsToken() *Token { - return n.data.(*Token) -} - -func (n *Node) AsIdentifier() *Identifier { - return n.data.(*Identifier) -} - -func (n *Node) AsPrivateIdentifier() *PrivateIdentifier { - return n.data.(*PrivateIdentifier) -} - -func (n *Node) AsQualifiedName() *QualifiedName { - return n.data.(*QualifiedName) -} - -func (n *Node) AsComputedPropertyName() *ComputedPropertyName { - return n.data.(*ComputedPropertyName) -} - -func (n *Node) AsDecorator() *Decorator { - return n.data.(*Decorator) -} - -func (n *Node) AsEmptyStatement() *EmptyStatement { - return n.data.(*EmptyStatement) -} - -func (n *Node) AsIfStatement() *IfStatement { - return n.data.(*IfStatement) -} - -func (n *Node) AsDoStatement() *DoStatement { - return n.data.(*DoStatement) -} - -func (n *Node) AsWhileStatement() *WhileStatement { - return n.data.(*WhileStatement) -} - -func (n *Node) AsForStatement() *ForStatement { - return n.data.(*ForStatement) -} - -func (n *Node) AsForInOrOfStatement() *ForInOrOfStatement { - return n.data.(*ForInOrOfStatement) -} - -func (n *Node) AsBreakStatement() *BreakStatement { - return n.data.(*BreakStatement) -} - -func (n *Node) AsContinueStatement() *ContinueStatement { - return n.data.(*ContinueStatement) -} - -func (n *Node) AsReturnStatement() *ReturnStatement { - return n.data.(*ReturnStatement) -} - -func (n *Node) AsWithStatement() *WithStatement { - return n.data.(*WithStatement) -} - -func (n *Node) AsSwitchStatement() *SwitchStatement { - return n.data.(*SwitchStatement) -} - -func (n *Node) AsCaseBlock() *CaseBlock { - return n.data.(*CaseBlock) -} - -func (n *Node) AsCaseOrDefaultClause() *CaseOrDefaultClause { - return n.data.(*CaseOrDefaultClause) +func (n *Node) VisitEachChild(v *NodeVisitor) *Node { + switch n.Kind { + case KindQualifiedName: + return (*QualifiedName)(unsafe.Pointer(n)).VisitEachChild(v) + case KindComputedPropertyName: + return (*ComputedPropertyName)(unsafe.Pointer(n)).VisitEachChild(v) + case KindDecorator: + return (*Decorator)(unsafe.Pointer(n)).VisitEachChild(v) + case KindIfStatement: + return (*IfStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindDoStatement: + return (*DoStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindWhileStatement: + return (*WhileStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindForStatement: + return (*ForStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindForInStatement, KindForOfStatement: + return (*ForInOrOfStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindBreakStatement: + return (*BreakStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindContinueStatement: + return (*ContinueStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindReturnStatement: + return (*ReturnStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindWithStatement: + return (*WithStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindSwitchStatement: + return (*SwitchStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindCaseBlock: + return (*CaseBlock)(unsafe.Pointer(n)).VisitEachChild(v) + case KindCaseClause, KindDefaultClause: + return (*CaseOrDefaultClause)(unsafe.Pointer(n)).VisitEachChild(v) + case KindThrowStatement: + return (*ThrowStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTryStatement: + return (*TryStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindCatchClause: + return (*CatchClause)(unsafe.Pointer(n)).VisitEachChild(v) + case KindLabeledStatement: + return (*LabeledStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindExpressionStatement: + return (*ExpressionStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindBlock: + return (*Block)(unsafe.Pointer(n)).VisitEachChild(v) + case KindVariableStatement: + return (*VariableStatement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindVariableDeclaration: + return (*VariableDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindVariableDeclarationList: + return (*VariableDeclarationList)(unsafe.Pointer(n)).VisitEachChild(v) + case KindObjectBindingPattern, KindArrayBindingPattern: + return (*BindingPattern)(unsafe.Pointer(n)).VisitEachChild(v) + case KindParameter: + return (*ParameterDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindBindingElement: + return (*BindingElement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindMissingDeclaration: + return (*MissingDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindFunctionDeclaration: + return (*FunctionDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindClassDeclaration: + return (*ClassDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindClassExpression: + return (*ClassExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindHeritageClause: + return (*HeritageClause)(unsafe.Pointer(n)).VisitEachChild(v) + case KindInterfaceDeclaration: + return (*InterfaceDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindEnumMember: + return (*EnumMember)(unsafe.Pointer(n)).VisitEachChild(v) + case KindEnumDeclaration: + return (*EnumDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindModuleBlock: + return (*ModuleBlock)(unsafe.Pointer(n)).VisitEachChild(v) + case KindImportDeclaration, KindJSImportDeclaration: + return (*ImportDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindExternalModuleReference: + return (*ExternalModuleReference)(unsafe.Pointer(n)).VisitEachChild(v) + case KindNamespaceImport: + return (*NamespaceImport)(unsafe.Pointer(n)).VisitEachChild(v) + case KindNamedImports: + return (*NamedImports)(unsafe.Pointer(n)).VisitEachChild(v) + case KindExportAssignment: + return (*ExportAssignment)(unsafe.Pointer(n)).VisitEachChild(v) + case KindNamespaceExportDeclaration: + return (*NamespaceExportDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindNamespaceExport: + return (*NamespaceExport)(unsafe.Pointer(n)).VisitEachChild(v) + case KindNamedExports: + return (*NamedExports)(unsafe.Pointer(n)).VisitEachChild(v) + case KindExportSpecifier: + return (*ExportSpecifier)(unsafe.Pointer(n)).VisitEachChild(v) + case KindCallSignature: + return (*CallSignatureDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindConstructSignature: + return (*ConstructSignatureDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindConstructor: + return (*ConstructorDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindGetAccessor: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindSetAccessor: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindIndexSignature: + return (*IndexSignatureDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindMethodSignature: + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindMethodDeclaration: + return (*MethodDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindPropertySignature: + return (*PropertySignatureDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindPropertyDeclaration: + return (*PropertyDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindClassStaticBlockDeclaration: + return (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindBinaryExpression: + return (*BinaryExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindPrefixUnaryExpression: + return (*PrefixUnaryExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindPostfixUnaryExpression: + return (*PostfixUnaryExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindYieldExpression: + return (*YieldExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindArrowFunction: + return (*ArrowFunction)(unsafe.Pointer(n)).VisitEachChild(v) + case KindFunctionExpression: + return (*FunctionExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindAsExpression: + return (*AsExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindSatisfiesExpression: + return (*SatisfiesExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindConditionalExpression: + return (*ConditionalExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindPropertyAccessExpression: + return (*PropertyAccessExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindElementAccessExpression: + return (*ElementAccessExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindCallExpression: + return (*CallExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindNewExpression: + return (*NewExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindMetaProperty: + return (*MetaProperty)(unsafe.Pointer(n)).VisitEachChild(v) + case KindNonNullExpression: + return (*NonNullExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindSpreadElement: + return (*SpreadElement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTemplateExpression: + return (*TemplateExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTemplateSpan: + return (*TemplateSpan)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTaggedTemplateExpression: + return (*TaggedTemplateExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindParenthesizedExpression: + return (*ParenthesizedExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindArrayLiteralExpression: + return (*ArrayLiteralExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindObjectLiteralExpression: + return (*ObjectLiteralExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindSpreadAssignment: + return (*SpreadAssignment)(unsafe.Pointer(n)).VisitEachChild(v) + case KindPropertyAssignment: + return (*PropertyAssignment)(unsafe.Pointer(n)).VisitEachChild(v) + case KindShorthandPropertyAssignment: + return (*ShorthandPropertyAssignment)(unsafe.Pointer(n)).VisitEachChild(v) + case KindDeleteExpression: + return (*DeleteExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTypeOfExpression: + return (*TypeOfExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindVoidExpression: + return (*VoidExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindAwaitExpression: + return (*AwaitExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTypeAssertionExpression: + return (*TypeAssertion)(unsafe.Pointer(n)).VisitEachChild(v) + case KindUnionType: + return (*UnionTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindIntersectionType: + return (*IntersectionTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindConditionalType: + return (*ConditionalTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTypeOperator: + return (*TypeOperatorNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindInferType: + return (*InferTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindArrayType: + return (*ArrayTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindIndexedAccessType: + return (*IndexedAccessTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTypeReference: + return (*TypeReferenceNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindExpressionWithTypeArguments: + return (*ExpressionWithTypeArguments)(unsafe.Pointer(n)).VisitEachChild(v) + case KindLiteralType: + return (*LiteralTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTypePredicate: + return (*TypePredicateNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindImportAttribute: + return (*ImportAttribute)(unsafe.Pointer(n)).VisitEachChild(v) + case KindImportAttributes: + return (*ImportAttributes)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTypeQuery: + return (*TypeQueryNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindMappedType: + return (*MappedTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTypeLiteral: + return (*TypeLiteralNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTupleType: + return (*TupleTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindNamedTupleMember: + return (*NamedTupleMember)(unsafe.Pointer(n)).VisitEachChild(v) + case KindOptionalType: + return (*OptionalTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindRestType: + return (*RestTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindParenthesizedType: + return (*ParenthesizedTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindFunctionType: + return (*FunctionTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindConstructorType: + return (*ConstructorTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTemplateLiteralType: + return (*TemplateLiteralTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTemplateLiteralTypeSpan: + return (*TemplateLiteralTypeSpan)(unsafe.Pointer(n)).VisitEachChild(v) + case KindSyntheticExpression: + return (*SyntheticExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindPartiallyEmittedExpression: + return (*PartiallyEmittedExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJsxElement: + return (*JsxElement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJsxAttributes: + return (*JsxAttributes)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJsxNamespacedName: + return (*JsxNamespacedName)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJsxOpeningElement: + return (*JsxOpeningElement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJsxSelfClosingElement: + return (*JsxSelfClosingElement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJsxFragment: + return (*JsxFragment)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJsxAttribute: + return (*JsxAttribute)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJsxSpreadAttribute: + return (*JsxSpreadAttribute)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJsxClosingElement: + return (*JsxClosingElement)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJsxExpression: + return (*JsxExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindSyntaxList: + return (*SyntaxList)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDoc: + return (*JSDoc)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocTypeExpression: + return (*JSDocTypeExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocNonNullableType: + return (*JSDocNonNullableType)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocNullableType: + return (*JSDocNullableType)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocVariadicType: + return (*JSDocVariadicType)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocOptionalType: + return (*JSDocOptionalType)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocTypeTag: + return (*JSDocTypeTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocUnknownTag: + return (*JSDocUnknownTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocTemplateTag: + return (*JSDocTemplateTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocReturnTag: + return (*JSDocReturnTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocPublicTag: + return (*JSDocPublicTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocPrivateTag: + return (*JSDocPrivateTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocProtectedTag: + return (*JSDocProtectedTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocReadonlyTag: + return (*JSDocReadonlyTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocOverrideTag: + return (*JSDocOverrideTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocDeprecatedTag: + return (*JSDocDeprecatedTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocSeeTag: + return (*JSDocSeeTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocImplementsTag: + return (*JSDocImplementsTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocAugmentsTag: + return (*JSDocAugmentsTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocSatisfiesTag: + return (*JSDocSatisfiesTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocThrowsTag: + return (*JSDocThrowsTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocThisTag: + return (*JSDocThisTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocImportTag: + return (*JSDocImportTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocCallbackTag: + return (*JSDocCallbackTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocOverloadTag: + return (*JSDocOverloadTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocTypedefTag: + return (*JSDocTypedefTag)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocSignature: + return (*JSDocSignature)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocNameReference: + return (*JSDocNameReference)(unsafe.Pointer(n)).VisitEachChild(v) + case KindSourceFile: + return (*SourceFile)(unsafe.Pointer(n)).VisitEachChild(v) + case KindModuleDeclaration: + return (*ModuleDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindImportEqualsDeclaration: + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindExportDeclaration: + return (*ExportDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindImportType: + return (*ImportTypeNode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindImportClause: + return (*ImportClause)(unsafe.Pointer(n)).VisitEachChild(v) + case KindImportSpecifier: + return (*ImportSpecifier)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocLink: + return (*JSDocLink)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocLinkPlain: + return (*JSDocLinkPlain)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocLinkCode: + return (*JSDocLinkCode)(unsafe.Pointer(n)).VisitEachChild(v) + case KindTypeParameter: + return (*TypeParameterDeclaration)(unsafe.Pointer(n)).VisitEachChild(v) + case KindSyntheticReferenceExpression: + return (*SyntheticReferenceExpression)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocTypeLiteral: + return (*JSDocTypeLiteral)(unsafe.Pointer(n)).VisitEachChild(v) + case KindJSDocParameterTag, KindJSDocPropertyTag: + return (*JSDocParameterOrPropertyTag)(unsafe.Pointer(n)).VisitEachChild(v) + default: + return n + } } -func (n *Node) AsThrowStatement() *ThrowStatement { - return n.data.(*ThrowStatement) -} +// ────────────────────────────────────────────────────────────────────── +// Clone dispatch +// ────────────────────────────────────────────────────────────────────── + +func (n *Node) Clone(f NodeFactoryCoercible) *Node { + switch n.Kind { + case kindFlowSwitchClauseData, kindFlowReduceLabelData: + return nil + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + return (*Token)(unsafe.Pointer(n)).Clone(f) + case KindNumericLiteral: + return (*NumericLiteral)(unsafe.Pointer(n)).Clone(f) + case KindBigIntLiteral: + return (*BigIntLiteral)(unsafe.Pointer(n)).Clone(f) + case KindStringLiteral: + return (*StringLiteral)(unsafe.Pointer(n)).Clone(f) + case KindJsxText: + return (*JsxText)(unsafe.Pointer(n)).Clone(f) + case KindRegularExpressionLiteral: + return (*RegularExpressionLiteral)(unsafe.Pointer(n)).Clone(f) + case KindNoSubstitutionTemplateLiteral: + return (*NoSubstitutionTemplateLiteral)(unsafe.Pointer(n)).Clone(f) + case KindTemplateHead: + return (*TemplateHead)(unsafe.Pointer(n)).Clone(f) + case KindTemplateMiddle: + return (*TemplateMiddle)(unsafe.Pointer(n)).Clone(f) + case KindTemplateTail: + return (*TemplateTail)(unsafe.Pointer(n)).Clone(f) + case KindIdentifier: + return (*Identifier)(unsafe.Pointer(n)).Clone(f) + case KindPrivateIdentifier: + return (*PrivateIdentifier)(unsafe.Pointer(n)).Clone(f) + case KindFalseKeyword, KindImportKeyword, KindNullKeyword, KindSuperKeyword, KindThisKeyword, KindTrueKeyword: + return (*KeywordExpression)(unsafe.Pointer(n)).Clone(f) + case KindVoidKeyword, KindAnyKeyword, KindBooleanKeyword, KindIntrinsicKeyword, KindNeverKeyword, KindNumberKeyword, KindObjectKeyword, KindStringKeyword, KindSymbolKeyword, KindUndefinedKeyword, KindUnknownKeyword, KindBigIntKeyword: + return (*KeywordTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindQualifiedName: + return (*QualifiedName)(unsafe.Pointer(n)).Clone(f) + case KindComputedPropertyName: + return (*ComputedPropertyName)(unsafe.Pointer(n)).Clone(f) + case KindDecorator: + return (*Decorator)(unsafe.Pointer(n)).Clone(f) + case KindEmptyStatement: + return (*EmptyStatement)(unsafe.Pointer(n)).Clone(f) + case KindIfStatement: + return (*IfStatement)(unsafe.Pointer(n)).Clone(f) + case KindDoStatement: + return (*DoStatement)(unsafe.Pointer(n)).Clone(f) + case KindWhileStatement: + return (*WhileStatement)(unsafe.Pointer(n)).Clone(f) + case KindForStatement: + return (*ForStatement)(unsafe.Pointer(n)).Clone(f) + case KindForInStatement, KindForOfStatement: + return (*ForInOrOfStatement)(unsafe.Pointer(n)).Clone(f) + case KindBreakStatement: + return (*BreakStatement)(unsafe.Pointer(n)).Clone(f) + case KindContinueStatement: + return (*ContinueStatement)(unsafe.Pointer(n)).Clone(f) + case KindReturnStatement: + return (*ReturnStatement)(unsafe.Pointer(n)).Clone(f) + case KindWithStatement: + return (*WithStatement)(unsafe.Pointer(n)).Clone(f) + case KindSwitchStatement: + return (*SwitchStatement)(unsafe.Pointer(n)).Clone(f) + case KindCaseBlock: + return (*CaseBlock)(unsafe.Pointer(n)).Clone(f) + case KindCaseClause, KindDefaultClause: + return (*CaseOrDefaultClause)(unsafe.Pointer(n)).Clone(f) + case KindThrowStatement: + return (*ThrowStatement)(unsafe.Pointer(n)).Clone(f) + case KindTryStatement: + return (*TryStatement)(unsafe.Pointer(n)).Clone(f) + case KindCatchClause: + return (*CatchClause)(unsafe.Pointer(n)).Clone(f) + case KindDebuggerStatement: + return (*DebuggerStatement)(unsafe.Pointer(n)).Clone(f) + case KindLabeledStatement: + return (*LabeledStatement)(unsafe.Pointer(n)).Clone(f) + case KindExpressionStatement: + return (*ExpressionStatement)(unsafe.Pointer(n)).Clone(f) + case KindBlock: + return (*Block)(unsafe.Pointer(n)).Clone(f) + case KindVariableStatement: + return (*VariableStatement)(unsafe.Pointer(n)).Clone(f) + case KindVariableDeclaration: + return (*VariableDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindVariableDeclarationList: + return (*VariableDeclarationList)(unsafe.Pointer(n)).Clone(f) + case KindObjectBindingPattern, KindArrayBindingPattern: + return (*BindingPattern)(unsafe.Pointer(n)).Clone(f) + case KindParameter: + return (*ParameterDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindBindingElement: + return (*BindingElement)(unsafe.Pointer(n)).Clone(f) + case KindMissingDeclaration: + return (*MissingDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindFunctionDeclaration: + return (*FunctionDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindClassDeclaration: + return (*ClassDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindClassExpression: + return (*ClassExpression)(unsafe.Pointer(n)).Clone(f) + case KindHeritageClause: + return (*HeritageClause)(unsafe.Pointer(n)).Clone(f) + case KindInterfaceDeclaration: + return (*InterfaceDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindEnumMember: + return (*EnumMember)(unsafe.Pointer(n)).Clone(f) + case KindEnumDeclaration: + return (*EnumDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindModuleBlock: + return (*ModuleBlock)(unsafe.Pointer(n)).Clone(f) + case KindNotEmittedStatement: + return (*NotEmittedStatement)(unsafe.Pointer(n)).Clone(f) + case KindNotEmittedTypeElement: + return (*NotEmittedTypeElement)(unsafe.Pointer(n)).Clone(f) + case KindImportDeclaration, KindJSImportDeclaration: + return (*ImportDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindExternalModuleReference: + return (*ExternalModuleReference)(unsafe.Pointer(n)).Clone(f) + case KindNamespaceImport: + return (*NamespaceImport)(unsafe.Pointer(n)).Clone(f) + case KindNamedImports: + return (*NamedImports)(unsafe.Pointer(n)).Clone(f) + case KindExportAssignment: + return (*ExportAssignment)(unsafe.Pointer(n)).Clone(f) + case KindNamespaceExportDeclaration: + return (*NamespaceExportDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindNamespaceExport: + return (*NamespaceExport)(unsafe.Pointer(n)).Clone(f) + case KindNamedExports: + return (*NamedExports)(unsafe.Pointer(n)).Clone(f) + case KindExportSpecifier: + return (*ExportSpecifier)(unsafe.Pointer(n)).Clone(f) + case KindCallSignature: + return (*CallSignatureDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindConstructSignature: + return (*ConstructSignatureDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindConstructor: + return (*ConstructorDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindGetAccessor: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindSetAccessor: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindIndexSignature: + return (*IndexSignatureDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindMethodSignature: + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindMethodDeclaration: + return (*MethodDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindPropertySignature: + return (*PropertySignatureDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindPropertyDeclaration: + return (*PropertyDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindSemicolonClassElement: + return (*SemicolonClassElement)(unsafe.Pointer(n)).Clone(f) + case KindClassStaticBlockDeclaration: + return (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindOmittedExpression: + return (*OmittedExpression)(unsafe.Pointer(n)).Clone(f) + case KindBinaryExpression: + return (*BinaryExpression)(unsafe.Pointer(n)).Clone(f) + case KindPrefixUnaryExpression: + return (*PrefixUnaryExpression)(unsafe.Pointer(n)).Clone(f) + case KindPostfixUnaryExpression: + return (*PostfixUnaryExpression)(unsafe.Pointer(n)).Clone(f) + case KindYieldExpression: + return (*YieldExpression)(unsafe.Pointer(n)).Clone(f) + case KindArrowFunction: + return (*ArrowFunction)(unsafe.Pointer(n)).Clone(f) + case KindFunctionExpression: + return (*FunctionExpression)(unsafe.Pointer(n)).Clone(f) + case KindAsExpression: + return (*AsExpression)(unsafe.Pointer(n)).Clone(f) + case KindSatisfiesExpression: + return (*SatisfiesExpression)(unsafe.Pointer(n)).Clone(f) + case KindConditionalExpression: + return (*ConditionalExpression)(unsafe.Pointer(n)).Clone(f) + case KindPropertyAccessExpression: + return (*PropertyAccessExpression)(unsafe.Pointer(n)).Clone(f) + case KindElementAccessExpression: + return (*ElementAccessExpression)(unsafe.Pointer(n)).Clone(f) + case KindCallExpression: + return (*CallExpression)(unsafe.Pointer(n)).Clone(f) + case KindNewExpression: + return (*NewExpression)(unsafe.Pointer(n)).Clone(f) + case KindMetaProperty: + return (*MetaProperty)(unsafe.Pointer(n)).Clone(f) + case KindNonNullExpression: + return (*NonNullExpression)(unsafe.Pointer(n)).Clone(f) + case KindSpreadElement: + return (*SpreadElement)(unsafe.Pointer(n)).Clone(f) + case KindTemplateExpression: + return (*TemplateExpression)(unsafe.Pointer(n)).Clone(f) + case KindTemplateSpan: + return (*TemplateSpan)(unsafe.Pointer(n)).Clone(f) + case KindTaggedTemplateExpression: + return (*TaggedTemplateExpression)(unsafe.Pointer(n)).Clone(f) + case KindParenthesizedExpression: + return (*ParenthesizedExpression)(unsafe.Pointer(n)).Clone(f) + case KindArrayLiteralExpression: + return (*ArrayLiteralExpression)(unsafe.Pointer(n)).Clone(f) + case KindObjectLiteralExpression: + return (*ObjectLiteralExpression)(unsafe.Pointer(n)).Clone(f) + case KindSpreadAssignment: + return (*SpreadAssignment)(unsafe.Pointer(n)).Clone(f) + case KindPropertyAssignment: + return (*PropertyAssignment)(unsafe.Pointer(n)).Clone(f) + case KindShorthandPropertyAssignment: + return (*ShorthandPropertyAssignment)(unsafe.Pointer(n)).Clone(f) + case KindDeleteExpression: + return (*DeleteExpression)(unsafe.Pointer(n)).Clone(f) + case KindTypeOfExpression: + return (*TypeOfExpression)(unsafe.Pointer(n)).Clone(f) + case KindVoidExpression: + return (*VoidExpression)(unsafe.Pointer(n)).Clone(f) + case KindAwaitExpression: + return (*AwaitExpression)(unsafe.Pointer(n)).Clone(f) + case KindTypeAssertionExpression: + return (*TypeAssertion)(unsafe.Pointer(n)).Clone(f) + case KindUnionType: + return (*UnionTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindIntersectionType: + return (*IntersectionTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindConditionalType: + return (*ConditionalTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindTypeOperator: + return (*TypeOperatorNode)(unsafe.Pointer(n)).Clone(f) + case KindInferType: + return (*InferTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindArrayType: + return (*ArrayTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindIndexedAccessType: + return (*IndexedAccessTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindTypeReference: + return (*TypeReferenceNode)(unsafe.Pointer(n)).Clone(f) + case KindExpressionWithTypeArguments: + return (*ExpressionWithTypeArguments)(unsafe.Pointer(n)).Clone(f) + case KindLiteralType: + return (*LiteralTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindThisType: + return (*ThisTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindTypePredicate: + return (*TypePredicateNode)(unsafe.Pointer(n)).Clone(f) + case KindImportAttribute: + return (*ImportAttribute)(unsafe.Pointer(n)).Clone(f) + case KindImportAttributes: + return (*ImportAttributes)(unsafe.Pointer(n)).Clone(f) + case KindTypeQuery: + return (*TypeQueryNode)(unsafe.Pointer(n)).Clone(f) + case KindMappedType: + return (*MappedTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindTypeLiteral: + return (*TypeLiteralNode)(unsafe.Pointer(n)).Clone(f) + case KindTupleType: + return (*TupleTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindNamedTupleMember: + return (*NamedTupleMember)(unsafe.Pointer(n)).Clone(f) + case KindOptionalType: + return (*OptionalTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindRestType: + return (*RestTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindParenthesizedType: + return (*ParenthesizedTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindFunctionType: + return (*FunctionTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindConstructorType: + return (*ConstructorTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindTemplateLiteralType: + return (*TemplateLiteralTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindTemplateLiteralTypeSpan: + return (*TemplateLiteralTypeSpan)(unsafe.Pointer(n)).Clone(f) + case KindSyntheticExpression: + return (*SyntheticExpression)(unsafe.Pointer(n)).Clone(f) + case KindPartiallyEmittedExpression: + return (*PartiallyEmittedExpression)(unsafe.Pointer(n)).Clone(f) + case KindJsxElement: + return (*JsxElement)(unsafe.Pointer(n)).Clone(f) + case KindJsxAttributes: + return (*JsxAttributes)(unsafe.Pointer(n)).Clone(f) + case KindJsxNamespacedName: + return (*JsxNamespacedName)(unsafe.Pointer(n)).Clone(f) + case KindJsxOpeningElement: + return (*JsxOpeningElement)(unsafe.Pointer(n)).Clone(f) + case KindJsxSelfClosingElement: + return (*JsxSelfClosingElement)(unsafe.Pointer(n)).Clone(f) + case KindJsxFragment: + return (*JsxFragment)(unsafe.Pointer(n)).Clone(f) + case KindJsxOpeningFragment: + return (*JsxOpeningFragment)(unsafe.Pointer(n)).Clone(f) + case KindJsxClosingFragment: + return (*JsxClosingFragment)(unsafe.Pointer(n)).Clone(f) + case KindJsxAttribute: + return (*JsxAttribute)(unsafe.Pointer(n)).Clone(f) + case KindJsxSpreadAttribute: + return (*JsxSpreadAttribute)(unsafe.Pointer(n)).Clone(f) + case KindJsxClosingElement: + return (*JsxClosingElement)(unsafe.Pointer(n)).Clone(f) + case KindJsxExpression: + return (*JsxExpression)(unsafe.Pointer(n)).Clone(f) + case KindSyntaxList: + return (*SyntaxList)(unsafe.Pointer(n)).Clone(f) + case KindJSDoc: + return (*JSDoc)(unsafe.Pointer(n)).Clone(f) + case KindJSDocTypeExpression: + return (*JSDocTypeExpression)(unsafe.Pointer(n)).Clone(f) + case KindJSDocNonNullableType: + return (*JSDocNonNullableType)(unsafe.Pointer(n)).Clone(f) + case KindJSDocNullableType: + return (*JSDocNullableType)(unsafe.Pointer(n)).Clone(f) + case KindJSDocAllType: + return (*JSDocAllType)(unsafe.Pointer(n)).Clone(f) + case KindJSDocVariadicType: + return (*JSDocVariadicType)(unsafe.Pointer(n)).Clone(f) + case KindJSDocOptionalType: + return (*JSDocOptionalType)(unsafe.Pointer(n)).Clone(f) + case KindJSDocTypeTag: + return (*JSDocTypeTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocUnknownTag: + return (*JSDocUnknownTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocTemplateTag: + return (*JSDocTemplateTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocReturnTag: + return (*JSDocReturnTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocPublicTag: + return (*JSDocPublicTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocPrivateTag: + return (*JSDocPrivateTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocProtectedTag: + return (*JSDocProtectedTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocReadonlyTag: + return (*JSDocReadonlyTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocOverrideTag: + return (*JSDocOverrideTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocDeprecatedTag: + return (*JSDocDeprecatedTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocSeeTag: + return (*JSDocSeeTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocImplementsTag: + return (*JSDocImplementsTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocAugmentsTag: + return (*JSDocAugmentsTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocSatisfiesTag: + return (*JSDocSatisfiesTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocThrowsTag: + return (*JSDocThrowsTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocThisTag: + return (*JSDocThisTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocImportTag: + return (*JSDocImportTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocCallbackTag: + return (*JSDocCallbackTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocOverloadTag: + return (*JSDocOverloadTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocTypedefTag: + return (*JSDocTypedefTag)(unsafe.Pointer(n)).Clone(f) + case KindJSDocSignature: + return (*JSDocSignature)(unsafe.Pointer(n)).Clone(f) + case KindJSDocNameReference: + return (*JSDocNameReference)(unsafe.Pointer(n)).Clone(f) + case KindSourceFile: + return (*SourceFile)(unsafe.Pointer(n)).Clone(f) + case KindModuleDeclaration: + return (*ModuleDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindImportEqualsDeclaration: + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindExportDeclaration: + return (*ExportDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindImportType: + return (*ImportTypeNode)(unsafe.Pointer(n)).Clone(f) + case KindImportClause: + return (*ImportClause)(unsafe.Pointer(n)).Clone(f) + case KindImportSpecifier: + return (*ImportSpecifier)(unsafe.Pointer(n)).Clone(f) + case KindJSDocText: + return (*JSDocText)(unsafe.Pointer(n)).Clone(f) + case KindJSDocLink: + return (*JSDocLink)(unsafe.Pointer(n)).Clone(f) + case KindJSDocLinkPlain: + return (*JSDocLinkPlain)(unsafe.Pointer(n)).Clone(f) + case KindJSDocLinkCode: + return (*JSDocLinkCode)(unsafe.Pointer(n)).Clone(f) + case KindTypeParameter: + return (*TypeParameterDeclaration)(unsafe.Pointer(n)).Clone(f) + case KindSyntheticReferenceExpression: + return (*SyntheticReferenceExpression)(unsafe.Pointer(n)).Clone(f) + case KindJSDocTypeLiteral: + return (*JSDocTypeLiteral)(unsafe.Pointer(n)).Clone(f) + case KindJSDocParameterTag, KindJSDocPropertyTag: + return (*JSDocParameterOrPropertyTag)(unsafe.Pointer(n)).Clone(f) + default: + return nil + } +} + +// ────────────────────────────────────────────────────────────────────── +// Subtree facts dispatch +// ────────────────────────────────────────────────────────────────────── + +func (n *Node) SubtreeFacts() SubtreeFacts { + switch n.Kind { + case kindFlowSwitchClauseData, kindFlowReduceLabelData: + return SubtreeFactsNone + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + return n.computeSubtreeFacts() + case KindNumericLiteral: + return n.computeSubtreeFacts() + case KindBigIntLiteral: + return n.computeSubtreeFacts() + case KindStringLiteral: + return n.computeSubtreeFacts() + case KindJsxText: + return n.computeSubtreeFacts() + case KindRegularExpressionLiteral: + return n.computeSubtreeFacts() + case KindNoSubstitutionTemplateLiteral: + return n.computeSubtreeFacts() + case KindTemplateHead: + return n.computeSubtreeFacts() + case KindTemplateMiddle: + return n.computeSubtreeFacts() + case KindTemplateTail: + return n.computeSubtreeFacts() + case KindIdentifier: + return n.computeSubtreeFacts() + case KindPrivateIdentifier: + return n.computeSubtreeFacts() + case KindFalseKeyword, KindImportKeyword, KindNullKeyword, KindSuperKeyword, KindThisKeyword, KindTrueKeyword: + return n.computeSubtreeFacts() + case KindVoidKeyword, KindAnyKeyword, KindBooleanKeyword, KindIntrinsicKeyword, KindNeverKeyword, KindNumberKeyword, KindObjectKeyword, KindStringKeyword, KindSymbolKeyword, KindUndefinedKeyword, KindUnknownKeyword, KindBigIntKeyword: + return n.computeSubtreeFacts() + case KindQualifiedName: + return (*QualifiedName)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindComputedPropertyName: + return (*ComputedPropertyName)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindDecorator: + return (*Decorator)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindEmptyStatement: + return n.computeSubtreeFacts() + case KindIfStatement: + return (*IfStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindDoStatement: + return (*DoStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindWhileStatement: + return (*WhileStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindForStatement: + return (*ForStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindForInStatement, KindForOfStatement: + return (*ForInOrOfStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindBreakStatement: + return n.computeSubtreeFacts() + case KindContinueStatement: + return n.computeSubtreeFacts() + case KindReturnStatement: + return (*ReturnStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindWithStatement: + return (*WithStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindSwitchStatement: + return (*SwitchStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindCaseBlock: + return (*CaseBlock)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindCaseClause, KindDefaultClause: + return (*CaseOrDefaultClause)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindThrowStatement: + return (*ThrowStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindTryStatement: + return (*TryStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindCatchClause: + return (*CatchClause)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindDebuggerStatement: + return n.computeSubtreeFacts() + case KindLabeledStatement: + return n.computeSubtreeFacts() + case KindExpressionStatement: + return n.computeSubtreeFacts() + case KindBlock: + return (*Block)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindVariableStatement: + return (*VariableStatement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindVariableDeclaration: + return (*VariableDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindVariableDeclarationList: + return (*VariableDeclarationList)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindObjectBindingPattern, KindArrayBindingPattern: + return (*BindingPattern)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindParameter: + return (*ParameterDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindBindingElement: + return (*BindingElement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindMissingDeclaration: + return n.computeSubtreeFacts() + case KindFunctionDeclaration: + return (*FunctionDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindClassDeclaration: + return (*ClassDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindClassExpression: + return (*ClassExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindHeritageClause: + return (*HeritageClause)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindInterfaceDeclaration: + return n.computeSubtreeFacts() + case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + return n.computeSubtreeFacts() + case KindEnumMember: + return (*EnumMember)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindEnumDeclaration: + return (*EnumDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindModuleBlock: + return (*ModuleBlock)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindNotEmittedStatement: + return n.computeSubtreeFacts() + case KindNotEmittedTypeElement: + return n.computeSubtreeFacts() + case KindImportDeclaration, KindJSImportDeclaration: + return (*ImportDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindExternalModuleReference: + return n.computeSubtreeFacts() + case KindNamespaceImport: + return n.computeSubtreeFacts() + case KindNamedImports: + return (*NamedImports)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindExportAssignment: + return (*ExportAssignment)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindNamespaceExportDeclaration: + return n.computeSubtreeFacts() + case KindNamespaceExport: + return n.computeSubtreeFacts() + case KindNamedExports: + return (*NamedExports)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindExportSpecifier: + return (*ExportSpecifier)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindCallSignature: + return n.computeSubtreeFacts() + case KindConstructSignature: + return n.computeSubtreeFacts() + case KindConstructor: + return (*ConstructorDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindGetAccessor: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindSetAccessor: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindIndexSignature: + return n.computeSubtreeFacts() + case KindMethodSignature: + return n.computeSubtreeFacts() + case KindMethodDeclaration: + return (*MethodDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindPropertySignature: + return n.computeSubtreeFacts() + case KindPropertyDeclaration: + return (*PropertyDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindSemicolonClassElement: + return n.computeSubtreeFacts() + case KindClassStaticBlockDeclaration: + return (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindOmittedExpression: + return n.computeSubtreeFacts() + case KindBinaryExpression: + return (*BinaryExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindPrefixUnaryExpression: + return n.computeSubtreeFacts() + case KindPostfixUnaryExpression: + return n.computeSubtreeFacts() + case KindYieldExpression: + return n.computeSubtreeFacts() + case KindArrowFunction: + return (*ArrowFunction)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindFunctionExpression: + return (*FunctionExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindAsExpression: + return n.computeSubtreeFacts() + case KindSatisfiesExpression: + return n.computeSubtreeFacts() + case KindConditionalExpression: + return (*ConditionalExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindPropertyAccessExpression: + return (*PropertyAccessExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindElementAccessExpression: + return (*ElementAccessExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindCallExpression: + return (*CallExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindNewExpression: + return (*NewExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindMetaProperty: + return (*MetaProperty)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindNonNullExpression: + return n.computeSubtreeFacts() + case KindSpreadElement: + return n.computeSubtreeFacts() + case KindTemplateExpression: + return (*TemplateExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindTemplateSpan: + return n.computeSubtreeFacts() + case KindTaggedTemplateExpression: + return (*TaggedTemplateExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindParenthesizedExpression: + return n.computeSubtreeFacts() + case KindArrayLiteralExpression: + return (*ArrayLiteralExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindObjectLiteralExpression: + return (*ObjectLiteralExpression)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindSpreadAssignment: + return n.computeSubtreeFacts() + case KindPropertyAssignment: + return (*PropertyAssignment)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindShorthandPropertyAssignment: + return (*ShorthandPropertyAssignment)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindDeleteExpression: + return n.computeSubtreeFacts() + case KindTypeOfExpression: + return n.computeSubtreeFacts() + case KindVoidExpression: + return n.computeSubtreeFacts() + case KindAwaitExpression: + return n.computeSubtreeFacts() + case KindTypeAssertionExpression: + return n.computeSubtreeFacts() + case KindUnionType: + return n.computeSubtreeFacts() + case KindIntersectionType: + return n.computeSubtreeFacts() + case KindConditionalType: + return n.computeSubtreeFacts() + case KindTypeOperator: + return n.computeSubtreeFacts() + case KindInferType: + return n.computeSubtreeFacts() + case KindArrayType: + return n.computeSubtreeFacts() + case KindIndexedAccessType: + return n.computeSubtreeFacts() + case KindTypeReference: + return n.computeSubtreeFacts() + case KindExpressionWithTypeArguments: + return (*ExpressionWithTypeArguments)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindLiteralType: + return n.computeSubtreeFacts() + case KindThisType: + return n.computeSubtreeFacts() + case KindTypePredicate: + return n.computeSubtreeFacts() + case KindImportAttribute: + return (*ImportAttribute)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindImportAttributes: + return (*ImportAttributes)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindTypeQuery: + return n.computeSubtreeFacts() + case KindMappedType: + return n.computeSubtreeFacts() + case KindTypeLiteral: + return n.computeSubtreeFacts() + case KindTupleType: + return n.computeSubtreeFacts() + case KindNamedTupleMember: + return n.computeSubtreeFacts() + case KindOptionalType: + return n.computeSubtreeFacts() + case KindRestType: + return n.computeSubtreeFacts() + case KindParenthesizedType: + return n.computeSubtreeFacts() + case KindFunctionType: + return n.computeSubtreeFacts() + case KindConstructorType: + return n.computeSubtreeFacts() + case KindTemplateLiteralType: + return n.computeSubtreeFacts() + case KindTemplateLiteralTypeSpan: + return n.computeSubtreeFacts() + case KindSyntheticExpression: + return n.computeSubtreeFacts() + case KindPartiallyEmittedExpression: + return n.computeSubtreeFacts() + case KindJsxElement: + return (*JsxElement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindJsxAttributes: + return (*JsxAttributes)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindJsxNamespacedName: + return (*JsxNamespacedName)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindJsxOpeningElement: + return (*JsxOpeningElement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindJsxSelfClosingElement: + return (*JsxSelfClosingElement)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindJsxFragment: + return (*JsxFragment)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindJsxOpeningFragment: + return n.computeSubtreeFacts() + case KindJsxClosingFragment: + return n.computeSubtreeFacts() + case KindJsxAttribute: + return (*JsxAttribute)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindJsxSpreadAttribute: + return n.computeSubtreeFacts() + case KindJsxClosingElement: + return n.computeSubtreeFacts() + case KindJsxExpression: + return n.computeSubtreeFacts() + case KindSyntaxList: + return n.computeSubtreeFacts() + case KindJSDoc: + return n.computeSubtreeFacts() + case KindJSDocTypeExpression: + return n.computeSubtreeFacts() + case KindJSDocNonNullableType: + return n.computeSubtreeFacts() + case KindJSDocNullableType: + return n.computeSubtreeFacts() + case KindJSDocAllType: + return n.computeSubtreeFacts() + case KindJSDocVariadicType: + return n.computeSubtreeFacts() + case KindJSDocOptionalType: + return n.computeSubtreeFacts() + case KindJSDocTypeTag: + return n.computeSubtreeFacts() + case KindJSDocUnknownTag: + return n.computeSubtreeFacts() + case KindJSDocTemplateTag: + return n.computeSubtreeFacts() + case KindJSDocReturnTag: + return n.computeSubtreeFacts() + case KindJSDocPublicTag: + return n.computeSubtreeFacts() + case KindJSDocPrivateTag: + return n.computeSubtreeFacts() + case KindJSDocProtectedTag: + return n.computeSubtreeFacts() + case KindJSDocReadonlyTag: + return n.computeSubtreeFacts() + case KindJSDocOverrideTag: + return n.computeSubtreeFacts() + case KindJSDocDeprecatedTag: + return n.computeSubtreeFacts() + case KindJSDocSeeTag: + return n.computeSubtreeFacts() + case KindJSDocImplementsTag: + return n.computeSubtreeFacts() + case KindJSDocAugmentsTag: + return n.computeSubtreeFacts() + case KindJSDocSatisfiesTag: + return n.computeSubtreeFacts() + case KindJSDocThrowsTag: + return n.computeSubtreeFacts() + case KindJSDocThisTag: + return n.computeSubtreeFacts() + case KindJSDocImportTag: + return n.computeSubtreeFacts() + case KindJSDocCallbackTag: + return n.computeSubtreeFacts() + case KindJSDocOverloadTag: + return n.computeSubtreeFacts() + case KindJSDocTypedefTag: + return n.computeSubtreeFacts() + case KindJSDocSignature: + return n.computeSubtreeFacts() + case KindJSDocNameReference: + return n.computeSubtreeFacts() + case KindSourceFile: + return (*SourceFile)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindModuleDeclaration: + return (*ModuleDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindImportEqualsDeclaration: + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindExportDeclaration: + return (*ExportDeclaration)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindImportType: + return n.computeSubtreeFacts() + case KindImportClause: + return (*ImportClause)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindImportSpecifier: + return (*ImportSpecifier)(unsafe.Pointer(n)).subtreeFactsWorker(n) + case KindJSDocText: + return n.computeSubtreeFacts() + case KindJSDocLink: + return n.computeSubtreeFacts() + case KindJSDocLinkPlain: + return n.computeSubtreeFacts() + case KindJSDocLinkCode: + return n.computeSubtreeFacts() + case KindTypeParameter: + return n.computeSubtreeFacts() + case KindSyntheticReferenceExpression: + return n.computeSubtreeFacts() + case KindJSDocTypeLiteral: + return n.computeSubtreeFacts() + case KindJSDocParameterTag, KindJSDocPropertyTag: + return n.computeSubtreeFacts() + default: + return SubtreeFactsNone + } +} + +func (n *Node) computeSubtreeFacts() SubtreeFacts { + switch n.Kind { + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + return (*Token)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNumericLiteral: + return (*NumericLiteral)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindBigIntLiteral: + return (*BigIntLiteral)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindStringLiteral: + return (*StringLiteral)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxText: + return (*JsxText)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindRegularExpressionLiteral: + return (*RegularExpressionLiteral)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNoSubstitutionTemplateLiteral: + return (*NoSubstitutionTemplateLiteral)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTemplateHead: + return (*TemplateHead)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTemplateMiddle: + return (*TemplateMiddle)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTemplateTail: + return (*TemplateTail)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindIdentifier: + return (*Identifier)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindPrivateIdentifier: + return (*PrivateIdentifier)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindFalseKeyword, KindImportKeyword, KindNullKeyword, KindSuperKeyword, KindThisKeyword, KindTrueKeyword: + return (*KeywordExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindVoidKeyword, KindAnyKeyword, KindBooleanKeyword, KindIntrinsicKeyword, KindNeverKeyword, KindNumberKeyword, KindObjectKeyword, KindStringKeyword, KindSymbolKeyword, KindUndefinedKeyword, KindUnknownKeyword, KindBigIntKeyword: + return (*KeywordTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindQualifiedName: + return (*QualifiedName)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindComputedPropertyName: + return (*ComputedPropertyName)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindDecorator: + return (*Decorator)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindEmptyStatement: + return (*EmptyStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindIfStatement: + return (*IfStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindDoStatement: + return (*DoStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindWhileStatement: + return (*WhileStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindForStatement: + return (*ForStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindForInStatement, KindForOfStatement: + return (*ForInOrOfStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindBreakStatement: + return (*BreakStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindContinueStatement: + return (*ContinueStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindReturnStatement: + return (*ReturnStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindWithStatement: + return (*WithStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindSwitchStatement: + return (*SwitchStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindCaseBlock: + return (*CaseBlock)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindCaseClause, KindDefaultClause: + return (*CaseOrDefaultClause)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindThrowStatement: + return (*ThrowStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTryStatement: + return (*TryStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindCatchClause: + return (*CatchClause)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindDebuggerStatement: + return (*DebuggerStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindLabeledStatement: + return (*LabeledStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindExpressionStatement: + return (*ExpressionStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindBlock: + return (*Block)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindVariableStatement: + return (*VariableStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindVariableDeclaration: + return (*VariableDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindVariableDeclarationList: + return (*VariableDeclarationList)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindObjectBindingPattern, KindArrayBindingPattern: + return (*BindingPattern)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindParameter: + return (*ParameterDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindBindingElement: + return (*BindingElement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindMissingDeclaration: + return (*MissingDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindFunctionDeclaration: + return (*FunctionDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindClassDeclaration: + return (*ClassDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindClassExpression: + return (*ClassExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindHeritageClause: + return (*HeritageClause)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindInterfaceDeclaration: + return (*InterfaceDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindEnumMember: + return (*EnumMember)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindEnumDeclaration: + return (*EnumDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindModuleBlock: + return (*ModuleBlock)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNotEmittedStatement: + return (*NotEmittedStatement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNotEmittedTypeElement: + return (*NotEmittedTypeElement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindImportDeclaration, KindJSImportDeclaration: + return (*ImportDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindExternalModuleReference: + return (*ExternalModuleReference)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNamespaceImport: + return (*NamespaceImport)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNamedImports: + return (*NamedImports)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindExportAssignment: + return (*ExportAssignment)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNamespaceExportDeclaration: + return (*NamespaceExportDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNamespaceExport: + return (*NamespaceExport)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNamedExports: + return (*NamedExports)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindExportSpecifier: + return (*ExportSpecifier)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindCallSignature: + return (*CallSignatureDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindConstructSignature: + return (*ConstructSignatureDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindConstructor: + return (*ConstructorDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindGetAccessor: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindSetAccessor: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindIndexSignature: + return (*IndexSignatureDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindMethodSignature: + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindMethodDeclaration: + return (*MethodDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindPropertySignature: + return (*PropertySignatureDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindPropertyDeclaration: + return (*PropertyDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindSemicolonClassElement: + return (*SemicolonClassElement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindClassStaticBlockDeclaration: + return (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindOmittedExpression: + return (*OmittedExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindBinaryExpression: + return (*BinaryExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindPrefixUnaryExpression: + return (*PrefixUnaryExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindPostfixUnaryExpression: + return (*PostfixUnaryExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindYieldExpression: + return (*YieldExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindArrowFunction: + return (*ArrowFunction)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindFunctionExpression: + return (*FunctionExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindAsExpression: + return (*AsExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindSatisfiesExpression: + return (*SatisfiesExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindConditionalExpression: + return (*ConditionalExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindPropertyAccessExpression: + return (*PropertyAccessExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindElementAccessExpression: + return (*ElementAccessExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindCallExpression: + return (*CallExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNewExpression: + return (*NewExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindMetaProperty: + return (*MetaProperty)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNonNullExpression: + return (*NonNullExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindSpreadElement: + return (*SpreadElement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTemplateExpression: + return (*TemplateExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTemplateSpan: + return (*TemplateSpan)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTaggedTemplateExpression: + return (*TaggedTemplateExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindParenthesizedExpression: + return (*ParenthesizedExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindArrayLiteralExpression: + return (*ArrayLiteralExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindObjectLiteralExpression: + return (*ObjectLiteralExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindSpreadAssignment: + return (*SpreadAssignment)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindPropertyAssignment: + return (*PropertyAssignment)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindShorthandPropertyAssignment: + return (*ShorthandPropertyAssignment)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindDeleteExpression: + return (*DeleteExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTypeOfExpression: + return (*TypeOfExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindVoidExpression: + return (*VoidExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindAwaitExpression: + return (*AwaitExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTypeAssertionExpression: + return (*TypeAssertion)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindUnionType: + return (*UnionTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindIntersectionType: + return (*IntersectionTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindConditionalType: + return (*ConditionalTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTypeOperator: + return (*TypeOperatorNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindInferType: + return (*InferTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindArrayType: + return (*ArrayTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindIndexedAccessType: + return (*IndexedAccessTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTypeReference: + return (*TypeReferenceNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindExpressionWithTypeArguments: + return (*ExpressionWithTypeArguments)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindLiteralType: + return (*LiteralTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindThisType: + return (*ThisTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTypePredicate: + return (*TypePredicateNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindImportAttribute: + return (*ImportAttribute)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindImportAttributes: + return (*ImportAttributes)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTypeQuery: + return (*TypeQueryNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindMappedType: + return (*MappedTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTypeLiteral: + return (*TypeLiteralNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTupleType: + return (*TupleTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindNamedTupleMember: + return (*NamedTupleMember)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindOptionalType: + return (*OptionalTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindRestType: + return (*RestTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindParenthesizedType: + return (*ParenthesizedTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindFunctionType: + return (*FunctionTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindConstructorType: + return (*ConstructorTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTemplateLiteralType: + return (*TemplateLiteralTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTemplateLiteralTypeSpan: + return (*TemplateLiteralTypeSpan)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindSyntheticExpression: + return (*SyntheticExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindPartiallyEmittedExpression: + return (*PartiallyEmittedExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxElement: + return (*JsxElement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxAttributes: + return (*JsxAttributes)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxNamespacedName: + return (*JsxNamespacedName)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxOpeningElement: + return (*JsxOpeningElement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxSelfClosingElement: + return (*JsxSelfClosingElement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxFragment: + return (*JsxFragment)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxOpeningFragment: + return (*JsxOpeningFragment)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxClosingFragment: + return (*JsxClosingFragment)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxAttribute: + return (*JsxAttribute)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxSpreadAttribute: + return (*JsxSpreadAttribute)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxClosingElement: + return (*JsxClosingElement)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJsxExpression: + return (*JsxExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindSyntaxList: + return (*SyntaxList)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDoc: + return (*JSDoc)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocTypeExpression: + return (*JSDocTypeExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocNonNullableType: + return (*JSDocNonNullableType)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocNullableType: + return (*JSDocNullableType)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocAllType: + return (*JSDocAllType)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocVariadicType: + return (*JSDocVariadicType)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocOptionalType: + return (*JSDocOptionalType)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocTypeTag: + return (*JSDocTypeTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocUnknownTag: + return (*JSDocUnknownTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocTemplateTag: + return (*JSDocTemplateTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocReturnTag: + return (*JSDocReturnTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocPublicTag: + return (*JSDocPublicTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocPrivateTag: + return (*JSDocPrivateTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocProtectedTag: + return (*JSDocProtectedTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocReadonlyTag: + return (*JSDocReadonlyTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocOverrideTag: + return (*JSDocOverrideTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocDeprecatedTag: + return (*JSDocDeprecatedTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocSeeTag: + return (*JSDocSeeTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocImplementsTag: + return (*JSDocImplementsTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocAugmentsTag: + return (*JSDocAugmentsTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocSatisfiesTag: + return (*JSDocSatisfiesTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocThrowsTag: + return (*JSDocThrowsTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocThisTag: + return (*JSDocThisTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocImportTag: + return (*JSDocImportTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocCallbackTag: + return (*JSDocCallbackTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocOverloadTag: + return (*JSDocOverloadTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocTypedefTag: + return (*JSDocTypedefTag)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocSignature: + return (*JSDocSignature)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocNameReference: + return (*JSDocNameReference)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindSourceFile: + return (*SourceFile)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindModuleDeclaration: + return (*ModuleDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindImportEqualsDeclaration: + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindExportDeclaration: + return (*ExportDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindImportType: + return (*ImportTypeNode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindImportClause: + return (*ImportClause)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindImportSpecifier: + return (*ImportSpecifier)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocText: + return (*JSDocText)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocLink: + return (*JSDocLink)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocLinkPlain: + return (*JSDocLinkPlain)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocLinkCode: + return (*JSDocLinkCode)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindTypeParameter: + return (*TypeParameterDeclaration)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindSyntheticReferenceExpression: + return (*SyntheticReferenceExpression)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocTypeLiteral: + return (*JSDocTypeLiteral)(unsafe.Pointer(n)).computeSubtreeFacts() + case KindJSDocParameterTag, KindJSDocPropertyTag: + return (*JSDocParameterOrPropertyTag)(unsafe.Pointer(n)).computeSubtreeFacts() + default: + return SubtreeFactsNone + } +} + +func (n *Node) propagateSubtreeFacts() SubtreeFacts { + switch n.Kind { + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + return (*Token)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNumericLiteral: + return (*NumericLiteral)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindBigIntLiteral: + return (*BigIntLiteral)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindStringLiteral: + return (*StringLiteral)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxText: + return (*JsxText)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindRegularExpressionLiteral: + return (*RegularExpressionLiteral)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNoSubstitutionTemplateLiteral: + return (*NoSubstitutionTemplateLiteral)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTemplateHead: + return (*TemplateHead)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTemplateMiddle: + return (*TemplateMiddle)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTemplateTail: + return (*TemplateTail)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindIdentifier: + return (*Identifier)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindPrivateIdentifier: + return (*PrivateIdentifier)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindFalseKeyword, KindImportKeyword, KindNullKeyword, KindSuperKeyword, KindThisKeyword, KindTrueKeyword: + return (*KeywordExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindVoidKeyword, KindAnyKeyword, KindBooleanKeyword, KindIntrinsicKeyword, KindNeverKeyword, KindNumberKeyword, KindObjectKeyword, KindStringKeyword, KindSymbolKeyword, KindUndefinedKeyword, KindUnknownKeyword, KindBigIntKeyword: + return (*KeywordTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindQualifiedName: + return (*QualifiedName)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindComputedPropertyName: + return (*ComputedPropertyName)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindDecorator: + return (*Decorator)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindEmptyStatement: + return (*EmptyStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindIfStatement: + return (*IfStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindDoStatement: + return (*DoStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindWhileStatement: + return (*WhileStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindForStatement: + return (*ForStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindForInStatement, KindForOfStatement: + return (*ForInOrOfStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindBreakStatement: + return (*BreakStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindContinueStatement: + return (*ContinueStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindReturnStatement: + return (*ReturnStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindWithStatement: + return (*WithStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindSwitchStatement: + return (*SwitchStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindCaseBlock: + return (*CaseBlock)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindCaseClause, KindDefaultClause: + return (*CaseOrDefaultClause)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindThrowStatement: + return (*ThrowStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTryStatement: + return (*TryStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindCatchClause: + return (*CatchClause)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindDebuggerStatement: + return (*DebuggerStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindLabeledStatement: + return (*LabeledStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindExpressionStatement: + return (*ExpressionStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindBlock: + return (*Block)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindVariableStatement: + return (*VariableStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindVariableDeclaration: + return (*VariableDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindVariableDeclarationList: + return (*VariableDeclarationList)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindObjectBindingPattern, KindArrayBindingPattern: + return (*BindingPattern)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindParameter: + return (*ParameterDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindBindingElement: + return (*BindingElement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindMissingDeclaration: + return (*MissingDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindFunctionDeclaration: + return (*FunctionDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindClassDeclaration: + return (*ClassDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindClassExpression: + return (*ClassExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindHeritageClause: + return (*HeritageClause)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindInterfaceDeclaration: + return (*InterfaceDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindEnumMember: + return (*EnumMember)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindEnumDeclaration: + return (*EnumDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindModuleBlock: + return (*ModuleBlock)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNotEmittedStatement: + return (*NotEmittedStatement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNotEmittedTypeElement: + return (*NotEmittedTypeElement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindImportDeclaration, KindJSImportDeclaration: + return (*ImportDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindExternalModuleReference: + return (*ExternalModuleReference)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNamespaceImport: + return (*NamespaceImport)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNamedImports: + return (*NamedImports)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindExportAssignment: + return (*ExportAssignment)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNamespaceExportDeclaration: + return (*NamespaceExportDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNamespaceExport: + return (*NamespaceExport)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNamedExports: + return (*NamedExports)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindExportSpecifier: + return (*ExportSpecifier)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindCallSignature: + return (*CallSignatureDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindConstructSignature: + return (*ConstructSignatureDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindConstructor: + return (*ConstructorDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindGetAccessor: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindSetAccessor: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindIndexSignature: + return (*IndexSignatureDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindMethodSignature: + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindMethodDeclaration: + return (*MethodDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindPropertySignature: + return (*PropertySignatureDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindPropertyDeclaration: + return (*PropertyDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindSemicolonClassElement: + return (*SemicolonClassElement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindClassStaticBlockDeclaration: + return (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindOmittedExpression: + return (*OmittedExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindBinaryExpression: + return (*BinaryExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindPrefixUnaryExpression: + return (*PrefixUnaryExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindPostfixUnaryExpression: + return (*PostfixUnaryExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindYieldExpression: + return (*YieldExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindArrowFunction: + return (*ArrowFunction)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindFunctionExpression: + return (*FunctionExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindAsExpression: + return (*AsExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindSatisfiesExpression: + return (*SatisfiesExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindConditionalExpression: + return (*ConditionalExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindPropertyAccessExpression: + return (*PropertyAccessExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindElementAccessExpression: + return (*ElementAccessExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindCallExpression: + return (*CallExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNewExpression: + return (*NewExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindMetaProperty: + return (*MetaProperty)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNonNullExpression: + return (*NonNullExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindSpreadElement: + return (*SpreadElement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTemplateExpression: + return (*TemplateExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTemplateSpan: + return (*TemplateSpan)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTaggedTemplateExpression: + return (*TaggedTemplateExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindParenthesizedExpression: + return (*ParenthesizedExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindArrayLiteralExpression: + return (*ArrayLiteralExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindObjectLiteralExpression: + return (*ObjectLiteralExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindSpreadAssignment: + return (*SpreadAssignment)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindPropertyAssignment: + return (*PropertyAssignment)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindShorthandPropertyAssignment: + return (*ShorthandPropertyAssignment)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindDeleteExpression: + return (*DeleteExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTypeOfExpression: + return (*TypeOfExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindVoidExpression: + return (*VoidExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindAwaitExpression: + return (*AwaitExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTypeAssertionExpression: + return (*TypeAssertion)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindUnionType: + return (*UnionTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindIntersectionType: + return (*IntersectionTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindConditionalType: + return (*ConditionalTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTypeOperator: + return (*TypeOperatorNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindInferType: + return (*InferTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindArrayType: + return (*ArrayTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindIndexedAccessType: + return (*IndexedAccessTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTypeReference: + return (*TypeReferenceNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindExpressionWithTypeArguments: + return (*ExpressionWithTypeArguments)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindLiteralType: + return (*LiteralTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindThisType: + return (*ThisTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTypePredicate: + return (*TypePredicateNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindImportAttribute: + return (*ImportAttribute)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindImportAttributes: + return (*ImportAttributes)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTypeQuery: + return (*TypeQueryNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindMappedType: + return (*MappedTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTypeLiteral: + return (*TypeLiteralNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTupleType: + return (*TupleTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindNamedTupleMember: + return (*NamedTupleMember)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindOptionalType: + return (*OptionalTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindRestType: + return (*RestTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindParenthesizedType: + return (*ParenthesizedTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindFunctionType: + return (*FunctionTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindConstructorType: + return (*ConstructorTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTemplateLiteralType: + return (*TemplateLiteralTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTemplateLiteralTypeSpan: + return (*TemplateLiteralTypeSpan)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindSyntheticExpression: + return (*SyntheticExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindPartiallyEmittedExpression: + return (*PartiallyEmittedExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxElement: + return (*JsxElement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxAttributes: + return (*JsxAttributes)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxNamespacedName: + return (*JsxNamespacedName)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxOpeningElement: + return (*JsxOpeningElement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxSelfClosingElement: + return (*JsxSelfClosingElement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxFragment: + return (*JsxFragment)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxOpeningFragment: + return (*JsxOpeningFragment)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxClosingFragment: + return (*JsxClosingFragment)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxAttribute: + return (*JsxAttribute)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxSpreadAttribute: + return (*JsxSpreadAttribute)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxClosingElement: + return (*JsxClosingElement)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJsxExpression: + return (*JsxExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindSyntaxList: + return (*SyntaxList)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDoc: + return (*JSDoc)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocTypeExpression: + return (*JSDocTypeExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocNonNullableType: + return (*JSDocNonNullableType)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocNullableType: + return (*JSDocNullableType)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocAllType: + return (*JSDocAllType)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocVariadicType: + return (*JSDocVariadicType)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocOptionalType: + return (*JSDocOptionalType)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocTypeTag: + return (*JSDocTypeTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocUnknownTag: + return (*JSDocUnknownTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocTemplateTag: + return (*JSDocTemplateTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocReturnTag: + return (*JSDocReturnTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocPublicTag: + return (*JSDocPublicTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocPrivateTag: + return (*JSDocPrivateTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocProtectedTag: + return (*JSDocProtectedTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocReadonlyTag: + return (*JSDocReadonlyTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocOverrideTag: + return (*JSDocOverrideTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocDeprecatedTag: + return (*JSDocDeprecatedTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocSeeTag: + return (*JSDocSeeTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocImplementsTag: + return (*JSDocImplementsTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocAugmentsTag: + return (*JSDocAugmentsTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocSatisfiesTag: + return (*JSDocSatisfiesTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocThrowsTag: + return (*JSDocThrowsTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocThisTag: + return (*JSDocThisTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocImportTag: + return (*JSDocImportTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocCallbackTag: + return (*JSDocCallbackTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocOverloadTag: + return (*JSDocOverloadTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocTypedefTag: + return (*JSDocTypedefTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocSignature: + return (*JSDocSignature)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocNameReference: + return (*JSDocNameReference)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindSourceFile: + return (*SourceFile)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindModuleDeclaration: + return (*ModuleDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindImportEqualsDeclaration: + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindExportDeclaration: + return (*ExportDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindImportType: + return (*ImportTypeNode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindImportClause: + return (*ImportClause)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindImportSpecifier: + return (*ImportSpecifier)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocText: + return (*JSDocText)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocLink: + return (*JSDocLink)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocLinkPlain: + return (*JSDocLinkPlain)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocLinkCode: + return (*JSDocLinkCode)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindTypeParameter: + return (*TypeParameterDeclaration)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindSyntheticReferenceExpression: + return (*SyntheticReferenceExpression)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocTypeLiteral: + return (*JSDocTypeLiteral)(unsafe.Pointer(n)).propagateSubtreeFacts() + case KindJSDocParameterTag, KindJSDocPropertyTag: + return (*JSDocParameterOrPropertyTag)(unsafe.Pointer(n)).propagateSubtreeFacts() + default: + return SubtreeFactsNone + } +} + +// ────────────────────────────────────────────────────────────────────── +// Node accessor dispatch +// ────────────────────────────────────────────────────────────────────── + +var nodeFlowNodeDataDispatch = [kindFlowReduceLabelData + 1]uint8{ + KindIdentifier: 1, + KindQualifiedName: 2, + KindEmptyStatement: 3, + KindIfStatement: 4, + KindDoStatement: 5, + KindWhileStatement: 6, + KindForStatement: 7, + KindForInStatement: 8, + KindForOfStatement: 8, + KindBreakStatement: 9, + KindContinueStatement: 10, + KindReturnStatement: 11, + KindWithStatement: 12, + KindSwitchStatement: 13, + KindThrowStatement: 14, + KindTryStatement: 15, + KindDebuggerStatement: 16, + KindLabeledStatement: 17, + KindExpressionStatement: 18, + KindBlock: 19, + KindVariableStatement: 20, + KindBindingElement: 21, + KindMissingDeclaration: 22, + KindFunctionDeclaration: 23, + KindClassDeclaration: 24, + KindInterfaceDeclaration: 25, + KindTypeAliasDeclaration: 26, + KindJSTypeAliasDeclaration: 26, + KindEnumDeclaration: 27, + KindModuleBlock: 28, + KindNotEmittedStatement: 29, + KindImportDeclaration: 30, + KindJSImportDeclaration: 30, + KindExportAssignment: 31, + KindNamespaceExportDeclaration: 32, + KindGetAccessor: 33, + KindSetAccessor: 34, + KindMethodDeclaration: 35, + KindNullKeyword: 36, + KindTrueKeyword: 36, + KindFalseKeyword: 36, + KindThisKeyword: 36, + KindSuperKeyword: 36, + KindImportKeyword: 36, + KindArrowFunction: 37, + KindFunctionExpression: 38, + KindPropertyAccessExpression: 39, + KindElementAccessExpression: 40, + KindMetaProperty: 41, + KindModuleDeclaration: 42, + KindImportEqualsDeclaration: 43, + KindExportDeclaration: 44, +} + +func (n *Node) FlowNodeData() *FlowNodeBase { + switch nodeFlowNodeDataDispatch[n.Kind] { + case 1: + return (*Identifier)(unsafe.Pointer(n)).FlowNodeData() + case 2: + return (*QualifiedName)(unsafe.Pointer(n)).FlowNodeData() + case 3: + return (*EmptyStatement)(unsafe.Pointer(n)).FlowNodeData() + case 4: + return (*IfStatement)(unsafe.Pointer(n)).FlowNodeData() + case 5: + return (*DoStatement)(unsafe.Pointer(n)).FlowNodeData() + case 6: + return (*WhileStatement)(unsafe.Pointer(n)).FlowNodeData() + case 7: + return (*ForStatement)(unsafe.Pointer(n)).FlowNodeData() + case 8: + return (*ForInOrOfStatement)(unsafe.Pointer(n)).FlowNodeData() + case 9: + return (*BreakStatement)(unsafe.Pointer(n)).FlowNodeData() + case 10: + return (*ContinueStatement)(unsafe.Pointer(n)).FlowNodeData() + case 11: + return (*ReturnStatement)(unsafe.Pointer(n)).FlowNodeData() + case 12: + return (*WithStatement)(unsafe.Pointer(n)).FlowNodeData() + case 13: + return (*SwitchStatement)(unsafe.Pointer(n)).FlowNodeData() + case 14: + return (*ThrowStatement)(unsafe.Pointer(n)).FlowNodeData() + case 15: + return (*TryStatement)(unsafe.Pointer(n)).FlowNodeData() + case 16: + return (*DebuggerStatement)(unsafe.Pointer(n)).FlowNodeData() + case 17: + return (*LabeledStatement)(unsafe.Pointer(n)).FlowNodeData() + case 18: + return (*ExpressionStatement)(unsafe.Pointer(n)).FlowNodeData() + case 19: + return (*Block)(unsafe.Pointer(n)).FlowNodeData() + case 20: + return (*VariableStatement)(unsafe.Pointer(n)).FlowNodeData() + case 21: + return (*BindingElement)(unsafe.Pointer(n)).FlowNodeData() + case 22: + return (*MissingDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 23: + return (*FunctionDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 24: + return (*ClassDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 25: + return (*InterfaceDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 26: + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 27: + return (*EnumDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 28: + return (*ModuleBlock)(unsafe.Pointer(n)).FlowNodeData() + case 29: + return (*NotEmittedStatement)(unsafe.Pointer(n)).FlowNodeData() + case 30: + return (*ImportDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 31: + return (*ExportAssignment)(unsafe.Pointer(n)).FlowNodeData() + case 32: + return (*NamespaceExportDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 33: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 34: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 35: + return (*MethodDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 36: + return (*KeywordExpression)(unsafe.Pointer(n)).FlowNodeData() + case 37: + return (*ArrowFunction)(unsafe.Pointer(n)).FlowNodeData() + case 38: + return (*FunctionExpression)(unsafe.Pointer(n)).FlowNodeData() + case 39: + return (*PropertyAccessExpression)(unsafe.Pointer(n)).FlowNodeData() + case 40: + return (*ElementAccessExpression)(unsafe.Pointer(n)).FlowNodeData() + case 41: + return (*MetaProperty)(unsafe.Pointer(n)).FlowNodeData() + case 42: + return (*ModuleDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 43: + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).FlowNodeData() + case 44: + return (*ExportDeclaration)(unsafe.Pointer(n)).FlowNodeData() + default: + return nil + } +} + +var nodeDeclarationDataDispatch = [kindFlowReduceLabelData + 1]uint8{ + KindVariableDeclaration: 1, + KindParameter: 2, + KindBindingElement: 3, + KindMissingDeclaration: 4, + KindFunctionDeclaration: 5, + KindClassDeclaration: 6, + KindClassExpression: 7, + KindInterfaceDeclaration: 8, + KindTypeAliasDeclaration: 9, + KindJSTypeAliasDeclaration: 9, + KindEnumMember: 10, + KindEnumDeclaration: 11, + KindNotEmittedTypeElement: 12, + KindImportDeclaration: 13, + KindJSImportDeclaration: 13, + KindNamespaceImport: 14, + KindExportAssignment: 15, + KindNamespaceExportDeclaration: 16, + KindNamespaceExport: 17, + KindExportSpecifier: 18, + KindCallSignature: 19, + KindConstructSignature: 20, + KindConstructor: 21, + KindGetAccessor: 22, + KindSetAccessor: 23, + KindIndexSignature: 24, + KindMethodSignature: 25, + KindMethodDeclaration: 26, + KindPropertySignature: 27, + KindPropertyDeclaration: 28, + KindSemicolonClassElement: 29, + KindClassStaticBlockDeclaration: 30, + KindNoSubstitutionTemplateLiteral: 31, + KindBinaryExpression: 32, + KindArrowFunction: 33, + KindFunctionExpression: 34, + KindCallExpression: 35, + KindObjectLiteralExpression: 36, + KindSpreadAssignment: 37, + KindPropertyAssignment: 38, + KindShorthandPropertyAssignment: 39, + KindMappedType: 40, + KindTypeLiteral: 41, + KindNamedTupleMember: 42, + KindFunctionType: 43, + KindConstructorType: 44, + KindJsxAttributes: 45, + KindJsxAttribute: 46, + KindJsxSpreadAttribute: 47, + KindJSDocSignature: 48, + KindSourceFile: 49, + KindModuleDeclaration: 50, + KindImportEqualsDeclaration: 51, + KindExportDeclaration: 52, + KindImportClause: 53, + KindImportSpecifier: 54, + KindTypeParameter: 55, + KindJSDocTypeLiteral: 56, +} + +func (n *Node) DeclarationData() *DeclarationBase { + switch nodeDeclarationDataDispatch[n.Kind] { + case 1: + return (*VariableDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 2: + return (*ParameterDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 3: + return (*BindingElement)(unsafe.Pointer(n)).DeclarationData() + case 4: + return (*MissingDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 5: + return (*FunctionDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 6: + return (*ClassDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 7: + return (*ClassExpression)(unsafe.Pointer(n)).DeclarationData() + case 8: + return (*InterfaceDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 9: + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 10: + return (*EnumMember)(unsafe.Pointer(n)).DeclarationData() + case 11: + return (*EnumDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 12: + return (*NotEmittedTypeElement)(unsafe.Pointer(n)).DeclarationData() + case 13: + return (*ImportDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 14: + return (*NamespaceImport)(unsafe.Pointer(n)).DeclarationData() + case 15: + return (*ExportAssignment)(unsafe.Pointer(n)).DeclarationData() + case 16: + return (*NamespaceExportDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 17: + return (*NamespaceExport)(unsafe.Pointer(n)).DeclarationData() + case 18: + return (*ExportSpecifier)(unsafe.Pointer(n)).DeclarationData() + case 19: + return (*CallSignatureDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 20: + return (*ConstructSignatureDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 21: + return (*ConstructorDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 22: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 23: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 24: + return (*IndexSignatureDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 25: + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 26: + return (*MethodDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 27: + return (*PropertySignatureDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 28: + return (*PropertyDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 29: + return (*SemicolonClassElement)(unsafe.Pointer(n)).DeclarationData() + case 30: + return (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 31: + return (*NoSubstitutionTemplateLiteral)(unsafe.Pointer(n)).DeclarationData() + case 32: + return (*BinaryExpression)(unsafe.Pointer(n)).DeclarationData() + case 33: + return (*ArrowFunction)(unsafe.Pointer(n)).DeclarationData() + case 34: + return (*FunctionExpression)(unsafe.Pointer(n)).DeclarationData() + case 35: + return (*CallExpression)(unsafe.Pointer(n)).DeclarationData() + case 36: + return (*ObjectLiteralExpression)(unsafe.Pointer(n)).DeclarationData() + case 37: + return (*SpreadAssignment)(unsafe.Pointer(n)).DeclarationData() + case 38: + return (*PropertyAssignment)(unsafe.Pointer(n)).DeclarationData() + case 39: + return (*ShorthandPropertyAssignment)(unsafe.Pointer(n)).DeclarationData() + case 40: + return (*MappedTypeNode)(unsafe.Pointer(n)).DeclarationData() + case 41: + return (*TypeLiteralNode)(unsafe.Pointer(n)).DeclarationData() + case 42: + return (*NamedTupleMember)(unsafe.Pointer(n)).DeclarationData() + case 43: + return (*FunctionTypeNode)(unsafe.Pointer(n)).DeclarationData() + case 44: + return (*ConstructorTypeNode)(unsafe.Pointer(n)).DeclarationData() + case 45: + return (*JsxAttributes)(unsafe.Pointer(n)).DeclarationData() + case 46: + return (*JsxAttribute)(unsafe.Pointer(n)).DeclarationData() + case 47: + return (*JsxSpreadAttribute)(unsafe.Pointer(n)).DeclarationData() + case 48: + return (*JSDocSignature)(unsafe.Pointer(n)).DeclarationData() + case 49: + return (*SourceFile)(unsafe.Pointer(n)).DeclarationData() + case 50: + return (*ModuleDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 51: + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 52: + return (*ExportDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 53: + return (*ImportClause)(unsafe.Pointer(n)).DeclarationData() + case 54: + return (*ImportSpecifier)(unsafe.Pointer(n)).DeclarationData() + case 55: + return (*TypeParameterDeclaration)(unsafe.Pointer(n)).DeclarationData() + case 56: + return (*JSDocTypeLiteral)(unsafe.Pointer(n)).DeclarationData() + default: + return nil + } +} + +var nodeExportableDataDispatch = [kindFlowReduceLabelData + 1]uint8{ + KindVariableDeclaration: 1, + KindBindingElement: 2, + KindFunctionDeclaration: 3, + KindClassDeclaration: 4, + KindClassExpression: 5, + KindInterfaceDeclaration: 6, + KindTypeAliasDeclaration: 7, + KindJSTypeAliasDeclaration: 7, + KindEnumDeclaration: 8, + KindNamespaceImport: 9, + KindExportSpecifier: 10, + KindModuleDeclaration: 11, + KindImportEqualsDeclaration: 12, + KindImportClause: 13, + KindImportSpecifier: 14, +} + +func (n *Node) ExportableData() *ExportableBase { + switch nodeExportableDataDispatch[n.Kind] { + case 1: + return (*VariableDeclaration)(unsafe.Pointer(n)).ExportableData() + case 2: + return (*BindingElement)(unsafe.Pointer(n)).ExportableData() + case 3: + return (*FunctionDeclaration)(unsafe.Pointer(n)).ExportableData() + case 4: + return (*ClassDeclaration)(unsafe.Pointer(n)).ExportableData() + case 5: + return (*ClassExpression)(unsafe.Pointer(n)).ExportableData() + case 6: + return (*InterfaceDeclaration)(unsafe.Pointer(n)).ExportableData() + case 7: + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).ExportableData() + case 8: + return (*EnumDeclaration)(unsafe.Pointer(n)).ExportableData() + case 9: + return (*NamespaceImport)(unsafe.Pointer(n)).ExportableData() + case 10: + return (*ExportSpecifier)(unsafe.Pointer(n)).ExportableData() + case 11: + return (*ModuleDeclaration)(unsafe.Pointer(n)).ExportableData() + case 12: + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).ExportableData() + case 13: + return (*ImportClause)(unsafe.Pointer(n)).ExportableData() + case 14: + return (*ImportSpecifier)(unsafe.Pointer(n)).ExportableData() + default: + return nil + } +} + +var nodeLocalsContainerDataDispatch = [kindFlowReduceLabelData + 1]uint8{ + KindForStatement: 1, + KindForInStatement: 2, + KindForOfStatement: 2, + KindCaseBlock: 3, + KindCatchClause: 4, + KindBlock: 5, + KindFunctionDeclaration: 6, + KindClassDeclaration: 7, + KindClassExpression: 8, + KindTypeAliasDeclaration: 9, + KindJSTypeAliasDeclaration: 9, + KindCallSignature: 10, + KindConstructSignature: 11, + KindConstructor: 12, + KindGetAccessor: 13, + KindSetAccessor: 14, + KindIndexSignature: 15, + KindMethodSignature: 16, + KindMethodDeclaration: 17, + KindClassStaticBlockDeclaration: 18, + KindArrowFunction: 19, + KindFunctionExpression: 20, + KindConditionalType: 21, + KindMappedType: 22, + KindFunctionType: 23, + KindConstructorType: 24, + KindJSDocSignature: 25, + KindSourceFile: 26, + KindModuleDeclaration: 27, +} + +func (n *Node) LocalsContainerData() *LocalsContainerBase { + switch nodeLocalsContainerDataDispatch[n.Kind] { + case 1: + return (*ForStatement)(unsafe.Pointer(n)).LocalsContainerData() + case 2: + return (*ForInOrOfStatement)(unsafe.Pointer(n)).LocalsContainerData() + case 3: + return (*CaseBlock)(unsafe.Pointer(n)).LocalsContainerData() + case 4: + return (*CatchClause)(unsafe.Pointer(n)).LocalsContainerData() + case 5: + return (*Block)(unsafe.Pointer(n)).LocalsContainerData() + case 6: + return (*FunctionDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 7: + return (*ClassDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 8: + return (*ClassExpression)(unsafe.Pointer(n)).LocalsContainerData() + case 9: + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 10: + return (*CallSignatureDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 11: + return (*ConstructSignatureDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 12: + return (*ConstructorDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 13: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 14: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 15: + return (*IndexSignatureDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 16: + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 17: + return (*MethodDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 18: + return (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + case 19: + return (*ArrowFunction)(unsafe.Pointer(n)).LocalsContainerData() + case 20: + return (*FunctionExpression)(unsafe.Pointer(n)).LocalsContainerData() + case 21: + return (*ConditionalTypeNode)(unsafe.Pointer(n)).LocalsContainerData() + case 22: + return (*MappedTypeNode)(unsafe.Pointer(n)).LocalsContainerData() + case 23: + return (*FunctionTypeNode)(unsafe.Pointer(n)).LocalsContainerData() + case 24: + return (*ConstructorTypeNode)(unsafe.Pointer(n)).LocalsContainerData() + case 25: + return (*JSDocSignature)(unsafe.Pointer(n)).LocalsContainerData() + case 26: + return (*SourceFile)(unsafe.Pointer(n)).LocalsContainerData() + case 27: + return (*ModuleDeclaration)(unsafe.Pointer(n)).LocalsContainerData() + default: + return nil + } +} + +var nodeFunctionLikeDataDispatch = [kindFlowReduceLabelData + 1]uint8{ + KindFunctionDeclaration: 1, + KindCallSignature: 2, + KindConstructSignature: 3, + KindConstructor: 4, + KindGetAccessor: 5, + KindSetAccessor: 6, + KindIndexSignature: 7, + KindMethodSignature: 8, + KindMethodDeclaration: 9, + KindArrowFunction: 10, + KindFunctionExpression: 11, + KindFunctionType: 12, + KindConstructorType: 13, + KindJSDocSignature: 14, +} + +func (n *Node) FunctionLikeData() *FunctionLikeBase { + switch nodeFunctionLikeDataDispatch[n.Kind] { + case 1: + return (*FunctionDeclaration)(unsafe.Pointer(n)).FunctionLikeData() + case 2: + return (*CallSignatureDeclaration)(unsafe.Pointer(n)).FunctionLikeData() + case 3: + return (*ConstructSignatureDeclaration)(unsafe.Pointer(n)).FunctionLikeData() + case 4: + return (*ConstructorDeclaration)(unsafe.Pointer(n)).FunctionLikeData() + case 5: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).FunctionLikeData() + case 6: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).FunctionLikeData() + case 7: + return (*IndexSignatureDeclaration)(unsafe.Pointer(n)).FunctionLikeData() + case 8: + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)).FunctionLikeData() + case 9: + return (*MethodDeclaration)(unsafe.Pointer(n)).FunctionLikeData() + case 10: + return (*ArrowFunction)(unsafe.Pointer(n)).FunctionLikeData() + case 11: + return (*FunctionExpression)(unsafe.Pointer(n)).FunctionLikeData() + case 12: + return (*FunctionTypeNode)(unsafe.Pointer(n)).FunctionLikeData() + case 13: + return (*ConstructorTypeNode)(unsafe.Pointer(n)).FunctionLikeData() + case 14: + return (*JSDocSignature)(unsafe.Pointer(n)).FunctionLikeData() + default: + return nil + } +} + +func (n *Node) ClassLikeData() *ClassLikeBase { + switch n.Kind { + case KindClassDeclaration: + return (*ClassDeclaration)(unsafe.Pointer(n)).ClassLikeData() + case KindClassExpression: + return (*ClassExpression)(unsafe.Pointer(n)).ClassLikeData() + default: + return nil + } +} + +var nodeBodyDataDispatch = [kindFlowReduceLabelData + 1]uint8{ + KindFunctionDeclaration: 1, + KindConstructor: 2, + KindGetAccessor: 3, + KindSetAccessor: 4, + KindMethodDeclaration: 5, + KindArrowFunction: 6, + KindFunctionExpression: 7, + KindModuleDeclaration: 8, +} + +func (n *Node) BodyData() *BodyBase { + switch nodeBodyDataDispatch[n.Kind] { + case 1: + return (*FunctionDeclaration)(unsafe.Pointer(n)).BodyData() + case 2: + return (*ConstructorDeclaration)(unsafe.Pointer(n)).BodyData() + case 3: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).BodyData() + case 4: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).BodyData() + case 5: + return (*MethodDeclaration)(unsafe.Pointer(n)).BodyData() + case 6: + return (*ArrowFunction)(unsafe.Pointer(n)).BodyData() + case 7: + return (*FunctionExpression)(unsafe.Pointer(n)).BodyData() + case 8: + return (*ModuleDeclaration)(unsafe.Pointer(n)).BodyData() + default: + return nil + } +} + +var nodeLiteralLikeDataDispatch = [kindFlowReduceLabelData + 1]uint8{ + KindStringLiteral: 1, + KindNumericLiteral: 2, + KindBigIntLiteral: 3, + KindRegularExpressionLiteral: 4, + KindNoSubstitutionTemplateLiteral: 5, + KindTemplateHead: 6, + KindTemplateMiddle: 7, + KindTemplateTail: 8, + KindJsxText: 9, +} + +func (n *Node) LiteralLikeData() *LiteralLikeNodeBase { + switch nodeLiteralLikeDataDispatch[n.Kind] { + case 1: + return (*StringLiteral)(unsafe.Pointer(n)).LiteralLikeData() + case 2: + return (*NumericLiteral)(unsafe.Pointer(n)).LiteralLikeData() + case 3: + return (*BigIntLiteral)(unsafe.Pointer(n)).LiteralLikeData() + case 4: + return (*RegularExpressionLiteral)(unsafe.Pointer(n)).LiteralLikeData() + case 5: + return (*NoSubstitutionTemplateLiteral)(unsafe.Pointer(n)).LiteralLikeData() + case 6: + return (*TemplateHead)(unsafe.Pointer(n)).LiteralLikeData() + case 7: + return (*TemplateMiddle)(unsafe.Pointer(n)).LiteralLikeData() + case 8: + return (*TemplateTail)(unsafe.Pointer(n)).LiteralLikeData() + case 9: + return (*JsxText)(unsafe.Pointer(n)).LiteralLikeData() + default: + return nil + } +} + +func (n *Node) TemplateLiteralLikeData() *TemplateLiteralLikeNodeBase { + switch n.Kind { + case KindNoSubstitutionTemplateLiteral: + return (*NoSubstitutionTemplateLiteral)(unsafe.Pointer(n)).TemplateLiteralLikeData() + case KindTemplateHead: + return (*TemplateHead)(unsafe.Pointer(n)).TemplateLiteralLikeData() + case KindTemplateMiddle: + return (*TemplateMiddle)(unsafe.Pointer(n)).TemplateLiteralLikeData() + case KindTemplateTail: + return (*TemplateTail)(unsafe.Pointer(n)).TemplateLiteralLikeData() + default: + return nil + } +} + +// ────────────────────────────────────────────────────────────────────── +// Common node accessor dispatch +// ────────────────────────────────────────────────────────────────────── + +var nodeNameDispatch = [kindFlowReduceLabelData + 1]uint8{ + KindVariableDeclaration: 1, + KindParameter: 2, + KindBindingElement: 3, + KindFunctionDeclaration: 4, + KindClassDeclaration: 5, + KindClassExpression: 6, + KindInterfaceDeclaration: 7, + KindTypeAliasDeclaration: 8, + KindJSTypeAliasDeclaration: 8, + KindEnumMember: 9, + KindEnumDeclaration: 10, + KindNamespaceImport: 11, + KindNamespaceExportDeclaration: 12, + KindNamespaceExport: 13, + KindExportSpecifier: 14, + KindGetAccessor: 15, + KindSetAccessor: 16, + KindMethodSignature: 17, + KindMethodDeclaration: 18, + KindPropertySignature: 19, + KindPropertyDeclaration: 20, + KindFunctionExpression: 21, + KindPropertyAccessExpression: 22, + KindMetaProperty: 23, + KindPropertyAssignment: 24, + KindShorthandPropertyAssignment: 25, + KindImportAttribute: 26, + KindNamedTupleMember: 27, + KindJsxNamespacedName: 28, + KindJsxAttribute: 29, + KindJSDocCallbackTag: 30, + KindJSDocTypedefTag: 31, + KindJSDocNameReference: 32, + KindModuleDeclaration: 33, + KindImportEqualsDeclaration: 34, + KindImportClause: 35, + KindImportSpecifier: 36, + KindJSDocLink: 37, + KindJSDocLinkPlain: 38, + KindJSDocLinkCode: 39, + KindTypeParameter: 40, + KindJSDocParameterTag: 41, + KindJSDocPropertyTag: 41, +} + +func (n *Node) Name() *DeclarationName { + switch nodeNameDispatch[n.Kind] { + case 1: + return (*VariableDeclaration)(unsafe.Pointer(n)).Name() + case 2: + return (*ParameterDeclaration)(unsafe.Pointer(n)).Name() + case 3: + return (*BindingElement)(unsafe.Pointer(n)).Name() + case 4: + return (*FunctionDeclaration)(unsafe.Pointer(n)).Name() + case 5: + return (*ClassDeclaration)(unsafe.Pointer(n)).Name() + case 6: + return (*ClassExpression)(unsafe.Pointer(n)).Name() + case 7: + return (*InterfaceDeclaration)(unsafe.Pointer(n)).Name() + case 8: + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).Name() + case 9: + return (*EnumMember)(unsafe.Pointer(n)).Name() + case 10: + return (*EnumDeclaration)(unsafe.Pointer(n)).Name() + case 11: + return (*NamespaceImport)(unsafe.Pointer(n)).Name() + case 12: + return (*NamespaceExportDeclaration)(unsafe.Pointer(n)).Name() + case 13: + return (*NamespaceExport)(unsafe.Pointer(n)).Name() + case 14: + return (*ExportSpecifier)(unsafe.Pointer(n)).Name() + case 15: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).Name() + case 16: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).Name() + case 17: + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)).Name() + case 18: + return (*MethodDeclaration)(unsafe.Pointer(n)).Name() + case 19: + return (*PropertySignatureDeclaration)(unsafe.Pointer(n)).Name() + case 20: + return (*PropertyDeclaration)(unsafe.Pointer(n)).Name() + case 21: + return (*FunctionExpression)(unsafe.Pointer(n)).Name() + case 22: + return (*PropertyAccessExpression)(unsafe.Pointer(n)).Name() + case 23: + return (*MetaProperty)(unsafe.Pointer(n)).Name() + case 24: + return (*PropertyAssignment)(unsafe.Pointer(n)).Name() + case 25: + return (*ShorthandPropertyAssignment)(unsafe.Pointer(n)).Name() + case 26: + return (*ImportAttribute)(unsafe.Pointer(n)).Name() + case 27: + return (*NamedTupleMember)(unsafe.Pointer(n)).Name() + case 28: + return (*JsxNamespacedName)(unsafe.Pointer(n)).Name() + case 29: + return (*JsxAttribute)(unsafe.Pointer(n)).Name() + case 30: + return (*JSDocCallbackTag)(unsafe.Pointer(n)).Name() + case 31: + return (*JSDocTypedefTag)(unsafe.Pointer(n)).Name() + case 32: + return (*JSDocNameReference)(unsafe.Pointer(n)).Name() + case 33: + return (*ModuleDeclaration)(unsafe.Pointer(n)).Name() + case 34: + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).Name() + case 35: + return (*ImportClause)(unsafe.Pointer(n)).Name() + case 36: + return (*ImportSpecifier)(unsafe.Pointer(n)).Name() + case 37: + return (*JSDocLink)(unsafe.Pointer(n)).Name() + case 38: + return (*JSDocLinkPlain)(unsafe.Pointer(n)).Name() + case 39: + return (*JSDocLinkCode)(unsafe.Pointer(n)).Name() + case 40: + return (*TypeParameterDeclaration)(unsafe.Pointer(n)).Name() + case 41: + return (*JSDocParameterOrPropertyTag)(unsafe.Pointer(n)).Name() + default: + return nil + } +} + +var nodeModifiersDispatch = [kindFlowReduceLabelData + 1]uint8{ + KindVariableStatement: 1, + KindParameter: 2, + KindMissingDeclaration: 3, + KindFunctionDeclaration: 4, + KindClassDeclaration: 5, + KindClassExpression: 6, + KindInterfaceDeclaration: 7, + KindTypeAliasDeclaration: 8, + KindJSTypeAliasDeclaration: 8, + KindEnumDeclaration: 9, + KindImportDeclaration: 10, + KindJSImportDeclaration: 10, + KindExportAssignment: 11, + KindNamespaceExportDeclaration: 12, + KindConstructor: 13, + KindGetAccessor: 14, + KindSetAccessor: 15, + KindIndexSignature: 16, + KindMethodSignature: 17, + KindMethodDeclaration: 18, + KindPropertySignature: 19, + KindPropertyDeclaration: 20, + KindClassStaticBlockDeclaration: 21, + KindBinaryExpression: 22, + KindArrowFunction: 23, + KindFunctionExpression: 24, + KindPropertyAssignment: 25, + KindShorthandPropertyAssignment: 26, + KindConstructorType: 27, + KindModuleDeclaration: 28, + KindImportEqualsDeclaration: 29, + KindExportDeclaration: 30, + KindTypeParameter: 31, +} + +func (n *Node) Modifiers() *ModifierList { + switch nodeModifiersDispatch[n.Kind] { + case 1: + return (*VariableStatement)(unsafe.Pointer(n)).Modifiers() + case 2: + return (*ParameterDeclaration)(unsafe.Pointer(n)).Modifiers() + case 3: + return (*MissingDeclaration)(unsafe.Pointer(n)).Modifiers() + case 4: + return (*FunctionDeclaration)(unsafe.Pointer(n)).Modifiers() + case 5: + return (*ClassDeclaration)(unsafe.Pointer(n)).Modifiers() + case 6: + return (*ClassExpression)(unsafe.Pointer(n)).Modifiers() + case 7: + return (*InterfaceDeclaration)(unsafe.Pointer(n)).Modifiers() + case 8: + return (*TypeAliasDeclaration)(unsafe.Pointer(n)).Modifiers() + case 9: + return (*EnumDeclaration)(unsafe.Pointer(n)).Modifiers() + case 10: + return (*ImportDeclaration)(unsafe.Pointer(n)).Modifiers() + case 11: + return (*ExportAssignment)(unsafe.Pointer(n)).Modifiers() + case 12: + return (*NamespaceExportDeclaration)(unsafe.Pointer(n)).Modifiers() + case 13: + return (*ConstructorDeclaration)(unsafe.Pointer(n)).Modifiers() + case 14: + return (*GetAccessorDeclaration)(unsafe.Pointer(n)).Modifiers() + case 15: + return (*SetAccessorDeclaration)(unsafe.Pointer(n)).Modifiers() + case 16: + return (*IndexSignatureDeclaration)(unsafe.Pointer(n)).Modifiers() + case 17: + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)).Modifiers() + case 18: + return (*MethodDeclaration)(unsafe.Pointer(n)).Modifiers() + case 19: + return (*PropertySignatureDeclaration)(unsafe.Pointer(n)).Modifiers() + case 20: + return (*PropertyDeclaration)(unsafe.Pointer(n)).Modifiers() + case 21: + return (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)).Modifiers() + case 22: + return (*BinaryExpression)(unsafe.Pointer(n)).Modifiers() + case 23: + return (*ArrowFunction)(unsafe.Pointer(n)).Modifiers() + case 24: + return (*FunctionExpression)(unsafe.Pointer(n)).Modifiers() + case 25: + return (*PropertyAssignment)(unsafe.Pointer(n)).Modifiers() + case 26: + return (*ShorthandPropertyAssignment)(unsafe.Pointer(n)).Modifiers() + case 27: + return (*ConstructorTypeNode)(unsafe.Pointer(n)).Modifiers() + case 28: + return (*ModuleDeclaration)(unsafe.Pointer(n)).Modifiers() + case 29: + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)).Modifiers() + case 30: + return (*ExportDeclaration)(unsafe.Pointer(n)).Modifiers() + case 31: + return (*TypeParameterDeclaration)(unsafe.Pointer(n)).Modifiers() + default: + return nil + } +} + +func (n *MutableNode) SetModifiers(modifiers *ModifierList) { + switch n.Kind { + case KindVariableStatement: + (*VariableStatement)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindParameter: + (*ParameterDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindMissingDeclaration: + (*MissingDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindFunctionDeclaration: + (*FunctionDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindClassDeclaration: + (*ClassDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindClassExpression: + (*ClassExpression)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindInterfaceDeclaration: + (*InterfaceDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + (*TypeAliasDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindEnumDeclaration: + (*EnumDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindImportDeclaration, KindJSImportDeclaration: + (*ImportDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindExportAssignment: + (*ExportAssignment)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindNamespaceExportDeclaration: + (*NamespaceExportDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindConstructor: + (*ConstructorDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindGetAccessor: + (*GetAccessorDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindSetAccessor: + (*SetAccessorDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindIndexSignature: + (*IndexSignatureDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindMethodSignature: + (*MethodSignatureDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindMethodDeclaration: + (*MethodDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindPropertySignature: + (*PropertySignatureDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindPropertyDeclaration: + (*PropertyDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindClassStaticBlockDeclaration: + (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindBinaryExpression: + (*BinaryExpression)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindArrowFunction: + (*ArrowFunction)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindFunctionExpression: + (*FunctionExpression)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindPropertyAssignment: + (*PropertyAssignment)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindShorthandPropertyAssignment: + (*ShorthandPropertyAssignment)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindConstructorType: + (*ConstructorTypeNode)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindModuleDeclaration: + (*ModuleDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindImportEqualsDeclaration: + (*ImportEqualsDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindExportDeclaration: + (*ExportDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + case KindTypeParameter: + (*TypeParameterDeclaration)(unsafe.Pointer(n)).setModifiers(modifiers) + } +} + +// ────────────────────────────────────────────────────────────────────── +// As*() cast methods +// ────────────────────────────────────────────────────────────────────── + +// Every concrete node embeds its header at offset zero. +var ( + _ [0 - unsafe.Offsetof(Token{}.Node)]byte + _ [0 - unsafe.Offsetof(Identifier{}.Node)]byte + _ [0 - unsafe.Offsetof(PrivateIdentifier{}.Node)]byte + _ [0 - unsafe.Offsetof(QualifiedName{}.Node)]byte + _ [0 - unsafe.Offsetof(ComputedPropertyName{}.Node)]byte + _ [0 - unsafe.Offsetof(Decorator{}.Node)]byte + _ [0 - unsafe.Offsetof(EmptyStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(IfStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(DoStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(WhileStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(ForStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(ForInOrOfStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(BreakStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(ContinueStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(ReturnStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(WithStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(SwitchStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(CaseBlock{}.Node)]byte + _ [0 - unsafe.Offsetof(CaseOrDefaultClause{}.Node)]byte + _ [0 - unsafe.Offsetof(ThrowStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(TryStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(CatchClause{}.Node)]byte + _ [0 - unsafe.Offsetof(DebuggerStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(LabeledStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(ExpressionStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(Block{}.Node)]byte + _ [0 - unsafe.Offsetof(VariableStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(VariableDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(VariableDeclarationList{}.Node)]byte + _ [0 - unsafe.Offsetof(BindingPattern{}.Node)]byte + _ [0 - unsafe.Offsetof(ParameterDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(BindingElement{}.Node)]byte + _ [0 - unsafe.Offsetof(MissingDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(FunctionDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(ClassDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(ClassExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(HeritageClause{}.Node)]byte + _ [0 - unsafe.Offsetof(InterfaceDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(TypeAliasDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(EnumMember{}.Node)]byte + _ [0 - unsafe.Offsetof(EnumDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(ModuleBlock{}.Node)]byte + _ [0 - unsafe.Offsetof(NotEmittedStatement{}.Node)]byte + _ [0 - unsafe.Offsetof(NotEmittedTypeElement{}.Node)]byte + _ [0 - unsafe.Offsetof(ImportDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(ExternalModuleReference{}.Node)]byte + _ [0 - unsafe.Offsetof(NamespaceImport{}.Node)]byte + _ [0 - unsafe.Offsetof(NamedImports{}.Node)]byte + _ [0 - unsafe.Offsetof(ExportAssignment{}.Node)]byte + _ [0 - unsafe.Offsetof(NamespaceExportDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(NamespaceExport{}.Node)]byte + _ [0 - unsafe.Offsetof(NamedExports{}.Node)]byte + _ [0 - unsafe.Offsetof(ExportSpecifier{}.Node)]byte + _ [0 - unsafe.Offsetof(CallSignatureDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(ConstructSignatureDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(ConstructorDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(GetAccessorDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(SetAccessorDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(IndexSignatureDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(MethodSignatureDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(MethodDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(PropertySignatureDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(PropertyDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(SemicolonClassElement{}.Node)]byte + _ [0 - unsafe.Offsetof(ClassStaticBlockDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(OmittedExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(KeywordExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(StringLiteral{}.Node)]byte + _ [0 - unsafe.Offsetof(NumericLiteral{}.Node)]byte + _ [0 - unsafe.Offsetof(BigIntLiteral{}.Node)]byte + _ [0 - unsafe.Offsetof(RegularExpressionLiteral{}.Node)]byte + _ [0 - unsafe.Offsetof(NoSubstitutionTemplateLiteral{}.Node)]byte + _ [0 - unsafe.Offsetof(BinaryExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(PrefixUnaryExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(PostfixUnaryExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(YieldExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(ArrowFunction{}.Node)]byte + _ [0 - unsafe.Offsetof(FunctionExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(AsExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(SatisfiesExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(ConditionalExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(PropertyAccessExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(ElementAccessExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(CallExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(NewExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(MetaProperty{}.Node)]byte + _ [0 - unsafe.Offsetof(NonNullExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(SpreadElement{}.Node)]byte + _ [0 - unsafe.Offsetof(TemplateExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(TemplateSpan{}.Node)]byte + _ [0 - unsafe.Offsetof(TaggedTemplateExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(ParenthesizedExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(ArrayLiteralExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(ObjectLiteralExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(SpreadAssignment{}.Node)]byte + _ [0 - unsafe.Offsetof(PropertyAssignment{}.Node)]byte + _ [0 - unsafe.Offsetof(ShorthandPropertyAssignment{}.Node)]byte + _ [0 - unsafe.Offsetof(DeleteExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(TypeOfExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(VoidExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(AwaitExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(TypeAssertion{}.Node)]byte + _ [0 - unsafe.Offsetof(KeywordTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(UnionTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(IntersectionTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(ConditionalTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(TypeOperatorNode{}.Node)]byte + _ [0 - unsafe.Offsetof(InferTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(ArrayTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(IndexedAccessTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(TypeReferenceNode{}.Node)]byte + _ [0 - unsafe.Offsetof(ExpressionWithTypeArguments{}.Node)]byte + _ [0 - unsafe.Offsetof(LiteralTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(ThisTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(TypePredicateNode{}.Node)]byte + _ [0 - unsafe.Offsetof(ImportAttribute{}.Node)]byte + _ [0 - unsafe.Offsetof(ImportAttributes{}.Node)]byte + _ [0 - unsafe.Offsetof(TypeQueryNode{}.Node)]byte + _ [0 - unsafe.Offsetof(MappedTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(TypeLiteralNode{}.Node)]byte + _ [0 - unsafe.Offsetof(TupleTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(NamedTupleMember{}.Node)]byte + _ [0 - unsafe.Offsetof(OptionalTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(RestTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(ParenthesizedTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(FunctionTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(ConstructorTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(TemplateHead{}.Node)]byte + _ [0 - unsafe.Offsetof(TemplateMiddle{}.Node)]byte + _ [0 - unsafe.Offsetof(TemplateTail{}.Node)]byte + _ [0 - unsafe.Offsetof(TemplateLiteralTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(TemplateLiteralTypeSpan{}.Node)]byte + _ [0 - unsafe.Offsetof(SyntheticExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(PartiallyEmittedExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxElement{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxAttributes{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxNamespacedName{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxOpeningElement{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxSelfClosingElement{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxFragment{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxOpeningFragment{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxClosingFragment{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxAttribute{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxSpreadAttribute{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxClosingElement{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(JsxText{}.Node)]byte + _ [0 - unsafe.Offsetof(SyntaxList{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDoc{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocTypeExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocNonNullableType{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocNullableType{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocAllType{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocVariadicType{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocOptionalType{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocTypeTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocUnknownTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocTemplateTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocReturnTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocPublicTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocPrivateTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocProtectedTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocReadonlyTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocOverrideTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocDeprecatedTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocSeeTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocImplementsTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocAugmentsTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocSatisfiesTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocThrowsTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocThisTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocImportTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocCallbackTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocOverloadTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocTypedefTag{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocSignature{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocNameReference{}.Node)]byte + _ [0 - unsafe.Offsetof(SourceFile{}.Node)]byte + _ [0 - unsafe.Offsetof(ModuleDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(ImportEqualsDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(ExportDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(ImportTypeNode{}.Node)]byte + _ [0 - unsafe.Offsetof(ImportClause{}.Node)]byte + _ [0 - unsafe.Offsetof(ImportSpecifier{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocText{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocLink{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocLinkPlain{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocLinkCode{}.Node)]byte + _ [0 - unsafe.Offsetof(TypeParameterDeclaration{}.Node)]byte + _ [0 - unsafe.Offsetof(SyntheticReferenceExpression{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocTypeLiteral{}.Node)]byte + _ [0 - unsafe.Offsetof(JSDocParameterOrPropertyTag{}.Node)]byte +) + +func (n *Node) AsToken() *Token { + switch n.Kind { + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + default: + panic("Invalid node cast to Token") + } + return (*Token)(unsafe.Pointer(n)) +} + +func (n *Node) AsIdentifier() *Identifier { + if n.Kind != KindIdentifier { + panic("Invalid node cast to Identifier") + } + return (*Identifier)(unsafe.Pointer(n)) +} + +func (n *Node) AsPrivateIdentifier() *PrivateIdentifier { + if n.Kind != KindPrivateIdentifier { + panic("Invalid node cast to PrivateIdentifier") + } + return (*PrivateIdentifier)(unsafe.Pointer(n)) +} + +func (n *Node) AsQualifiedName() *QualifiedName { + if n.Kind != KindQualifiedName { + panic("Invalid node cast to QualifiedName") + } + return (*QualifiedName)(unsafe.Pointer(n)) +} + +func (n *Node) AsComputedPropertyName() *ComputedPropertyName { + if n.Kind != KindComputedPropertyName { + panic("Invalid node cast to ComputedPropertyName") + } + return (*ComputedPropertyName)(unsafe.Pointer(n)) +} + +func (n *Node) AsDecorator() *Decorator { + if n.Kind != KindDecorator { + panic("Invalid node cast to Decorator") + } + return (*Decorator)(unsafe.Pointer(n)) +} + +func (n *Node) AsEmptyStatement() *EmptyStatement { + if n.Kind != KindEmptyStatement { + panic("Invalid node cast to EmptyStatement") + } + return (*EmptyStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsIfStatement() *IfStatement { + if n.Kind != KindIfStatement { + panic("Invalid node cast to IfStatement") + } + return (*IfStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsDoStatement() *DoStatement { + if n.Kind != KindDoStatement { + panic("Invalid node cast to DoStatement") + } + return (*DoStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsWhileStatement() *WhileStatement { + if n.Kind != KindWhileStatement { + panic("Invalid node cast to WhileStatement") + } + return (*WhileStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsForStatement() *ForStatement { + if n.Kind != KindForStatement { + panic("Invalid node cast to ForStatement") + } + return (*ForStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsForInOrOfStatement() *ForInOrOfStatement { + switch n.Kind { + case KindForInStatement, KindForOfStatement: + default: + panic("Invalid node cast to ForInOrOfStatement") + } + return (*ForInOrOfStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsBreakStatement() *BreakStatement { + if n.Kind != KindBreakStatement { + panic("Invalid node cast to BreakStatement") + } + return (*BreakStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsContinueStatement() *ContinueStatement { + if n.Kind != KindContinueStatement { + panic("Invalid node cast to ContinueStatement") + } + return (*ContinueStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsReturnStatement() *ReturnStatement { + if n.Kind != KindReturnStatement { + panic("Invalid node cast to ReturnStatement") + } + return (*ReturnStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsWithStatement() *WithStatement { + if n.Kind != KindWithStatement { + panic("Invalid node cast to WithStatement") + } + return (*WithStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsSwitchStatement() *SwitchStatement { + if n.Kind != KindSwitchStatement { + panic("Invalid node cast to SwitchStatement") + } + return (*SwitchStatement)(unsafe.Pointer(n)) +} + +func (n *Node) AsCaseBlock() *CaseBlock { + if n.Kind != KindCaseBlock { + panic("Invalid node cast to CaseBlock") + } + return (*CaseBlock)(unsafe.Pointer(n)) +} + +func (n *Node) AsCaseOrDefaultClause() *CaseOrDefaultClause { + switch n.Kind { + case KindCaseClause, KindDefaultClause: + default: + panic("Invalid node cast to CaseOrDefaultClause") + } + return (*CaseOrDefaultClause)(unsafe.Pointer(n)) +} + +func (n *Node) AsThrowStatement() *ThrowStatement { + if n.Kind != KindThrowStatement { + panic("Invalid node cast to ThrowStatement") + } + return (*ThrowStatement)(unsafe.Pointer(n)) +} func (n *Node) AsTryStatement() *TryStatement { - return n.data.(*TryStatement) + if n.Kind != KindTryStatement { + panic("Invalid node cast to TryStatement") + } + return (*TryStatement)(unsafe.Pointer(n)) } func (n *Node) AsCatchClause() *CatchClause { - return n.data.(*CatchClause) + if n.Kind != KindCatchClause { + panic("Invalid node cast to CatchClause") + } + return (*CatchClause)(unsafe.Pointer(n)) } func (n *Node) AsDebuggerStatement() *DebuggerStatement { - return n.data.(*DebuggerStatement) + if n.Kind != KindDebuggerStatement { + panic("Invalid node cast to DebuggerStatement") + } + return (*DebuggerStatement)(unsafe.Pointer(n)) } func (n *Node) AsLabeledStatement() *LabeledStatement { - return n.data.(*LabeledStatement) + if n.Kind != KindLabeledStatement { + panic("Invalid node cast to LabeledStatement") + } + return (*LabeledStatement)(unsafe.Pointer(n)) } func (n *Node) AsExpressionStatement() *ExpressionStatement { - return n.data.(*ExpressionStatement) + if n.Kind != KindExpressionStatement { + panic("Invalid node cast to ExpressionStatement") + } + return (*ExpressionStatement)(unsafe.Pointer(n)) } func (n *Node) AsBlock() *Block { - return n.data.(*Block) + if n.Kind != KindBlock { + panic("Invalid node cast to Block") + } + return (*Block)(unsafe.Pointer(n)) } func (n *Node) AsVariableStatement() *VariableStatement { - return n.data.(*VariableStatement) + if n.Kind != KindVariableStatement { + panic("Invalid node cast to VariableStatement") + } + return (*VariableStatement)(unsafe.Pointer(n)) } func (n *Node) AsVariableDeclaration() *VariableDeclaration { - return n.data.(*VariableDeclaration) + if n.Kind != KindVariableDeclaration { + panic("Invalid node cast to VariableDeclaration") + } + return (*VariableDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsVariableDeclarationList() *VariableDeclarationList { - return n.data.(*VariableDeclarationList) + if n.Kind != KindVariableDeclarationList { + panic("Invalid node cast to VariableDeclarationList") + } + return (*VariableDeclarationList)(unsafe.Pointer(n)) } func (n *Node) AsBindingPattern() *BindingPattern { - return n.data.(*BindingPattern) + switch n.Kind { + case KindObjectBindingPattern, KindArrayBindingPattern: + default: + panic("Invalid node cast to BindingPattern") + } + return (*BindingPattern)(unsafe.Pointer(n)) } func (n *Node) AsParameterDeclaration() *ParameterDeclaration { - return n.data.(*ParameterDeclaration) + if n.Kind != KindParameter { + panic("Invalid node cast to ParameterDeclaration") + } + return (*ParameterDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsBindingElement() *BindingElement { - return n.data.(*BindingElement) + if n.Kind != KindBindingElement { + panic("Invalid node cast to BindingElement") + } + return (*BindingElement)(unsafe.Pointer(n)) } func (n *Node) AsMissingDeclaration() *MissingDeclaration { - return n.data.(*MissingDeclaration) + if n.Kind != KindMissingDeclaration { + panic("Invalid node cast to MissingDeclaration") + } + return (*MissingDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsFunctionDeclaration() *FunctionDeclaration { - return n.data.(*FunctionDeclaration) + if n.Kind != KindFunctionDeclaration { + panic("Invalid node cast to FunctionDeclaration") + } + return (*FunctionDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsClassDeclaration() *ClassDeclaration { - return n.data.(*ClassDeclaration) + if n.Kind != KindClassDeclaration { + panic("Invalid node cast to ClassDeclaration") + } + return (*ClassDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsClassExpression() *ClassExpression { - return n.data.(*ClassExpression) + if n.Kind != KindClassExpression { + panic("Invalid node cast to ClassExpression") + } + return (*ClassExpression)(unsafe.Pointer(n)) } func (n *Node) AsHeritageClause() *HeritageClause { - return n.data.(*HeritageClause) + if n.Kind != KindHeritageClause { + panic("Invalid node cast to HeritageClause") + } + return (*HeritageClause)(unsafe.Pointer(n)) } func (n *Node) AsInterfaceDeclaration() *InterfaceDeclaration { - return n.data.(*InterfaceDeclaration) + if n.Kind != KindInterfaceDeclaration { + panic("Invalid node cast to InterfaceDeclaration") + } + return (*InterfaceDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsTypeAliasDeclaration() *TypeAliasDeclaration { - return n.data.(*TypeAliasDeclaration) + switch n.Kind { + case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + default: + panic("Invalid node cast to TypeAliasDeclaration") + } + return (*TypeAliasDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsEnumMember() *EnumMember { - return n.data.(*EnumMember) + if n.Kind != KindEnumMember { + panic("Invalid node cast to EnumMember") + } + return (*EnumMember)(unsafe.Pointer(n)) } func (n *Node) AsEnumDeclaration() *EnumDeclaration { - return n.data.(*EnumDeclaration) + if n.Kind != KindEnumDeclaration { + panic("Invalid node cast to EnumDeclaration") + } + return (*EnumDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsModuleBlock() *ModuleBlock { - return n.data.(*ModuleBlock) + if n.Kind != KindModuleBlock { + panic("Invalid node cast to ModuleBlock") + } + return (*ModuleBlock)(unsafe.Pointer(n)) } func (n *Node) AsNotEmittedStatement() *NotEmittedStatement { - return n.data.(*NotEmittedStatement) + if n.Kind != KindNotEmittedStatement { + panic("Invalid node cast to NotEmittedStatement") + } + return (*NotEmittedStatement)(unsafe.Pointer(n)) } func (n *Node) AsNotEmittedTypeElement() *NotEmittedTypeElement { - return n.data.(*NotEmittedTypeElement) + if n.Kind != KindNotEmittedTypeElement { + panic("Invalid node cast to NotEmittedTypeElement") + } + return (*NotEmittedTypeElement)(unsafe.Pointer(n)) } func (n *Node) AsImportDeclaration() *ImportDeclaration { - return n.data.(*ImportDeclaration) + switch n.Kind { + case KindImportDeclaration, KindJSImportDeclaration: + default: + panic("Invalid node cast to ImportDeclaration") + } + return (*ImportDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsExternalModuleReference() *ExternalModuleReference { - return n.data.(*ExternalModuleReference) + if n.Kind != KindExternalModuleReference { + panic("Invalid node cast to ExternalModuleReference") + } + return (*ExternalModuleReference)(unsafe.Pointer(n)) } func (n *Node) AsNamespaceImport() *NamespaceImport { - return n.data.(*NamespaceImport) + if n.Kind != KindNamespaceImport { + panic("Invalid node cast to NamespaceImport") + } + return (*NamespaceImport)(unsafe.Pointer(n)) } func (n *Node) AsNamedImports() *NamedImports { - return n.data.(*NamedImports) + if n.Kind != KindNamedImports { + panic("Invalid node cast to NamedImports") + } + return (*NamedImports)(unsafe.Pointer(n)) } func (n *Node) AsExportAssignment() *ExportAssignment { - return n.data.(*ExportAssignment) + if n.Kind != KindExportAssignment { + panic("Invalid node cast to ExportAssignment") + } + return (*ExportAssignment)(unsafe.Pointer(n)) } func (n *Node) AsNamespaceExportDeclaration() *NamespaceExportDeclaration { - return n.data.(*NamespaceExportDeclaration) + if n.Kind != KindNamespaceExportDeclaration { + panic("Invalid node cast to NamespaceExportDeclaration") + } + return (*NamespaceExportDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsNamespaceExport() *NamespaceExport { - return n.data.(*NamespaceExport) + if n.Kind != KindNamespaceExport { + panic("Invalid node cast to NamespaceExport") + } + return (*NamespaceExport)(unsafe.Pointer(n)) } func (n *Node) AsNamedExports() *NamedExports { - return n.data.(*NamedExports) + if n.Kind != KindNamedExports { + panic("Invalid node cast to NamedExports") + } + return (*NamedExports)(unsafe.Pointer(n)) } func (n *Node) AsExportSpecifier() *ExportSpecifier { - return n.data.(*ExportSpecifier) + if n.Kind != KindExportSpecifier { + panic("Invalid node cast to ExportSpecifier") + } + return (*ExportSpecifier)(unsafe.Pointer(n)) } func (n *Node) AsCallSignatureDeclaration() *CallSignatureDeclaration { - return n.data.(*CallSignatureDeclaration) + if n.Kind != KindCallSignature { + panic("Invalid node cast to CallSignatureDeclaration") + } + return (*CallSignatureDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsConstructSignatureDeclaration() *ConstructSignatureDeclaration { - return n.data.(*ConstructSignatureDeclaration) + if n.Kind != KindConstructSignature { + panic("Invalid node cast to ConstructSignatureDeclaration") + } + return (*ConstructSignatureDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsConstructorDeclaration() *ConstructorDeclaration { - return n.data.(*ConstructorDeclaration) + if n.Kind != KindConstructor { + panic("Invalid node cast to ConstructorDeclaration") + } + return (*ConstructorDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsGetAccessorDeclaration() *GetAccessorDeclaration { - return n.data.(*GetAccessorDeclaration) + if n.Kind != KindGetAccessor { + panic("Invalid node cast to GetAccessorDeclaration") + } + return (*GetAccessorDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsSetAccessorDeclaration() *SetAccessorDeclaration { - return n.data.(*SetAccessorDeclaration) + if n.Kind != KindSetAccessor { + panic("Invalid node cast to SetAccessorDeclaration") + } + return (*SetAccessorDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsIndexSignatureDeclaration() *IndexSignatureDeclaration { - return n.data.(*IndexSignatureDeclaration) + if n.Kind != KindIndexSignature { + panic("Invalid node cast to IndexSignatureDeclaration") + } + return (*IndexSignatureDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsMethodSignatureDeclaration() *MethodSignatureDeclaration { - return n.data.(*MethodSignatureDeclaration) + if n.Kind != KindMethodSignature { + panic("Invalid node cast to MethodSignatureDeclaration") + } + return (*MethodSignatureDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsMethodDeclaration() *MethodDeclaration { - return n.data.(*MethodDeclaration) + if n.Kind != KindMethodDeclaration { + panic("Invalid node cast to MethodDeclaration") + } + return (*MethodDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsPropertySignatureDeclaration() *PropertySignatureDeclaration { - return n.data.(*PropertySignatureDeclaration) + if n.Kind != KindPropertySignature { + panic("Invalid node cast to PropertySignatureDeclaration") + } + return (*PropertySignatureDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsPropertyDeclaration() *PropertyDeclaration { - return n.data.(*PropertyDeclaration) + if n.Kind != KindPropertyDeclaration { + panic("Invalid node cast to PropertyDeclaration") + } + return (*PropertyDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsSemicolonClassElement() *SemicolonClassElement { - return n.data.(*SemicolonClassElement) + if n.Kind != KindSemicolonClassElement { + panic("Invalid node cast to SemicolonClassElement") + } + return (*SemicolonClassElement)(unsafe.Pointer(n)) } func (n *Node) AsClassStaticBlockDeclaration() *ClassStaticBlockDeclaration { - return n.data.(*ClassStaticBlockDeclaration) + if n.Kind != KindClassStaticBlockDeclaration { + panic("Invalid node cast to ClassStaticBlockDeclaration") + } + return (*ClassStaticBlockDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsOmittedExpression() *OmittedExpression { - return n.data.(*OmittedExpression) + if n.Kind != KindOmittedExpression { + panic("Invalid node cast to OmittedExpression") + } + return (*OmittedExpression)(unsafe.Pointer(n)) } func (n *Node) AsKeywordExpression() *KeywordExpression { - return n.data.(*KeywordExpression) + switch n.Kind { + case KindFalseKeyword, KindImportKeyword, KindNullKeyword, KindSuperKeyword, KindThisKeyword, KindTrueKeyword: + default: + panic("Invalid node cast to KeywordExpression") + } + return (*KeywordExpression)(unsafe.Pointer(n)) } func (n *Node) AsStringLiteral() *StringLiteral { - return n.data.(*StringLiteral) + if n.Kind != KindStringLiteral { + panic("Invalid node cast to StringLiteral") + } + return (*StringLiteral)(unsafe.Pointer(n)) } func (n *Node) AsNumericLiteral() *NumericLiteral { - return n.data.(*NumericLiteral) + if n.Kind != KindNumericLiteral { + panic("Invalid node cast to NumericLiteral") + } + return (*NumericLiteral)(unsafe.Pointer(n)) } func (n *Node) AsBigIntLiteral() *BigIntLiteral { - return n.data.(*BigIntLiteral) + if n.Kind != KindBigIntLiteral { + panic("Invalid node cast to BigIntLiteral") + } + return (*BigIntLiteral)(unsafe.Pointer(n)) } func (n *Node) AsRegularExpressionLiteral() *RegularExpressionLiteral { - return n.data.(*RegularExpressionLiteral) + if n.Kind != KindRegularExpressionLiteral { + panic("Invalid node cast to RegularExpressionLiteral") + } + return (*RegularExpressionLiteral)(unsafe.Pointer(n)) } func (n *Node) AsNoSubstitutionTemplateLiteral() *NoSubstitutionTemplateLiteral { - return n.data.(*NoSubstitutionTemplateLiteral) + if n.Kind != KindNoSubstitutionTemplateLiteral { + panic("Invalid node cast to NoSubstitutionTemplateLiteral") + } + return (*NoSubstitutionTemplateLiteral)(unsafe.Pointer(n)) } func (n *Node) AsBinaryExpression() *BinaryExpression { - return n.data.(*BinaryExpression) + if n.Kind != KindBinaryExpression { + panic("Invalid node cast to BinaryExpression") + } + return (*BinaryExpression)(unsafe.Pointer(n)) } func (n *Node) AsPrefixUnaryExpression() *PrefixUnaryExpression { - return n.data.(*PrefixUnaryExpression) + if n.Kind != KindPrefixUnaryExpression { + panic("Invalid node cast to PrefixUnaryExpression") + } + return (*PrefixUnaryExpression)(unsafe.Pointer(n)) } func (n *Node) AsPostfixUnaryExpression() *PostfixUnaryExpression { - return n.data.(*PostfixUnaryExpression) + if n.Kind != KindPostfixUnaryExpression { + panic("Invalid node cast to PostfixUnaryExpression") + } + return (*PostfixUnaryExpression)(unsafe.Pointer(n)) } func (n *Node) AsYieldExpression() *YieldExpression { - return n.data.(*YieldExpression) + if n.Kind != KindYieldExpression { + panic("Invalid node cast to YieldExpression") + } + return (*YieldExpression)(unsafe.Pointer(n)) } func (n *Node) AsArrowFunction() *ArrowFunction { - return n.data.(*ArrowFunction) + if n.Kind != KindArrowFunction { + panic("Invalid node cast to ArrowFunction") + } + return (*ArrowFunction)(unsafe.Pointer(n)) } func (n *Node) AsFunctionExpression() *FunctionExpression { - return n.data.(*FunctionExpression) + if n.Kind != KindFunctionExpression { + panic("Invalid node cast to FunctionExpression") + } + return (*FunctionExpression)(unsafe.Pointer(n)) } func (n *Node) AsAsExpression() *AsExpression { - return n.data.(*AsExpression) + if n.Kind != KindAsExpression { + panic("Invalid node cast to AsExpression") + } + return (*AsExpression)(unsafe.Pointer(n)) } func (n *Node) AsSatisfiesExpression() *SatisfiesExpression { - return n.data.(*SatisfiesExpression) + if n.Kind != KindSatisfiesExpression { + panic("Invalid node cast to SatisfiesExpression") + } + return (*SatisfiesExpression)(unsafe.Pointer(n)) } func (n *Node) AsConditionalExpression() *ConditionalExpression { - return n.data.(*ConditionalExpression) + if n.Kind != KindConditionalExpression { + panic("Invalid node cast to ConditionalExpression") + } + return (*ConditionalExpression)(unsafe.Pointer(n)) } func (n *Node) AsPropertyAccessExpression() *PropertyAccessExpression { - return n.data.(*PropertyAccessExpression) + if n.Kind != KindPropertyAccessExpression { + panic("Invalid node cast to PropertyAccessExpression") + } + return (*PropertyAccessExpression)(unsafe.Pointer(n)) } func (n *Node) AsElementAccessExpression() *ElementAccessExpression { - return n.data.(*ElementAccessExpression) + if n.Kind != KindElementAccessExpression { + panic("Invalid node cast to ElementAccessExpression") + } + return (*ElementAccessExpression)(unsafe.Pointer(n)) } func (n *Node) AsCallExpression() *CallExpression { - return n.data.(*CallExpression) + if n.Kind != KindCallExpression { + panic("Invalid node cast to CallExpression") + } + return (*CallExpression)(unsafe.Pointer(n)) } func (n *Node) AsNewExpression() *NewExpression { - return n.data.(*NewExpression) + if n.Kind != KindNewExpression { + panic("Invalid node cast to NewExpression") + } + return (*NewExpression)(unsafe.Pointer(n)) } func (n *Node) AsMetaProperty() *MetaProperty { - return n.data.(*MetaProperty) + if n.Kind != KindMetaProperty { + panic("Invalid node cast to MetaProperty") + } + return (*MetaProperty)(unsafe.Pointer(n)) } func (n *Node) AsNonNullExpression() *NonNullExpression { - return n.data.(*NonNullExpression) + if n.Kind != KindNonNullExpression { + panic("Invalid node cast to NonNullExpression") + } + return (*NonNullExpression)(unsafe.Pointer(n)) } func (n *Node) AsSpreadElement() *SpreadElement { - return n.data.(*SpreadElement) + if n.Kind != KindSpreadElement { + panic("Invalid node cast to SpreadElement") + } + return (*SpreadElement)(unsafe.Pointer(n)) } func (n *Node) AsTemplateExpression() *TemplateExpression { - return n.data.(*TemplateExpression) + if n.Kind != KindTemplateExpression { + panic("Invalid node cast to TemplateExpression") + } + return (*TemplateExpression)(unsafe.Pointer(n)) } func (n *Node) AsTemplateSpan() *TemplateSpan { - return n.data.(*TemplateSpan) + if n.Kind != KindTemplateSpan { + panic("Invalid node cast to TemplateSpan") + } + return (*TemplateSpan)(unsafe.Pointer(n)) } func (n *Node) AsTaggedTemplateExpression() *TaggedTemplateExpression { - return n.data.(*TaggedTemplateExpression) + if n.Kind != KindTaggedTemplateExpression { + panic("Invalid node cast to TaggedTemplateExpression") + } + return (*TaggedTemplateExpression)(unsafe.Pointer(n)) } func (n *Node) AsParenthesizedExpression() *ParenthesizedExpression { - return n.data.(*ParenthesizedExpression) + if n.Kind != KindParenthesizedExpression { + panic("Invalid node cast to ParenthesizedExpression") + } + return (*ParenthesizedExpression)(unsafe.Pointer(n)) } func (n *Node) AsArrayLiteralExpression() *ArrayLiteralExpression { - return n.data.(*ArrayLiteralExpression) + if n.Kind != KindArrayLiteralExpression { + panic("Invalid node cast to ArrayLiteralExpression") + } + return (*ArrayLiteralExpression)(unsafe.Pointer(n)) } func (n *Node) AsObjectLiteralExpression() *ObjectLiteralExpression { - return n.data.(*ObjectLiteralExpression) + if n.Kind != KindObjectLiteralExpression { + panic("Invalid node cast to ObjectLiteralExpression") + } + return (*ObjectLiteralExpression)(unsafe.Pointer(n)) } func (n *Node) AsSpreadAssignment() *SpreadAssignment { - return n.data.(*SpreadAssignment) + if n.Kind != KindSpreadAssignment { + panic("Invalid node cast to SpreadAssignment") + } + return (*SpreadAssignment)(unsafe.Pointer(n)) } func (n *Node) AsPropertyAssignment() *PropertyAssignment { - return n.data.(*PropertyAssignment) + if n.Kind != KindPropertyAssignment { + panic("Invalid node cast to PropertyAssignment") + } + return (*PropertyAssignment)(unsafe.Pointer(n)) } func (n *Node) AsShorthandPropertyAssignment() *ShorthandPropertyAssignment { - return n.data.(*ShorthandPropertyAssignment) + if n.Kind != KindShorthandPropertyAssignment { + panic("Invalid node cast to ShorthandPropertyAssignment") + } + return (*ShorthandPropertyAssignment)(unsafe.Pointer(n)) } func (n *Node) AsDeleteExpression() *DeleteExpression { - return n.data.(*DeleteExpression) + if n.Kind != KindDeleteExpression { + panic("Invalid node cast to DeleteExpression") + } + return (*DeleteExpression)(unsafe.Pointer(n)) } func (n *Node) AsTypeOfExpression() *TypeOfExpression { - return n.data.(*TypeOfExpression) + if n.Kind != KindTypeOfExpression { + panic("Invalid node cast to TypeOfExpression") + } + return (*TypeOfExpression)(unsafe.Pointer(n)) } func (n *Node) AsVoidExpression() *VoidExpression { - return n.data.(*VoidExpression) + if n.Kind != KindVoidExpression { + panic("Invalid node cast to VoidExpression") + } + return (*VoidExpression)(unsafe.Pointer(n)) } func (n *Node) AsAwaitExpression() *AwaitExpression { - return n.data.(*AwaitExpression) + if n.Kind != KindAwaitExpression { + panic("Invalid node cast to AwaitExpression") + } + return (*AwaitExpression)(unsafe.Pointer(n)) } func (n *Node) AsTypeAssertion() *TypeAssertion { - return n.data.(*TypeAssertion) + if n.Kind != KindTypeAssertionExpression { + panic("Invalid node cast to TypeAssertion") + } + return (*TypeAssertion)(unsafe.Pointer(n)) } func (n *Node) AsKeywordTypeNode() *KeywordTypeNode { - return n.data.(*KeywordTypeNode) + switch n.Kind { + case KindVoidKeyword, KindAnyKeyword, KindBooleanKeyword, KindIntrinsicKeyword, KindNeverKeyword, KindNumberKeyword, KindObjectKeyword, KindStringKeyword, KindSymbolKeyword, KindUndefinedKeyword, KindUnknownKeyword, KindBigIntKeyword: + default: + panic("Invalid node cast to KeywordTypeNode") + } + return (*KeywordTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsUnionTypeNode() *UnionTypeNode { - return n.data.(*UnionTypeNode) + if n.Kind != KindUnionType { + panic("Invalid node cast to UnionTypeNode") + } + return (*UnionTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsIntersectionTypeNode() *IntersectionTypeNode { - return n.data.(*IntersectionTypeNode) + if n.Kind != KindIntersectionType { + panic("Invalid node cast to IntersectionTypeNode") + } + return (*IntersectionTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsConditionalTypeNode() *ConditionalTypeNode { - return n.data.(*ConditionalTypeNode) + if n.Kind != KindConditionalType { + panic("Invalid node cast to ConditionalTypeNode") + } + return (*ConditionalTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsTypeOperatorNode() *TypeOperatorNode { - return n.data.(*TypeOperatorNode) + if n.Kind != KindTypeOperator { + panic("Invalid node cast to TypeOperatorNode") + } + return (*TypeOperatorNode)(unsafe.Pointer(n)) } func (n *Node) AsInferTypeNode() *InferTypeNode { - return n.data.(*InferTypeNode) + if n.Kind != KindInferType { + panic("Invalid node cast to InferTypeNode") + } + return (*InferTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsArrayTypeNode() *ArrayTypeNode { - return n.data.(*ArrayTypeNode) + if n.Kind != KindArrayType { + panic("Invalid node cast to ArrayTypeNode") + } + return (*ArrayTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsIndexedAccessTypeNode() *IndexedAccessTypeNode { - return n.data.(*IndexedAccessTypeNode) + if n.Kind != KindIndexedAccessType { + panic("Invalid node cast to IndexedAccessTypeNode") + } + return (*IndexedAccessTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsTypeReferenceNode() *TypeReferenceNode { - return n.data.(*TypeReferenceNode) + if n.Kind != KindTypeReference { + panic("Invalid node cast to TypeReferenceNode") + } + return (*TypeReferenceNode)(unsafe.Pointer(n)) } func (n *Node) AsExpressionWithTypeArguments() *ExpressionWithTypeArguments { - return n.data.(*ExpressionWithTypeArguments) + if n.Kind != KindExpressionWithTypeArguments { + panic("Invalid node cast to ExpressionWithTypeArguments") + } + return (*ExpressionWithTypeArguments)(unsafe.Pointer(n)) } func (n *Node) AsLiteralTypeNode() *LiteralTypeNode { - return n.data.(*LiteralTypeNode) + if n.Kind != KindLiteralType { + panic("Invalid node cast to LiteralTypeNode") + } + return (*LiteralTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsThisTypeNode() *ThisTypeNode { - return n.data.(*ThisTypeNode) + if n.Kind != KindThisType { + panic("Invalid node cast to ThisTypeNode") + } + return (*ThisTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsTypePredicateNode() *TypePredicateNode { - return n.data.(*TypePredicateNode) + if n.Kind != KindTypePredicate { + panic("Invalid node cast to TypePredicateNode") + } + return (*TypePredicateNode)(unsafe.Pointer(n)) } func (n *Node) AsImportAttribute() *ImportAttribute { - return n.data.(*ImportAttribute) + if n.Kind != KindImportAttribute { + panic("Invalid node cast to ImportAttribute") + } + return (*ImportAttribute)(unsafe.Pointer(n)) } func (n *Node) AsImportAttributes() *ImportAttributes { - return n.data.(*ImportAttributes) + if n.Kind != KindImportAttributes { + panic("Invalid node cast to ImportAttributes") + } + return (*ImportAttributes)(unsafe.Pointer(n)) } func (n *Node) AsTypeQueryNode() *TypeQueryNode { - return n.data.(*TypeQueryNode) + if n.Kind != KindTypeQuery { + panic("Invalid node cast to TypeQueryNode") + } + return (*TypeQueryNode)(unsafe.Pointer(n)) } func (n *Node) AsMappedTypeNode() *MappedTypeNode { - return n.data.(*MappedTypeNode) + if n.Kind != KindMappedType { + panic("Invalid node cast to MappedTypeNode") + } + return (*MappedTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsTypeLiteralNode() *TypeLiteralNode { - return n.data.(*TypeLiteralNode) + if n.Kind != KindTypeLiteral { + panic("Invalid node cast to TypeLiteralNode") + } + return (*TypeLiteralNode)(unsafe.Pointer(n)) } func (n *Node) AsTupleTypeNode() *TupleTypeNode { - return n.data.(*TupleTypeNode) + if n.Kind != KindTupleType { + panic("Invalid node cast to TupleTypeNode") + } + return (*TupleTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsNamedTupleMember() *NamedTupleMember { - return n.data.(*NamedTupleMember) + if n.Kind != KindNamedTupleMember { + panic("Invalid node cast to NamedTupleMember") + } + return (*NamedTupleMember)(unsafe.Pointer(n)) } func (n *Node) AsOptionalTypeNode() *OptionalTypeNode { - return n.data.(*OptionalTypeNode) + if n.Kind != KindOptionalType { + panic("Invalid node cast to OptionalTypeNode") + } + return (*OptionalTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsRestTypeNode() *RestTypeNode { - return n.data.(*RestTypeNode) + if n.Kind != KindRestType { + panic("Invalid node cast to RestTypeNode") + } + return (*RestTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsParenthesizedTypeNode() *ParenthesizedTypeNode { - return n.data.(*ParenthesizedTypeNode) + if n.Kind != KindParenthesizedType { + panic("Invalid node cast to ParenthesizedTypeNode") + } + return (*ParenthesizedTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsFunctionTypeNode() *FunctionTypeNode { - return n.data.(*FunctionTypeNode) + if n.Kind != KindFunctionType { + panic("Invalid node cast to FunctionTypeNode") + } + return (*FunctionTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsConstructorTypeNode() *ConstructorTypeNode { - return n.data.(*ConstructorTypeNode) + if n.Kind != KindConstructorType { + panic("Invalid node cast to ConstructorTypeNode") + } + return (*ConstructorTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsTemplateHead() *TemplateHead { - return n.data.(*TemplateHead) + if n.Kind != KindTemplateHead { + panic("Invalid node cast to TemplateHead") + } + return (*TemplateHead)(unsafe.Pointer(n)) } func (n *Node) AsTemplateMiddle() *TemplateMiddle { - return n.data.(*TemplateMiddle) + if n.Kind != KindTemplateMiddle { + panic("Invalid node cast to TemplateMiddle") + } + return (*TemplateMiddle)(unsafe.Pointer(n)) } func (n *Node) AsTemplateTail() *TemplateTail { - return n.data.(*TemplateTail) + if n.Kind != KindTemplateTail { + panic("Invalid node cast to TemplateTail") + } + return (*TemplateTail)(unsafe.Pointer(n)) } func (n *Node) AsTemplateLiteralTypeNode() *TemplateLiteralTypeNode { - return n.data.(*TemplateLiteralTypeNode) + if n.Kind != KindTemplateLiteralType { + panic("Invalid node cast to TemplateLiteralTypeNode") + } + return (*TemplateLiteralTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsTemplateLiteralTypeSpan() *TemplateLiteralTypeSpan { - return n.data.(*TemplateLiteralTypeSpan) + if n.Kind != KindTemplateLiteralTypeSpan { + panic("Invalid node cast to TemplateLiteralTypeSpan") + } + return (*TemplateLiteralTypeSpan)(unsafe.Pointer(n)) } func (n *Node) AsSyntheticExpression() *SyntheticExpression { - return n.data.(*SyntheticExpression) + if n.Kind != KindSyntheticExpression { + panic("Invalid node cast to SyntheticExpression") + } + return (*SyntheticExpression)(unsafe.Pointer(n)) } func (n *Node) AsPartiallyEmittedExpression() *PartiallyEmittedExpression { - return n.data.(*PartiallyEmittedExpression) + if n.Kind != KindPartiallyEmittedExpression { + panic("Invalid node cast to PartiallyEmittedExpression") + } + return (*PartiallyEmittedExpression)(unsafe.Pointer(n)) } func (n *Node) AsJsxElement() *JsxElement { - return n.data.(*JsxElement) + if n.Kind != KindJsxElement { + panic("Invalid node cast to JsxElement") + } + return (*JsxElement)(unsafe.Pointer(n)) } func (n *Node) AsJsxAttributes() *JsxAttributes { - return n.data.(*JsxAttributes) + if n.Kind != KindJsxAttributes { + panic("Invalid node cast to JsxAttributes") + } + return (*JsxAttributes)(unsafe.Pointer(n)) } func (n *Node) AsJsxNamespacedName() *JsxNamespacedName { - return n.data.(*JsxNamespacedName) + if n.Kind != KindJsxNamespacedName { + panic("Invalid node cast to JsxNamespacedName") + } + return (*JsxNamespacedName)(unsafe.Pointer(n)) } func (n *Node) AsJsxOpeningElement() *JsxOpeningElement { - return n.data.(*JsxOpeningElement) + if n.Kind != KindJsxOpeningElement { + panic("Invalid node cast to JsxOpeningElement") + } + return (*JsxOpeningElement)(unsafe.Pointer(n)) } func (n *Node) AsJsxSelfClosingElement() *JsxSelfClosingElement { - return n.data.(*JsxSelfClosingElement) + if n.Kind != KindJsxSelfClosingElement { + panic("Invalid node cast to JsxSelfClosingElement") + } + return (*JsxSelfClosingElement)(unsafe.Pointer(n)) } func (n *Node) AsJsxFragment() *JsxFragment { - return n.data.(*JsxFragment) + if n.Kind != KindJsxFragment { + panic("Invalid node cast to JsxFragment") + } + return (*JsxFragment)(unsafe.Pointer(n)) } func (n *Node) AsJsxOpeningFragment() *JsxOpeningFragment { - return n.data.(*JsxOpeningFragment) + if n.Kind != KindJsxOpeningFragment { + panic("Invalid node cast to JsxOpeningFragment") + } + return (*JsxOpeningFragment)(unsafe.Pointer(n)) } func (n *Node) AsJsxClosingFragment() *JsxClosingFragment { - return n.data.(*JsxClosingFragment) + if n.Kind != KindJsxClosingFragment { + panic("Invalid node cast to JsxClosingFragment") + } + return (*JsxClosingFragment)(unsafe.Pointer(n)) } func (n *Node) AsJsxAttribute() *JsxAttribute { - return n.data.(*JsxAttribute) + if n.Kind != KindJsxAttribute { + panic("Invalid node cast to JsxAttribute") + } + return (*JsxAttribute)(unsafe.Pointer(n)) } func (n *Node) AsJsxSpreadAttribute() *JsxSpreadAttribute { - return n.data.(*JsxSpreadAttribute) + if n.Kind != KindJsxSpreadAttribute { + panic("Invalid node cast to JsxSpreadAttribute") + } + return (*JsxSpreadAttribute)(unsafe.Pointer(n)) } func (n *Node) AsJsxClosingElement() *JsxClosingElement { - return n.data.(*JsxClosingElement) + if n.Kind != KindJsxClosingElement { + panic("Invalid node cast to JsxClosingElement") + } + return (*JsxClosingElement)(unsafe.Pointer(n)) } func (n *Node) AsJsxExpression() *JsxExpression { - return n.data.(*JsxExpression) + if n.Kind != KindJsxExpression { + panic("Invalid node cast to JsxExpression") + } + return (*JsxExpression)(unsafe.Pointer(n)) } func (n *Node) AsJsxText() *JsxText { - return n.data.(*JsxText) + if n.Kind != KindJsxText { + panic("Invalid node cast to JsxText") + } + return (*JsxText)(unsafe.Pointer(n)) } func (n *Node) AsSyntaxList() *SyntaxList { - return n.data.(*SyntaxList) + if n.Kind != KindSyntaxList { + panic("Invalid node cast to SyntaxList") + } + return (*SyntaxList)(unsafe.Pointer(n)) } func (n *Node) AsJSDoc() *JSDoc { - return n.data.(*JSDoc) + if n.Kind != KindJSDoc { + panic("Invalid node cast to JSDoc") + } + return (*JSDoc)(unsafe.Pointer(n)) } func (n *Node) AsJSDocTypeExpression() *JSDocTypeExpression { - return n.data.(*JSDocTypeExpression) + if n.Kind != KindJSDocTypeExpression { + panic("Invalid node cast to JSDocTypeExpression") + } + return (*JSDocTypeExpression)(unsafe.Pointer(n)) } func (n *Node) AsJSDocNonNullableType() *JSDocNonNullableType { - return n.data.(*JSDocNonNullableType) + if n.Kind != KindJSDocNonNullableType { + panic("Invalid node cast to JSDocNonNullableType") + } + return (*JSDocNonNullableType)(unsafe.Pointer(n)) } func (n *Node) AsJSDocNullableType() *JSDocNullableType { - return n.data.(*JSDocNullableType) + if n.Kind != KindJSDocNullableType { + panic("Invalid node cast to JSDocNullableType") + } + return (*JSDocNullableType)(unsafe.Pointer(n)) } func (n *Node) AsJSDocAllType() *JSDocAllType { - return n.data.(*JSDocAllType) + if n.Kind != KindJSDocAllType { + panic("Invalid node cast to JSDocAllType") + } + return (*JSDocAllType)(unsafe.Pointer(n)) } func (n *Node) AsJSDocVariadicType() *JSDocVariadicType { - return n.data.(*JSDocVariadicType) + if n.Kind != KindJSDocVariadicType { + panic("Invalid node cast to JSDocVariadicType") + } + return (*JSDocVariadicType)(unsafe.Pointer(n)) } func (n *Node) AsJSDocOptionalType() *JSDocOptionalType { - return n.data.(*JSDocOptionalType) + if n.Kind != KindJSDocOptionalType { + panic("Invalid node cast to JSDocOptionalType") + } + return (*JSDocOptionalType)(unsafe.Pointer(n)) } func (n *Node) AsJSDocTypeTag() *JSDocTypeTag { - return n.data.(*JSDocTypeTag) + if n.Kind != KindJSDocTypeTag { + panic("Invalid node cast to JSDocTypeTag") + } + return (*JSDocTypeTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocUnknownTag() *JSDocUnknownTag { - return n.data.(*JSDocUnknownTag) + if n.Kind != KindJSDocUnknownTag { + panic("Invalid node cast to JSDocUnknownTag") + } + return (*JSDocUnknownTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocTemplateTag() *JSDocTemplateTag { - return n.data.(*JSDocTemplateTag) + if n.Kind != KindJSDocTemplateTag { + panic("Invalid node cast to JSDocTemplateTag") + } + return (*JSDocTemplateTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocReturnTag() *JSDocReturnTag { - return n.data.(*JSDocReturnTag) + if n.Kind != KindJSDocReturnTag { + panic("Invalid node cast to JSDocReturnTag") + } + return (*JSDocReturnTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocPublicTag() *JSDocPublicTag { - return n.data.(*JSDocPublicTag) + if n.Kind != KindJSDocPublicTag { + panic("Invalid node cast to JSDocPublicTag") + } + return (*JSDocPublicTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocPrivateTag() *JSDocPrivateTag { - return n.data.(*JSDocPrivateTag) + if n.Kind != KindJSDocPrivateTag { + panic("Invalid node cast to JSDocPrivateTag") + } + return (*JSDocPrivateTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocProtectedTag() *JSDocProtectedTag { - return n.data.(*JSDocProtectedTag) + if n.Kind != KindJSDocProtectedTag { + panic("Invalid node cast to JSDocProtectedTag") + } + return (*JSDocProtectedTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocReadonlyTag() *JSDocReadonlyTag { - return n.data.(*JSDocReadonlyTag) + if n.Kind != KindJSDocReadonlyTag { + panic("Invalid node cast to JSDocReadonlyTag") + } + return (*JSDocReadonlyTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocOverrideTag() *JSDocOverrideTag { - return n.data.(*JSDocOverrideTag) + if n.Kind != KindJSDocOverrideTag { + panic("Invalid node cast to JSDocOverrideTag") + } + return (*JSDocOverrideTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocDeprecatedTag() *JSDocDeprecatedTag { - return n.data.(*JSDocDeprecatedTag) + if n.Kind != KindJSDocDeprecatedTag { + panic("Invalid node cast to JSDocDeprecatedTag") + } + return (*JSDocDeprecatedTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocSeeTag() *JSDocSeeTag { - return n.data.(*JSDocSeeTag) + if n.Kind != KindJSDocSeeTag { + panic("Invalid node cast to JSDocSeeTag") + } + return (*JSDocSeeTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocImplementsTag() *JSDocImplementsTag { - return n.data.(*JSDocImplementsTag) + if n.Kind != KindJSDocImplementsTag { + panic("Invalid node cast to JSDocImplementsTag") + } + return (*JSDocImplementsTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocAugmentsTag() *JSDocAugmentsTag { - return n.data.(*JSDocAugmentsTag) + if n.Kind != KindJSDocAugmentsTag { + panic("Invalid node cast to JSDocAugmentsTag") + } + return (*JSDocAugmentsTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocSatisfiesTag() *JSDocSatisfiesTag { - return n.data.(*JSDocSatisfiesTag) + if n.Kind != KindJSDocSatisfiesTag { + panic("Invalid node cast to JSDocSatisfiesTag") + } + return (*JSDocSatisfiesTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocThrowsTag() *JSDocThrowsTag { - return n.data.(*JSDocThrowsTag) + if n.Kind != KindJSDocThrowsTag { + panic("Invalid node cast to JSDocThrowsTag") + } + return (*JSDocThrowsTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocThisTag() *JSDocThisTag { - return n.data.(*JSDocThisTag) + if n.Kind != KindJSDocThisTag { + panic("Invalid node cast to JSDocThisTag") + } + return (*JSDocThisTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocImportTag() *JSDocImportTag { - return n.data.(*JSDocImportTag) + if n.Kind != KindJSDocImportTag { + panic("Invalid node cast to JSDocImportTag") + } + return (*JSDocImportTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocCallbackTag() *JSDocCallbackTag { - return n.data.(*JSDocCallbackTag) + if n.Kind != KindJSDocCallbackTag { + panic("Invalid node cast to JSDocCallbackTag") + } + return (*JSDocCallbackTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocOverloadTag() *JSDocOverloadTag { - return n.data.(*JSDocOverloadTag) + if n.Kind != KindJSDocOverloadTag { + panic("Invalid node cast to JSDocOverloadTag") + } + return (*JSDocOverloadTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocTypedefTag() *JSDocTypedefTag { - return n.data.(*JSDocTypedefTag) + if n.Kind != KindJSDocTypedefTag { + panic("Invalid node cast to JSDocTypedefTag") + } + return (*JSDocTypedefTag)(unsafe.Pointer(n)) } func (n *Node) AsJSDocSignature() *JSDocSignature { - return n.data.(*JSDocSignature) + if n.Kind != KindJSDocSignature { + panic("Invalid node cast to JSDocSignature") + } + return (*JSDocSignature)(unsafe.Pointer(n)) } func (n *Node) AsJSDocNameReference() *JSDocNameReference { - return n.data.(*JSDocNameReference) + if n.Kind != KindJSDocNameReference { + panic("Invalid node cast to JSDocNameReference") + } + return (*JSDocNameReference)(unsafe.Pointer(n)) } func (n *Node) AsSourceFile() *SourceFile { - return n.data.(*SourceFile) + if n.Kind != KindSourceFile { + panic("Invalid node cast to SourceFile") + } + return (*SourceFile)(unsafe.Pointer(n)) } func (n *Node) AsModuleDeclaration() *ModuleDeclaration { - return n.data.(*ModuleDeclaration) + if n.Kind != KindModuleDeclaration { + panic("Invalid node cast to ModuleDeclaration") + } + return (*ModuleDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsImportEqualsDeclaration() *ImportEqualsDeclaration { - return n.data.(*ImportEqualsDeclaration) + if n.Kind != KindImportEqualsDeclaration { + panic("Invalid node cast to ImportEqualsDeclaration") + } + return (*ImportEqualsDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsExportDeclaration() *ExportDeclaration { - return n.data.(*ExportDeclaration) + if n.Kind != KindExportDeclaration { + panic("Invalid node cast to ExportDeclaration") + } + return (*ExportDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsImportTypeNode() *ImportTypeNode { - return n.data.(*ImportTypeNode) + if n.Kind != KindImportType { + panic("Invalid node cast to ImportTypeNode") + } + return (*ImportTypeNode)(unsafe.Pointer(n)) } func (n *Node) AsImportClause() *ImportClause { - return n.data.(*ImportClause) + if n.Kind != KindImportClause { + panic("Invalid node cast to ImportClause") + } + return (*ImportClause)(unsafe.Pointer(n)) } func (n *Node) AsImportSpecifier() *ImportSpecifier { - return n.data.(*ImportSpecifier) + if n.Kind != KindImportSpecifier { + panic("Invalid node cast to ImportSpecifier") + } + return (*ImportSpecifier)(unsafe.Pointer(n)) } func (n *Node) AsJSDocText() *JSDocText { - return n.data.(*JSDocText) + if n.Kind != KindJSDocText { + panic("Invalid node cast to JSDocText") + } + return (*JSDocText)(unsafe.Pointer(n)) } func (n *Node) AsJSDocLink() *JSDocLink { - return n.data.(*JSDocLink) + if n.Kind != KindJSDocLink { + panic("Invalid node cast to JSDocLink") + } + return (*JSDocLink)(unsafe.Pointer(n)) } func (n *Node) AsJSDocLinkPlain() *JSDocLinkPlain { - return n.data.(*JSDocLinkPlain) + if n.Kind != KindJSDocLinkPlain { + panic("Invalid node cast to JSDocLinkPlain") + } + return (*JSDocLinkPlain)(unsafe.Pointer(n)) } func (n *Node) AsJSDocLinkCode() *JSDocLinkCode { - return n.data.(*JSDocLinkCode) + if n.Kind != KindJSDocLinkCode { + panic("Invalid node cast to JSDocLinkCode") + } + return (*JSDocLinkCode)(unsafe.Pointer(n)) } func (n *Node) AsTypeParameterDeclaration() *TypeParameterDeclaration { - return n.data.(*TypeParameterDeclaration) + if n.Kind != KindTypeParameter { + panic("Invalid node cast to TypeParameterDeclaration") + } + return (*TypeParameterDeclaration)(unsafe.Pointer(n)) } func (n *Node) AsSyntheticReferenceExpression() *SyntheticReferenceExpression { - return n.data.(*SyntheticReferenceExpression) + if n.Kind != KindSyntheticReferenceExpression { + panic("Invalid node cast to SyntheticReferenceExpression") + } + return (*SyntheticReferenceExpression)(unsafe.Pointer(n)) } func (n *Node) AsJSDocTypeLiteral() *JSDocTypeLiteral { - return n.data.(*JSDocTypeLiteral) + if n.Kind != KindJSDocTypeLiteral { + panic("Invalid node cast to JSDocTypeLiteral") + } + return (*JSDocTypeLiteral)(unsafe.Pointer(n)) } func (n *Node) AsJSDocParameterOrPropertyTag() *JSDocParameterOrPropertyTag { - return n.data.(*JSDocParameterOrPropertyTag) + switch n.Kind { + case KindJSDocParameterTag, KindJSDocPropertyTag: + default: + panic("Invalid node cast to JSDocParameterOrPropertyTag") + } + return (*JSDocParameterOrPropertyTag)(unsafe.Pointer(n)) } // ────────────────────────────────────────────────────────────────────── diff --git a/tsc/internal/ast/flow.go b/tsc/internal/ast/flow.go index 274a92f716689..43a4bc2f0dfea 100644 --- a/tsc/internal/ast/flow.go +++ b/tsc/internal/ast/flow.go @@ -1,5 +1,7 @@ package ast +import "unsafe" + // FlowFlags type FlowFlags uint32 @@ -38,6 +40,11 @@ type FlowList struct { type FlowLabel = FlowNode +const ( + kindFlowSwitchClauseData Kind = KindCount + 1 + iota + kindFlowReduceLabelData +) + // FlowSwitchClauseData (synthetic AST node for FlowFlagsSwitchClause) type FlowSwitchClauseData struct { @@ -47,12 +54,14 @@ type FlowSwitchClauseData struct { ClauseEnd int32 // End index of case/default clause range } +var _ [0 - unsafe.Offsetof(FlowSwitchClauseData{}.Node)]byte + func NewFlowSwitchClauseData(switchStatement *Node, clauseStart int, clauseEnd int) *Node { node := &FlowSwitchClauseData{} node.SwitchStatement = switchStatement node.ClauseStart = int32(clauseStart) node.ClauseEnd = int32(clauseEnd) - return newNode(KindUnknown, node, NodeFactoryHooks{}) + return newNode(kindFlowSwitchClauseData, node.AsNode(), NodeFactoryHooks{}) } func (node *FlowSwitchClauseData) IsEmpty() bool { @@ -67,9 +76,11 @@ type FlowReduceLabelData struct { Antecedents *FlowList // Temporary antecedent list } +var _ [0 - unsafe.Offsetof(FlowReduceLabelData{}.Node)]byte + func NewFlowReduceLabelData(target *FlowLabel, antecedents *FlowList) *Node { node := &FlowReduceLabelData{} node.Target = target node.Antecedents = antecedents - return newNode(KindUnknown, node, NodeFactoryHooks{}) + return newNode(kindFlowReduceLabelData, node.AsNode(), NodeFactoryHooks{}) } diff --git a/tsc/internal/ast/kind_stringer_generated.go b/tsc/internal/ast/kind_stringer_generated.go index 9600c3d090453..5ef080dd0350e 100644 --- a/tsc/internal/ast/kind_stringer_generated.go +++ b/tsc/internal/ast/kind_stringer_generated.go @@ -8,6 +8,8 @@ func _() { // An "invalid array index" compiler error signifies that the constant values have changed. // Re-run the stringer command to generate them again. var x [1]struct{} + _ = x[kindFlowSwitchClauseData-353] + _ = x[kindFlowReduceLabelData-354] _ = x[KindUnknown-0] _ = x[KindEndOfFile-1] _ = x[KindSingleLineCommentTrivia-2] @@ -363,9 +365,9 @@ func _() { _ = x[KindCount-352] } -const _Kind_name = "KindUnknownKindEndOfFileKindSingleLineCommentTriviaKindMultiLineCommentTriviaKindNewLineTriviaKindWhitespaceTriviaKindConflictMarkerTriviaKindNonTextFileMarkerTriviaKindNumericLiteralKindBigIntLiteralKindStringLiteralKindJsxTextKindJsxTextAllWhiteSpacesKindRegularExpressionLiteralKindNoSubstitutionTemplateLiteralKindTemplateHeadKindTemplateMiddleKindTemplateTailKindOpenBraceTokenKindCloseBraceTokenKindOpenParenTokenKindCloseParenTokenKindOpenBracketTokenKindCloseBracketTokenKindDotTokenKindDotDotDotTokenKindSemicolonTokenKindCommaTokenKindQuestionDotTokenKindLessThanTokenKindLessThanSlashTokenKindGreaterThanTokenKindLessThanEqualsTokenKindGreaterThanEqualsTokenKindEqualsEqualsTokenKindExclamationEqualsTokenKindEqualsEqualsEqualsTokenKindExclamationEqualsEqualsTokenKindEqualsGreaterThanTokenKindPlusTokenKindMinusTokenKindAsteriskTokenKindAsteriskAsteriskTokenKindSlashTokenKindPercentTokenKindPlusPlusTokenKindMinusMinusTokenKindLessThanLessThanTokenKindGreaterThanGreaterThanTokenKindGreaterThanGreaterThanGreaterThanTokenKindAmpersandTokenKindBarTokenKindCaretTokenKindExclamationTokenKindTildeTokenKindAmpersandAmpersandTokenKindBarBarTokenKindQuestionTokenKindColonTokenKindAtTokenKindQuestionQuestionTokenKindBacktickTokenKindHashTokenKindEqualsTokenKindPlusEqualsTokenKindMinusEqualsTokenKindAsteriskEqualsTokenKindAsteriskAsteriskEqualsTokenKindSlashEqualsTokenKindPercentEqualsTokenKindLessThanLessThanEqualsTokenKindGreaterThanGreaterThanEqualsTokenKindGreaterThanGreaterThanGreaterThanEqualsTokenKindAmpersandEqualsTokenKindBarEqualsTokenKindBarBarEqualsTokenKindAmpersandAmpersandEqualsTokenKindQuestionQuestionEqualsTokenKindCaretEqualsTokenKindIdentifierKindPrivateIdentifierKindJSDocCommentTextTokenKindBreakKeywordKindCaseKeywordKindCatchKeywordKindClassKeywordKindConstKeywordKindContinueKeywordKindDebuggerKeywordKindDefaultKeywordKindDeleteKeywordKindDoKeywordKindElseKeywordKindEnumKeywordKindExportKeywordKindExtendsKeywordKindFalseKeywordKindFinallyKeywordKindForKeywordKindFunctionKeywordKindIfKeywordKindImportKeywordKindInKeywordKindInstanceOfKeywordKindNewKeywordKindNullKeywordKindReturnKeywordKindSuperKeywordKindSwitchKeywordKindThisKeywordKindThrowKeywordKindTrueKeywordKindTryKeywordKindTypeOfKeywordKindVarKeywordKindVoidKeywordKindWhileKeywordKindWithKeywordKindImplementsKeywordKindInterfaceKeywordKindLetKeywordKindPackageKeywordKindPrivateKeywordKindProtectedKeywordKindPublicKeywordKindStaticKeywordKindYieldKeywordKindAbstractKeywordKindAccessorKeywordKindAsKeywordKindAssertsKeywordKindAssertKeywordKindAnyKeywordKindAsyncKeywordKindAwaitKeywordKindBooleanKeywordKindConstructorKeywordKindDeclareKeywordKindGetKeywordKindImmediateKeywordKindInferKeywordKindIntrinsicKeywordKindIsKeywordKindKeyOfKeywordKindModuleKeywordKindNamespaceKeywordKindNeverKeywordKindOutKeywordKindReadonlyKeywordKindRequireKeywordKindNumberKeywordKindObjectKeywordKindSatisfiesKeywordKindSetKeywordKindStringKeywordKindSymbolKeywordKindTypeKeywordKindUndefinedKeywordKindUniqueKeywordKindUnknownKeywordKindUsingKeywordKindFromKeywordKindGlobalKeywordKindBigIntKeywordKindOverrideKeywordKindOfKeywordKindDeferKeywordKindSourceKeywordKindQualifiedNameKindComputedPropertyNameKindTypeParameterKindParameterKindDecoratorKindPropertySignatureKindPropertyDeclarationKindMethodSignatureKindMethodDeclarationKindClassStaticBlockDeclarationKindConstructorKindGetAccessorKindSetAccessorKindCallSignatureKindConstructSignatureKindIndexSignatureKindTypePredicateKindTypeReferenceKindFunctionTypeKindConstructorTypeKindTypeQueryKindTypeLiteralKindArrayTypeKindTupleTypeKindOptionalTypeKindRestTypeKindUnionTypeKindIntersectionTypeKindConditionalTypeKindInferTypeKindParenthesizedTypeKindThisTypeKindTypeOperatorKindIndexedAccessTypeKindMappedTypeKindLiteralTypeKindNamedTupleMemberKindTemplateLiteralTypeKindTemplateLiteralTypeSpanKindImportTypeKindObjectBindingPatternKindArrayBindingPatternKindBindingElementKindArrayLiteralExpressionKindObjectLiteralExpressionKindPropertyAccessExpressionKindElementAccessExpressionKindCallExpressionKindNewExpressionKindTaggedTemplateExpressionKindTypeAssertionExpressionKindParenthesizedExpressionKindFunctionExpressionKindArrowFunctionKindDeleteExpressionKindTypeOfExpressionKindVoidExpressionKindAwaitExpressionKindPrefixUnaryExpressionKindPostfixUnaryExpressionKindBinaryExpressionKindConditionalExpressionKindTemplateExpressionKindYieldExpressionKindSpreadElementKindClassExpressionKindOmittedExpressionKindExpressionWithTypeArgumentsKindAsExpressionKindNonNullExpressionKindMetaPropertyKindSyntheticExpressionKindSatisfiesExpressionKindTemplateSpanKindSemicolonClassElementKindBlockKindEmptyStatementKindVariableStatementKindExpressionStatementKindIfStatementKindDoStatementKindWhileStatementKindForStatementKindForInStatementKindForOfStatementKindContinueStatementKindBreakStatementKindReturnStatementKindWithStatementKindSwitchStatementKindLabeledStatementKindThrowStatementKindTryStatementKindDebuggerStatementKindVariableDeclarationKindVariableDeclarationListKindFunctionDeclarationKindClassDeclarationKindInterfaceDeclarationKindTypeAliasDeclarationKindEnumDeclarationKindModuleDeclarationKindModuleBlockKindCaseBlockKindNamespaceExportDeclarationKindImportEqualsDeclarationKindImportDeclarationKindImportClauseKindNamespaceImportKindNamedImportsKindImportSpecifierKindExportAssignmentKindExportDeclarationKindNamedExportsKindNamespaceExportKindExportSpecifierKindMissingDeclarationKindExternalModuleReferenceKindJsxElementKindJsxSelfClosingElementKindJsxOpeningElementKindJsxClosingElementKindJsxFragmentKindJsxOpeningFragmentKindJsxClosingFragmentKindJsxAttributeKindJsxAttributesKindJsxSpreadAttributeKindJsxExpressionKindJsxNamespacedNameKindCaseClauseKindDefaultClauseKindHeritageClauseKindCatchClauseKindImportAttributesKindImportAttributeKindPropertyAssignmentKindShorthandPropertyAssignmentKindSpreadAssignmentKindEnumMemberKindSourceFileKindJSDocTypeExpressionKindJSDocNameReferenceKindJSDocAllTypeKindJSDocNullableTypeKindJSDocNonNullableTypeKindJSDocOptionalTypeKindJSDocVariadicTypeKindJSDocKindJSDocTextKindJSDocTypeLiteralKindJSDocSignatureKindJSDocLinkKindJSDocLinkCodeKindJSDocLinkPlainKindJSDocUnknownTagKindJSDocAugmentsTagKindJSDocImplementsTagKindJSDocDeprecatedTagKindJSDocPublicTagKindJSDocPrivateTagKindJSDocProtectedTagKindJSDocReadonlyTagKindJSDocOverrideTagKindJSDocCallbackTagKindJSDocOverloadTagKindJSDocParameterTagKindJSDocReturnTagKindJSDocThisTagKindJSDocTypeTagKindJSDocTemplateTagKindJSDocTypedefTagKindJSDocSeeTagKindJSDocPropertyTagKindJSDocThrowsTagKindJSDocSatisfiesTagKindJSDocImportTagKindSyntaxListKindJSTypeAliasDeclarationKindJSImportDeclarationKindNotEmittedStatementKindPartiallyEmittedExpressionKindSyntheticReferenceExpressionKindNotEmittedTypeElementKindCount" +const _Kind_name = "KindUnknownKindEndOfFileKindSingleLineCommentTriviaKindMultiLineCommentTriviaKindNewLineTriviaKindWhitespaceTriviaKindConflictMarkerTriviaKindNonTextFileMarkerTriviaKindNumericLiteralKindBigIntLiteralKindStringLiteralKindJsxTextKindJsxTextAllWhiteSpacesKindRegularExpressionLiteralKindNoSubstitutionTemplateLiteralKindTemplateHeadKindTemplateMiddleKindTemplateTailKindOpenBraceTokenKindCloseBraceTokenKindOpenParenTokenKindCloseParenTokenKindOpenBracketTokenKindCloseBracketTokenKindDotTokenKindDotDotDotTokenKindSemicolonTokenKindCommaTokenKindQuestionDotTokenKindLessThanTokenKindLessThanSlashTokenKindGreaterThanTokenKindLessThanEqualsTokenKindGreaterThanEqualsTokenKindEqualsEqualsTokenKindExclamationEqualsTokenKindEqualsEqualsEqualsTokenKindExclamationEqualsEqualsTokenKindEqualsGreaterThanTokenKindPlusTokenKindMinusTokenKindAsteriskTokenKindAsteriskAsteriskTokenKindSlashTokenKindPercentTokenKindPlusPlusTokenKindMinusMinusTokenKindLessThanLessThanTokenKindGreaterThanGreaterThanTokenKindGreaterThanGreaterThanGreaterThanTokenKindAmpersandTokenKindBarTokenKindCaretTokenKindExclamationTokenKindTildeTokenKindAmpersandAmpersandTokenKindBarBarTokenKindQuestionTokenKindColonTokenKindAtTokenKindQuestionQuestionTokenKindBacktickTokenKindHashTokenKindEqualsTokenKindPlusEqualsTokenKindMinusEqualsTokenKindAsteriskEqualsTokenKindAsteriskAsteriskEqualsTokenKindSlashEqualsTokenKindPercentEqualsTokenKindLessThanLessThanEqualsTokenKindGreaterThanGreaterThanEqualsTokenKindGreaterThanGreaterThanGreaterThanEqualsTokenKindAmpersandEqualsTokenKindBarEqualsTokenKindBarBarEqualsTokenKindAmpersandAmpersandEqualsTokenKindQuestionQuestionEqualsTokenKindCaretEqualsTokenKindIdentifierKindPrivateIdentifierKindJSDocCommentTextTokenKindBreakKeywordKindCaseKeywordKindCatchKeywordKindClassKeywordKindConstKeywordKindContinueKeywordKindDebuggerKeywordKindDefaultKeywordKindDeleteKeywordKindDoKeywordKindElseKeywordKindEnumKeywordKindExportKeywordKindExtendsKeywordKindFalseKeywordKindFinallyKeywordKindForKeywordKindFunctionKeywordKindIfKeywordKindImportKeywordKindInKeywordKindInstanceOfKeywordKindNewKeywordKindNullKeywordKindReturnKeywordKindSuperKeywordKindSwitchKeywordKindThisKeywordKindThrowKeywordKindTrueKeywordKindTryKeywordKindTypeOfKeywordKindVarKeywordKindVoidKeywordKindWhileKeywordKindWithKeywordKindImplementsKeywordKindInterfaceKeywordKindLetKeywordKindPackageKeywordKindPrivateKeywordKindProtectedKeywordKindPublicKeywordKindStaticKeywordKindYieldKeywordKindAbstractKeywordKindAccessorKeywordKindAsKeywordKindAssertsKeywordKindAssertKeywordKindAnyKeywordKindAsyncKeywordKindAwaitKeywordKindBooleanKeywordKindConstructorKeywordKindDeclareKeywordKindGetKeywordKindImmediateKeywordKindInferKeywordKindIntrinsicKeywordKindIsKeywordKindKeyOfKeywordKindModuleKeywordKindNamespaceKeywordKindNeverKeywordKindOutKeywordKindReadonlyKeywordKindRequireKeywordKindNumberKeywordKindObjectKeywordKindSatisfiesKeywordKindSetKeywordKindStringKeywordKindSymbolKeywordKindTypeKeywordKindUndefinedKeywordKindUniqueKeywordKindUnknownKeywordKindUsingKeywordKindFromKeywordKindGlobalKeywordKindBigIntKeywordKindOverrideKeywordKindOfKeywordKindDeferKeywordKindSourceKeywordKindQualifiedNameKindComputedPropertyNameKindTypeParameterKindParameterKindDecoratorKindPropertySignatureKindPropertyDeclarationKindMethodSignatureKindMethodDeclarationKindClassStaticBlockDeclarationKindConstructorKindGetAccessorKindSetAccessorKindCallSignatureKindConstructSignatureKindIndexSignatureKindTypePredicateKindTypeReferenceKindFunctionTypeKindConstructorTypeKindTypeQueryKindTypeLiteralKindArrayTypeKindTupleTypeKindOptionalTypeKindRestTypeKindUnionTypeKindIntersectionTypeKindConditionalTypeKindInferTypeKindParenthesizedTypeKindThisTypeKindTypeOperatorKindIndexedAccessTypeKindMappedTypeKindLiteralTypeKindNamedTupleMemberKindTemplateLiteralTypeKindTemplateLiteralTypeSpanKindImportTypeKindObjectBindingPatternKindArrayBindingPatternKindBindingElementKindArrayLiteralExpressionKindObjectLiteralExpressionKindPropertyAccessExpressionKindElementAccessExpressionKindCallExpressionKindNewExpressionKindTaggedTemplateExpressionKindTypeAssertionExpressionKindParenthesizedExpressionKindFunctionExpressionKindArrowFunctionKindDeleteExpressionKindTypeOfExpressionKindVoidExpressionKindAwaitExpressionKindPrefixUnaryExpressionKindPostfixUnaryExpressionKindBinaryExpressionKindConditionalExpressionKindTemplateExpressionKindYieldExpressionKindSpreadElementKindClassExpressionKindOmittedExpressionKindExpressionWithTypeArgumentsKindAsExpressionKindNonNullExpressionKindMetaPropertyKindSyntheticExpressionKindSatisfiesExpressionKindTemplateSpanKindSemicolonClassElementKindBlockKindEmptyStatementKindVariableStatementKindExpressionStatementKindIfStatementKindDoStatementKindWhileStatementKindForStatementKindForInStatementKindForOfStatementKindContinueStatementKindBreakStatementKindReturnStatementKindWithStatementKindSwitchStatementKindLabeledStatementKindThrowStatementKindTryStatementKindDebuggerStatementKindVariableDeclarationKindVariableDeclarationListKindFunctionDeclarationKindClassDeclarationKindInterfaceDeclarationKindTypeAliasDeclarationKindEnumDeclarationKindModuleDeclarationKindModuleBlockKindCaseBlockKindNamespaceExportDeclarationKindImportEqualsDeclarationKindImportDeclarationKindImportClauseKindNamespaceImportKindNamedImportsKindImportSpecifierKindExportAssignmentKindExportDeclarationKindNamedExportsKindNamespaceExportKindExportSpecifierKindMissingDeclarationKindExternalModuleReferenceKindJsxElementKindJsxSelfClosingElementKindJsxOpeningElementKindJsxClosingElementKindJsxFragmentKindJsxOpeningFragmentKindJsxClosingFragmentKindJsxAttributeKindJsxAttributesKindJsxSpreadAttributeKindJsxExpressionKindJsxNamespacedNameKindCaseClauseKindDefaultClauseKindHeritageClauseKindCatchClauseKindImportAttributesKindImportAttributeKindPropertyAssignmentKindShorthandPropertyAssignmentKindSpreadAssignmentKindEnumMemberKindSourceFileKindJSDocTypeExpressionKindJSDocNameReferenceKindJSDocAllTypeKindJSDocNullableTypeKindJSDocNonNullableTypeKindJSDocOptionalTypeKindJSDocVariadicTypeKindJSDocKindJSDocTextKindJSDocTypeLiteralKindJSDocSignatureKindJSDocLinkKindJSDocLinkCodeKindJSDocLinkPlainKindJSDocUnknownTagKindJSDocAugmentsTagKindJSDocImplementsTagKindJSDocDeprecatedTagKindJSDocPublicTagKindJSDocPrivateTagKindJSDocProtectedTagKindJSDocReadonlyTagKindJSDocOverrideTagKindJSDocCallbackTagKindJSDocOverloadTagKindJSDocParameterTagKindJSDocReturnTagKindJSDocThisTagKindJSDocTypeTagKindJSDocTemplateTagKindJSDocTypedefTagKindJSDocSeeTagKindJSDocPropertyTagKindJSDocThrowsTagKindJSDocSatisfiesTagKindJSDocImportTagKindSyntaxListKindJSTypeAliasDeclarationKindJSImportDeclarationKindNotEmittedStatementKindPartiallyEmittedExpressionKindSyntheticReferenceExpressionKindNotEmittedTypeElementKindCountkindFlowSwitchClauseDatakindFlowReduceLabelData" -var _Kind_index = [...]uint16{0, 11, 24, 51, 77, 94, 114, 138, 165, 183, 200, 217, 228, 253, 281, 314, 330, 348, 364, 382, 401, 419, 438, 458, 479, 491, 509, 527, 541, 561, 578, 600, 620, 643, 669, 690, 716, 743, 775, 801, 814, 828, 845, 870, 884, 900, 917, 936, 961, 992, 1034, 1052, 1064, 1078, 1098, 1112, 1139, 1154, 1171, 1185, 1196, 1221, 1238, 1251, 1266, 1285, 1305, 1328, 1359, 1379, 1401, 1432, 1469, 1517, 1541, 1559, 1580, 1613, 1644, 1664, 1678, 1699, 1724, 1740, 1755, 1771, 1787, 1803, 1822, 1841, 1859, 1876, 1889, 1904, 1919, 1936, 1954, 1970, 1988, 2002, 2021, 2034, 2051, 2064, 2085, 2099, 2114, 2131, 2147, 2164, 2179, 2195, 2210, 2224, 2241, 2255, 2270, 2286, 2301, 2322, 2342, 2356, 2374, 2392, 2412, 2429, 2446, 2462, 2481, 2500, 2513, 2531, 2548, 2562, 2578, 2594, 2612, 2634, 2652, 2666, 2686, 2702, 2722, 2735, 2751, 2768, 2788, 2804, 2818, 2837, 2855, 2872, 2889, 2909, 2923, 2940, 2957, 2972, 2992, 3009, 3027, 3043, 3058, 3075, 3092, 3111, 3124, 3140, 3157, 3174, 3198, 3215, 3228, 3241, 3262, 3285, 3304, 3325, 3356, 3371, 3386, 3401, 3418, 3440, 3458, 3475, 3492, 3508, 3527, 3540, 3555, 3568, 3581, 3597, 3609, 3622, 3642, 3661, 3674, 3695, 3707, 3723, 3744, 3758, 3773, 3793, 3816, 3843, 3857, 3881, 3904, 3922, 3948, 3975, 4003, 4030, 4048, 4065, 4093, 4120, 4147, 4169, 4186, 4206, 4226, 4244, 4263, 4288, 4314, 4334, 4359, 4381, 4400, 4417, 4436, 4457, 4488, 4504, 4525, 4541, 4564, 4587, 4603, 4628, 4637, 4655, 4676, 4699, 4714, 4729, 4747, 4763, 4781, 4799, 4820, 4838, 4857, 4874, 4893, 4913, 4931, 4947, 4968, 4991, 5018, 5041, 5061, 5085, 5109, 5128, 5149, 5164, 5177, 5207, 5234, 5255, 5271, 5290, 5306, 5325, 5345, 5366, 5382, 5401, 5420, 5442, 5469, 5483, 5508, 5529, 5550, 5565, 5587, 5609, 5625, 5642, 5664, 5681, 5702, 5716, 5733, 5751, 5766, 5786, 5805, 5827, 5858, 5878, 5892, 5906, 5929, 5951, 5967, 5988, 6012, 6033, 6054, 6063, 6076, 6096, 6114, 6127, 6144, 6162, 6181, 6201, 6223, 6245, 6263, 6282, 6303, 6323, 6343, 6363, 6383, 6404, 6422, 6438, 6454, 6474, 6493, 6508, 6528, 6546, 6567, 6585, 6599, 6625, 6648, 6671, 6701, 6733, 6758, 6767} +var _Kind_index = [...]uint16{0, 11, 24, 51, 77, 94, 114, 138, 165, 183, 200, 217, 228, 253, 281, 314, 330, 348, 364, 382, 401, 419, 438, 458, 479, 491, 509, 527, 541, 561, 578, 600, 620, 643, 669, 690, 716, 743, 775, 801, 814, 828, 845, 870, 884, 900, 917, 936, 961, 992, 1034, 1052, 1064, 1078, 1098, 1112, 1139, 1154, 1171, 1185, 1196, 1221, 1238, 1251, 1266, 1285, 1305, 1328, 1359, 1379, 1401, 1432, 1469, 1517, 1541, 1559, 1580, 1613, 1644, 1664, 1678, 1699, 1724, 1740, 1755, 1771, 1787, 1803, 1822, 1841, 1859, 1876, 1889, 1904, 1919, 1936, 1954, 1970, 1988, 2002, 2021, 2034, 2051, 2064, 2085, 2099, 2114, 2131, 2147, 2164, 2179, 2195, 2210, 2224, 2241, 2255, 2270, 2286, 2301, 2322, 2342, 2356, 2374, 2392, 2412, 2429, 2446, 2462, 2481, 2500, 2513, 2531, 2548, 2562, 2578, 2594, 2612, 2634, 2652, 2666, 2686, 2702, 2722, 2735, 2751, 2768, 2788, 2804, 2818, 2837, 2855, 2872, 2889, 2909, 2923, 2940, 2957, 2972, 2992, 3009, 3027, 3043, 3058, 3075, 3092, 3111, 3124, 3140, 3157, 3174, 3198, 3215, 3228, 3241, 3262, 3285, 3304, 3325, 3356, 3371, 3386, 3401, 3418, 3440, 3458, 3475, 3492, 3508, 3527, 3540, 3555, 3568, 3581, 3597, 3609, 3622, 3642, 3661, 3674, 3695, 3707, 3723, 3744, 3758, 3773, 3793, 3816, 3843, 3857, 3881, 3904, 3922, 3948, 3975, 4003, 4030, 4048, 4065, 4093, 4120, 4147, 4169, 4186, 4206, 4226, 4244, 4263, 4288, 4314, 4334, 4359, 4381, 4400, 4417, 4436, 4457, 4488, 4504, 4525, 4541, 4564, 4587, 4603, 4628, 4637, 4655, 4676, 4699, 4714, 4729, 4747, 4763, 4781, 4799, 4820, 4838, 4857, 4874, 4893, 4913, 4931, 4947, 4968, 4991, 5018, 5041, 5061, 5085, 5109, 5128, 5149, 5164, 5177, 5207, 5234, 5255, 5271, 5290, 5306, 5325, 5345, 5366, 5382, 5401, 5420, 5442, 5469, 5483, 5508, 5529, 5550, 5565, 5587, 5609, 5625, 5642, 5664, 5681, 5702, 5716, 5733, 5751, 5766, 5786, 5805, 5827, 5858, 5878, 5892, 5906, 5929, 5951, 5967, 5988, 6012, 6033, 6054, 6063, 6076, 6096, 6114, 6127, 6144, 6162, 6181, 6201, 6223, 6245, 6263, 6282, 6303, 6323, 6343, 6363, 6383, 6404, 6422, 6438, 6454, 6474, 6493, 6508, 6528, 6546, 6567, 6585, 6599, 6625, 6648, 6671, 6701, 6733, 6758, 6767, 6791, 6814} func (i Kind) String() string { idx := int(i) - 0 diff --git a/tsc/internal/ast/nodeaccessors_bench_test.go b/tsc/internal/ast/nodeaccessors_bench_test.go new file mode 100644 index 0000000000000..f7d2226f207e7 --- /dev/null +++ b/tsc/internal/ast/nodeaccessors_bench_test.go @@ -0,0 +1,120 @@ +package ast_test + +import ( + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/parser" + "github.com/microsoft/TypeScript/tsc/internal/testutil/fixtures" + "github.com/microsoft/TypeScript/tsc/internal/tspath" + "github.com/microsoft/TypeScript/tsc/internal/vfs/osvfs" +) + +var ( + accessorName *ast.Node + accessorModifiers *ast.ModifierList + accessorDeclaration *ast.DeclarationBase + accessorLocals *ast.LocalsContainerBase +) + +func BenchmarkNodeAccessors(b *testing.B) { + for _, f := range fixtures.BenchFixtures { + b.Run(f.Name(), func(b *testing.B) { + f.SkipIfNotExist(b) + fileName := tspath.ToRootedFilePath(f.Path(), "/") + path := osvfs.FS().CaseSensitivity().PathKey(tspath.RootedPath(fileName)) + sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: fileName, + PathKey: path, + }, f.ReadFile(b), core.GetScriptKindFromFileName(fileName)) + benchmarkNodeAccessors(b, sourceFile.AsNode()) + }) + } +} + +func benchmarkNodeAccessors(b *testing.B, root *ast.Node) { + var nodes, named, declarations, containers []*ast.Node + var visit ast.Visitor + visit = func(node *ast.Node) bool { + nodes = append(nodes, node) + if node.Name() != nil { + named = append(named, node) + } + if node.DeclarationData() != nil { + declarations = append(declarations, node) + } + if node.LocalsContainerData() != nil { + containers = append(containers, node) + } + node.ForEachChild(visit) + return false + } + visit(root) + + b.Run("Name", func(b *testing.B) { + for b.Loop() { + for _, node := range nodes { + accessorName = node.Name() + } + } + b.ReportMetric(float64(b.Elapsed().Nanoseconds())/float64(b.N*len(nodes)), "ns/node") + }) + b.Run("Modifiers", func(b *testing.B) { + for b.Loop() { + for _, node := range nodes { + accessorModifiers = node.Modifiers() + } + } + b.ReportMetric(float64(b.Elapsed().Nanoseconds())/float64(b.N*len(nodes)), "ns/node") + }) + b.Run("DeclarationData", func(b *testing.B) { + for b.Loop() { + for _, node := range nodes { + accessorDeclaration = node.DeclarationData() + } + } + b.ReportMetric(float64(b.Elapsed().Nanoseconds())/float64(b.N*len(nodes)), "ns/node") + }) + b.Run("LocalsContainerData", func(b *testing.B) { + for b.Loop() { + for _, node := range nodes { + accessorLocals = node.LocalsContainerData() + } + } + b.ReportMetric(float64(b.Elapsed().Nanoseconds())/float64(b.N*len(nodes)), "ns/node") + }) + b.Run("NamePresent", func(b *testing.B) { + if len(named) == 0 { + b.Skip("fixture has no named nodes") + } + for b.Loop() { + for _, node := range named { + accessorName = node.Name() + } + } + b.ReportMetric(float64(b.Elapsed().Nanoseconds())/float64(b.N*len(named)), "ns/node") + }) + b.Run("DeclarationDataPresent", func(b *testing.B) { + if len(declarations) == 0 { + b.Skip("fixture has no declaration data") + } + for b.Loop() { + for _, node := range declarations { + accessorDeclaration = node.DeclarationData() + } + } + b.ReportMetric(float64(b.Elapsed().Nanoseconds())/float64(b.N*len(declarations)), "ns/node") + }) + b.Run("LocalsContainerDataPresent", func(b *testing.B) { + if len(containers) == 0 { + b.Skip("fixture has no locals containers") + } + for b.Loop() { + for _, node := range containers { + accessorLocals = node.LocalsContainerData() + } + } + b.ReportMetric(float64(b.Elapsed().Nanoseconds())/float64(b.N*len(containers)), "ns/node") + }) +} diff --git a/tsc/internal/ast/nodeaccessors_test.go b/tsc/internal/ast/nodeaccessors_test.go new file mode 100644 index 0000000000000..f842ed1fc2f89 --- /dev/null +++ b/tsc/internal/ast/nodeaccessors_test.go @@ -0,0 +1,177 @@ +package ast_test + +import ( + "reflect" + "runtime" + "slices" + "testing" + "unsafe" + + "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/testutil" + "gotest.tools/v3/assert" +) + +func TestNodeFactoryKinds(t *testing.T) { + t.Parallel() + for _, test := range []struct { + name string + kinds []ast.Kind + }{ + {"ForInOrOfStatement", []ast.Kind{ast.KindForInStatement, ast.KindForOfStatement}}, + {"CaseOrDefaultClause", []ast.Kind{ast.KindCaseClause, ast.KindDefaultClause}}, + {"BindingPattern", []ast.Kind{ast.KindArrayBindingPattern, ast.KindObjectBindingPattern}}, + {"KeywordExpression", []ast.Kind{ast.KindFalseKeyword, ast.KindImportKeyword, ast.KindNullKeyword, ast.KindSuperKeyword, ast.KindThisKeyword, ast.KindTrueKeyword}}, + {"KeywordTypeNode", []ast.Kind{ast.KindVoidKeyword, ast.KindAnyKeyword, ast.KindBooleanKeyword, ast.KindIntrinsicKeyword, ast.KindNeverKeyword, ast.KindNumberKeyword, ast.KindObjectKeyword, ast.KindStringKeyword, ast.KindSymbolKeyword, ast.KindUndefinedKeyword, ast.KindUnknownKeyword, ast.KindBigIntKeyword}}, + {"JSDocParameterOrPropertyTag", []ast.Kind{ast.KindJSDocParameterTag, ast.KindJSDocPropertyTag}}, + } { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + factory := reflect.ValueOf(ast.NewNodeFactory(ast.NodeFactoryHooks{})) + constructor := factory.MethodByName("New" + test.name) + args := make([]reflect.Value, constructor.Type().NumIn()) + for i := range args { + args[i] = reflect.Zero(constructor.Type().In(i)) + } + for kind := ast.Kind(-1); kind <= ast.KindCount+2; kind++ { + args[0] = reflect.ValueOf(kind) + var node *ast.Node + panicked := func() (panicked bool) { + defer func() { panicked = recover() != nil }() + node = constructor.Call(args)[0].Interface().(*ast.Node) + return false + }() + valid := slices.Contains(test.kinds, kind) + if panicked == valid { + t.Fatalf("New%s(%v): valid=%v, panicked=%v", test.name, kind, valid, panicked) + } + if valid { + assert.Equal(t, node.Kind, kind) + assert.Assert(t, reflect.ValueOf(node).MethodByName("As" + test.name).Call(nil)[0].Pointer() != 0) + } + } + }) + } +} + +func TestNodeAccessors(t *testing.T) { + t.Parallel() + factory := ast.NewNodeFactory(ast.NodeFactoryHooks{}) + name := factory.NewIdentifier("f") + modifiers := factory.NewModifierList([]*ast.Node{factory.NewToken(ast.KindExportKeyword)}) + node := factory.NewFunctionDeclaration(modifiers, nil, name, nil, nil, nil, nil, nil) + data := node.AsFunctionDeclaration() + + assert.Equal(t, node.Name(), name) + assert.Equal(t, node.Modifiers(), modifiers) + assert.Equal(t, node.DeclarationData(), &data.DeclarationBase) + assert.Equal(t, node.ExportableData(), &data.ExportableBase) + assert.Equal(t, node.FlowNodeData(), &data.FlowNodeBase) + assert.Equal(t, node.LocalsContainerData(), &data.LocalsContainerBase) + assert.Equal(t, node.FunctionLikeData(), &data.FunctionLikeBase) + assert.Equal(t, node.BodyData(), &data.BodyBase) + assert.Equal(t, node.LiteralLikeData(), (*ast.LiteralLikeNodeBase)(nil)) + + literal := factory.NewStringLiteral("text", ast.TokenFlagsNone) + assert.Equal(t, literal.LiteralLikeData(), &literal.AsStringLiteral().LiteralLikeNodeBase) +} + +func TestNodeAccessorsSharedKinds(t *testing.T) { + t.Parallel() + factory := ast.NewNodeFactory(ast.NodeFactoryHooks{}) + name := factory.NewIdentifier("T") + modifiers := factory.NewModifierList([]*ast.Node{factory.NewToken(ast.KindExportKeyword)}) + for _, node := range []*ast.Node{ + factory.NewTypeAliasDeclaration(modifiers, name, nil, nil), + factory.NewJSTypeAliasDeclaration(modifiers, name, nil, nil), + } { + data := node.AsTypeAliasDeclaration() + assert.Equal(t, node.Name(), name) + assert.Equal(t, node.Modifiers(), modifiers) + assert.Equal(t, node.DeclarationData(), &data.DeclarationBase) + assert.Equal(t, node.ExportableData(), &data.ExportableBase) + assert.Equal(t, node.FlowNodeData(), &data.FlowNodeBase) + } +} + +func TestNodeAccessorsMissing(t *testing.T) { + t.Parallel() + factory := ast.NewNodeFactory(ast.NodeFactoryHooks{}) + nodes := []*ast.Node{ + factory.NewToken(ast.KindUnknown), + factory.NewToken(ast.KindEndOfFile), + factory.NewToken(ast.KindPlusToken), + ast.NewFlowSwitchClauseData(nil, 0, 0), + ast.NewFlowReduceLabelData(nil, nil), + } + + for _, node := range nodes { + t.Run(node.Kind.String(), func(t *testing.T) { + t.Parallel() + assert.Equal(t, node.Name(), (*ast.Node)(nil)) + assert.Equal(t, node.Modifiers(), (*ast.ModifierList)(nil)) + assert.Equal(t, node.DeclarationData(), (*ast.DeclarationBase)(nil)) + assert.Equal(t, node.ExportableData(), (*ast.ExportableBase)(nil)) + assert.Equal(t, node.FlowNodeData(), (*ast.FlowNodeBase)(nil)) + assert.Equal(t, node.LocalsContainerData(), (*ast.LocalsContainerBase)(nil)) + assert.Equal(t, node.FunctionLikeData(), (*ast.FunctionLikeBase)(nil)) + assert.Equal(t, node.BodyData(), (*ast.BodyBase)(nil)) + assert.Equal(t, node.LiteralLikeData(), (*ast.LiteralLikeNodeBase)(nil)) + }) + } +} + +func TestNodeHeaderLayout(t *testing.T) { + t.Parallel() + assert.Equal(t, unsafe.Sizeof(ast.Node{}), uintptr(32)) + assert.Equal(t, unsafe.Offsetof(ast.Identifier{}.Node), uintptr(0)) + assert.Equal(t, unsafe.Offsetof(ast.SourceFile{}.Node), uintptr(0)) + assert.Equal(t, unsafe.Offsetof(ast.FlowSwitchClauseData{}.Node), uintptr(0)) + assert.Equal(t, unsafe.Offsetof(ast.FlowReduceLabelData{}.Node), uintptr(0)) +} + +func TestNodeCastRejectsWrongKind(t *testing.T) { + t.Parallel() + factory := ast.NewNodeFactory(ast.NodeFactoryHooks{}) + identifier := factory.NewIdentifier("name") + testutil.AssertPanics(t, func() { + identifier.AsStringLiteral() + }, "Invalid node cast to StringLiteral") + literal := factory.NewStringLiteral("name", ast.TokenFlagsNone) + testutil.AssertPanics(t, func() { + literal.AsIdentifier() + }, "Invalid node cast to Identifier") + testutil.AssertPanics(t, func() { + factory.NewToken(ast.KindPlusToken).AsFlowSwitchClauseData() + }, "Invalid node cast to FlowSwitchClauseData") + for _, kind := range []ast.Kind{ast.KindIdentifier, ast.KindStringLiteral, ast.KindTrueKeyword, ast.KindAnyKeyword} { + testutil.AssertPanics(t, func() { + factory.NewToken(kind).AsToken() + }, "Invalid node cast to Token") + } + assert.Equal(t, factory.NewToken(ast.KindPlusToken).AsToken().Kind, ast.KindPlusToken) + testutil.AssertPanics(t, func() { + factory.NewToken(ast.KindFunctionDeclaration) + }, "Invalid token kind") +} + +func TestNodeHeaderKeepsPayloadAlive(t *testing.T) { + t.Parallel() + factory := ast.NewNodeFactory(ast.NodeFactoryHooks{}) + name := factory.NewIdentifier("property") + root := factory.NewPropertyAccessExpression(factory.NewIdentifier("object"), nil, name, ast.NodeFlagsNone) + name.Parent = root + for range 1000 { + factory.NewPropertyAccessExpression(factory.NewIdentifier("other"), nil, factory.NewIdentifier("field"), ast.NodeFlagsNone) + } + factory = nil + runtime.GC() + assert.Equal(t, root.AsPropertyAccessExpression().Name(), name) + assert.Equal(t, name.AsIdentifier().Text, "property") + assert.Equal(t, name.Parent, root) + clone := root.Clone(ast.NewNodeFactory(ast.NodeFactoryHooks{})) + runtime.GC() + assert.Assert(t, clone != root) + assert.Equal(t, clone.AsPropertyAccessExpression().Name(), name) + assert.Equal(t, clone.AsPropertyAccessExpression().Expression.Text(), "object") +} diff --git a/tsc/internal/ast/symbol.go b/tsc/internal/ast/symbol.go index 95cb4f2154d27..00312310691c5 100644 --- a/tsc/internal/ast/symbol.go +++ b/tsc/internal/ast/symbol.go @@ -4,6 +4,7 @@ import ( "strings" "sync/atomic" + "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/debug" ) @@ -23,10 +24,20 @@ type symbolData struct { name string declarations []*Node valueDeclaration *Node - members SymbolTable - exports SymbolTable parent *Symbol - exportSymbol *Symbol + extra *symbolExtra +} + +type symbolExtra struct { + members SymbolTable + exports SymbolTable + exportSymbol *Symbol +} + +// SymbolExtraArena batches optional symbol metadata without adding an allocator +// pointer to every symbol. References from symbolData keep its blocks alive. +type SymbolExtraArena struct { + arena core.Arena[symbolExtra] } func (s *Symbol) Flags() SymbolFlags { return s.flags } @@ -34,20 +45,60 @@ func (s *Symbol) CheckFlags() CheckFlags { return s.checkFlags } func (s *Symbol) Name() string { return s.data.name } func (s *Symbol) Declarations() []*Node { return s.data.declarations } func (s *Symbol) ValueDeclaration() *Node { return s.data.valueDeclaration } -func (s *Symbol) Members() SymbolTable { return s.data.members } -func (s *Symbol) Exports() SymbolTable { return s.data.exports } func (s *Symbol) Parent() *Symbol { return s.data.parent } -func (s *Symbol) ExportSymbol() *Symbol { return s.data.exportSymbol } + +func (s *Symbol) Members() SymbolTable { + if s.data.extra == nil { + return nil + } + return s.data.extra.members +} + +func (s *Symbol) Exports() SymbolTable { + if s.data.extra == nil { + return nil + } + return s.data.extra.exports +} + +func (s *Symbol) ExportSymbol() *Symbol { + if s.data.extra == nil { + return nil + } + return s.data.extra.exportSymbol +} func (s *Symbol) SetFlags(value SymbolFlags) { s.flags = value } func (s *Symbol) SetCheckFlags(value CheckFlags) { s.checkFlags = value } func (s *Symbol) SetName(value string) { s.data.name = value } func (s *Symbol) SetDeclarations(value []*Node) { s.data.declarations = value } func (s *Symbol) SetValueDeclaration(value *Node) { s.data.valueDeclaration = value } -func (s *Symbol) SetMembers(value SymbolTable) { s.data.members = value } -func (s *Symbol) SetExports(value SymbolTable) { s.data.exports = value } func (s *Symbol) SetParent(value *Symbol) { s.data.parent = value } -func (s *Symbol) SetExportSymbol(value *Symbol) { s.data.exportSymbol = value } + +func (s *Symbol) ensureExtra(arena *SymbolExtraArena) *symbolExtra { + if s.data.extra == nil { + s.data.extra = arena.arena.New() + } + return s.data.extra +} + +func (s *Symbol) SetMembers(value SymbolTable, arena *SymbolExtraArena) { + if value != nil || s.data.extra != nil { + s.ensureExtra(arena).members = value + } +} + +func (s *Symbol) SetExports(value SymbolTable, arena *SymbolExtraArena) { + if value != nil || s.data.extra != nil { + s.ensureExtra(arena).exports = value + } +} + +func (s *Symbol) SetExportSymbol(value *Symbol, arena *SymbolExtraArena) { + if value != nil || s.data.extra != nil { + s.ensureExtra(arena).exportSymbol = value + } +} // SymbolWithData is a helper structure that contains both a Symbol and its associated symbolData. type SymbolWithData struct { diff --git a/tsc/internal/ast/symbol_test.go b/tsc/internal/ast/symbol_test.go index 3c1997e352b20..1f8f44aaa66d2 100644 --- a/tsc/internal/ast/symbol_test.go +++ b/tsc/internal/ast/symbol_test.go @@ -2,7 +2,9 @@ package ast_test import ( "reflect" + "runtime" "testing" + "unsafe" "github.com/microsoft/TypeScript/tsc/internal/ast" "gotest.tools/v3/assert" @@ -17,6 +19,7 @@ func TestSymbolFieldsArePrivate(t *testing.T) { func TestSymbolAccessors(t *testing.T) { t.Parallel() + var arena ast.SymbolExtraArena symbol := ast.NewSymbol() assert.Equal(t, symbol.Flags(), ast.SymbolFlagsNone) assert.Equal(t, symbol.CheckFlags(), ast.CheckFlags(0)) @@ -43,10 +46,10 @@ func TestSymbolAccessors(t *testing.T) { symbol.SetName("C") symbol.SetDeclarations(declarations) symbol.SetValueDeclaration(declaration) - symbol.SetMembers(members) - symbol.SetExports(exports) + symbol.SetMembers(members, &arena) + symbol.SetExports(exports, &arena) symbol.SetParent(parent) - symbol.SetExportSymbol(exportSymbol) + symbol.SetExportSymbol(exportSymbol, &arena) assert.Equal(t, symbol.Flags(), ast.SymbolFlagsClass|ast.SymbolFlagsTransient) assert.Equal(t, symbol.CheckFlags(), ast.CheckFlagsReadonly) @@ -72,10 +75,10 @@ func TestSymbolAccessors(t *testing.T) { symbol.SetName("") symbol.SetDeclarations(nil) symbol.SetValueDeclaration(nil) - symbol.SetMembers(nil) - symbol.SetExports(nil) + symbol.SetMembers(nil, &arena) + symbol.SetExports(nil, &arena) symbol.SetParent(nil) - symbol.SetExportSymbol(nil) + symbol.SetExportSymbol(nil, &arena) assert.Equal(t, symbol.Flags(), ast.SymbolFlagsNone) assert.Equal(t, symbol.CheckFlags(), ast.CheckFlags(0)) @@ -90,24 +93,76 @@ func TestSymbolAccessors(t *testing.T) { func TestSymbolTableInitialization(t *testing.T) { t.Parallel() + var arena ast.SymbolExtraArena symbol := ast.NewSymbol() member := ast.NewSymbol() export := ast.NewSymbol() - members := ast.GetMembers(symbol) + members := ast.GetMembers(symbol, &arena) members["member"] = member assert.Equal(t, symbol.Members()["member"], member) - assert.Equal(t, ast.GetMembers(symbol)["member"], member) + assert.Equal(t, ast.GetMembers(symbol, &arena)["member"], member) - exports := ast.GetExports(symbol) + exports := ast.GetExports(symbol, &arena) exports["export"] = export assert.Equal(t, symbol.Exports()["export"], export) - assert.Equal(t, ast.GetExports(symbol)["export"], export) + assert.Equal(t, ast.GetExports(symbol, &arena)["export"], export) - symbol.SetMembers(nil) - symbol.SetExports(nil) - assert.Assert(t, ast.GetMembers(symbol) != nil) - assert.Assert(t, ast.GetExports(symbol) != nil) + symbol.SetMembers(nil, &arena) + symbol.SetExports(nil, &arena) + assert.Assert(t, ast.GetMembers(symbol, &arena) != nil) + assert.Assert(t, ast.GetExports(symbol, &arena) != nil) assert.Equal(t, len(symbol.Members()), 0) assert.Equal(t, len(symbol.Exports()), 0) } + +func TestSymbolHotRecordLayout(t *testing.T) { + t.Parallel() + assert.Equal(t, unsafe.Sizeof(ast.SymbolWithData{}), unsafe.Sizeof(ast.Symbol{})+8*unsafe.Sizeof((*ast.Node)(nil))) +} + +func TestSymbolNilExtraFieldsDoNotAllocate(t *testing.T) { //nolint:paralleltest + var arena ast.SymbolExtraArena + symbol := ast.NewSymbol() + allocs := testing.AllocsPerRun(10, func() { + symbol.SetMembers(nil, &arena) + symbol.SetExports(nil, &arena) + symbol.SetExportSymbol(nil, &arena) + }) + assert.Equal(t, allocs, float64(0)) + assert.Assert(t, reflect.ValueOf(symbol).Elem().FieldByName("data").Elem().FieldByName("extra").IsNil()) +} + +func TestSymbolSharedExtraData(t *testing.T) { + t.Parallel() + var arena ast.SymbolExtraArena + var otherArena ast.SymbolExtraArena + symbol := ast.NewSymbol() + alias := ast.NewSymbol() + alias.SetSymbolData(symbol) + member := ast.NewSymbol() + export := ast.NewSymbol() + alias.SetMembers(ast.SymbolTable{"member": member}, &arena) + symbol.SetExports(ast.SymbolTable{"export": export}, &otherArena) + alias.SetExportSymbol(export, &otherArena) + runtime.GC() + assert.Equal(t, symbol.Members()["member"], member) + assert.Equal(t, alias.Exports()["export"], export) + assert.Equal(t, symbol.ExportSymbol(), export) + symbol.SetMembers(nil, &otherArena) + alias.SetExports(nil, &arena) + symbol.SetExportSymbol(nil, &arena) + assert.Assert(t, alias.Members() == nil) + assert.Assert(t, symbol.Exports() == nil) + assert.Assert(t, alias.ExportSymbol() == nil) + ast.GetMembers(alias, &otherArena)["new"] = export + ast.GetExports(symbol, &arena)["new"] = member + for range 1024 { + ast.NewSymbol().SetExports(ast.SymbolTable{"export": export}, &arena) + } + arena = ast.SymbolExtraArena{} + otherArena = ast.SymbolExtraArena{} + runtime.GC() + assert.Equal(t, symbol.Members()["new"], export) + assert.Equal(t, alias.Exports()["new"], member) +} diff --git a/tsc/internal/ast/utilities.go b/tsc/internal/ast/utilities.go index 668883c00d285..ff11fd6a2c2f4 100644 --- a/tsc/internal/ast/utilities.go +++ b/tsc/internal/ast/utilities.go @@ -99,12 +99,12 @@ func GetSymbolTable(data *SymbolTable) SymbolTable { return *data } -func GetMembers(symbol *Symbol) SymbolTable { - return GetSymbolTable(&symbol.data.members) +func GetMembers(symbol *Symbol, arena *SymbolExtraArena) SymbolTable { + return GetSymbolTable(&symbol.ensureExtra(arena).members) } -func GetExports(symbol *Symbol) SymbolTable { - return GetSymbolTable(&symbol.data.exports) +func GetExports(symbol *Symbol, arena *SymbolExtraArena) SymbolTable { + return GetSymbolTable(&symbol.ensureExtra(arena).exports) } func GetLocals(container *Node) SymbolTable { diff --git a/tsc/internal/binder/binder.go b/tsc/internal/binder/binder.go index eb9bcebe5cf35..a95bb19ecdff7 100644 --- a/tsc/internal/binder/binder.go +++ b/tsc/internal/binder/binder.go @@ -74,6 +74,7 @@ type Binder struct { symbolCount int notConstEnumOnlyModules collections.Set[*ast.Symbol] symbolWithDataArena core.Arena[ast.SymbolWithData] + symbolExtraArena ast.SymbolExtraArena flowNodeArena core.Arena[ast.FlowNode] flowListArena core.Arena[ast.FlowList] singleDeclarationsArena core.Arena[*ast.Node] @@ -379,7 +380,7 @@ func (b *Binder) declareModuleMember(node *ast.Node, symbolFlags ast.SymbolFlags hasExportModifier := ast.GetCombinedModifierFlags(node)&ast.ModifierFlagsExport != 0 || ast.IsImplicitlyExportedJSDocDeclaration(node) if symbolFlags&ast.SymbolFlagsAlias != 0 { if node.Kind == ast.KindExportSpecifier || (node.Kind == ast.KindImportEqualsDeclaration && hasExportModifier) { - return b.declareSymbol(ast.GetExports(container.Symbol()), container.Symbol(), node, symbolFlags, symbolExcludes) + return b.declareSymbol(ast.GetExports(container.Symbol(), &b.symbolExtraArena), container.Symbol(), node, symbolFlags, symbolExcludes) } return b.declareSymbol(ast.GetLocals(container), nil /*parent*/, node, symbolFlags, symbolExcludes) } @@ -400,7 +401,7 @@ func (b *Binder) declareModuleMember(node *ast.Node, symbolFlags ast.SymbolFlags // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed. if !ast.IsAmbientModule(node) && (hasExportModifier || container.Flags&ast.NodeFlagsExportContext != 0) { if !ast.IsLocalsContainer(container) || (ast.HasSyntacticModifier(node, ast.ModifierFlagsDefault) && b.getDeclarationName(node) == ast.InternalSymbolNameMissing) { - return b.declareSymbol(ast.GetExports(container.Symbol()), container.Symbol(), node, symbolFlags, symbolExcludes) + return b.declareSymbol(ast.GetExports(container.Symbol(), &b.symbolExtraArena), container.Symbol(), node, symbolFlags, symbolExcludes) // No local symbol for an unnamed default! } exportKind := ast.SymbolFlagsNone @@ -408,7 +409,7 @@ func (b *Binder) declareModuleMember(node *ast.Node, symbolFlags ast.SymbolFlags exportKind = ast.SymbolFlagsExportValue } local := b.declareSymbol(ast.GetLocals(container), nil /*parent*/, node, exportKind, symbolExcludes) - local.SetExportSymbol(b.declareSymbol(ast.GetExports(container.Symbol()), container.Symbol(), node, symbolFlags, symbolExcludes)) + local.SetExportSymbol(b.declareSymbol(ast.GetExports(container.Symbol(), &b.symbolExtraArena), container.Symbol(), node, symbolFlags, symbolExcludes), &b.symbolExtraArena) node.ExportableData().LocalSymbol = local return local } @@ -417,9 +418,9 @@ func (b *Binder) declareModuleMember(node *ast.Node, symbolFlags ast.SymbolFlags func (b *Binder) declareClassMember(node *ast.Node, symbolFlags ast.SymbolFlags, symbolExcludes ast.SymbolFlags) *ast.Symbol { if ast.IsStatic(node) { - return b.declareSymbol(ast.GetExports(b.container.Symbol()), b.container.Symbol(), node, symbolFlags, symbolExcludes) + return b.declareSymbol(ast.GetExports(b.container.Symbol(), &b.symbolExtraArena), b.container.Symbol(), node, symbolFlags, symbolExcludes) } - return b.declareSymbol(ast.GetMembers(b.container.Symbol()), b.container.Symbol(), node, symbolFlags, symbolExcludes) + return b.declareSymbol(ast.GetMembers(b.container.Symbol(), &b.symbolExtraArena), b.container.Symbol(), node, symbolFlags, symbolExcludes) } func (b *Binder) declareSourceFileMember(node *ast.Node, symbolFlags ast.SymbolFlags, symbolExcludes ast.SymbolFlags) *ast.Symbol { @@ -438,9 +439,9 @@ func (b *Binder) declareSymbolAndAddToSymbolTable(node *ast.Node, symbolFlags as case ast.KindClassExpression, ast.KindClassDeclaration: return b.declareClassMember(node, symbolFlags, symbolExcludes) case ast.KindEnumDeclaration: - return b.declareSymbol(ast.GetExports(b.container.Symbol()), b.container.Symbol(), node, symbolFlags, symbolExcludes) + return b.declareSymbol(ast.GetExports(b.container.Symbol(), &b.symbolExtraArena), b.container.Symbol(), node, symbolFlags, symbolExcludes) case ast.KindTypeLiteral, ast.KindObjectLiteralExpression, ast.KindInterfaceDeclaration, ast.KindJsxAttributes: - return b.declareSymbol(ast.GetMembers(b.container.Symbol()), b.container.Symbol(), node, symbolFlags, symbolExcludes) + return b.declareSymbol(ast.GetMembers(b.container.Symbol(), &b.symbolExtraArena), b.container.Symbol(), node, symbolFlags, symbolExcludes) case ast.KindFunctionType, ast.KindConstructorType, ast.KindCallSignature, ast.KindConstructSignature, ast.KindIndexSignature, ast.KindMethodDeclaration, ast.KindMethodSignature, ast.KindConstructor, ast.KindGetAccessor, ast.KindSetAccessor, ast.KindFunctionDeclaration, ast.KindFunctionExpression, ast.KindArrowFunction, @@ -763,7 +764,7 @@ func (b *Binder) bindSourceFileIfExternalModule() { b.bindSourceFileAsExternalModule() // Create symbol equivalent for the module.exports = {} originalSymbol := b.file.Symbol - b.declareSymbol(ast.GetExports(b.file.Symbol), b.file.Symbol, b.file.AsNode(), ast.SymbolFlagsProperty, ast.SymbolFlagsAll) + b.declareSymbol(ast.GetExports(b.file.Symbol, &b.symbolExtraArena), b.file.Symbol, b.file.AsNode(), ast.SymbolFlagsProperty, ast.SymbolFlagsAll) b.file.Symbol = originalSymbol } } @@ -853,9 +854,9 @@ func (b *Binder) bindExportDeclaration(node *ast.Node) { b.bindAnonymousDeclaration(node, ast.SymbolFlagsExportStar, b.getDeclarationName(node)) } else if decl.ExportClause == nil { // All export * declarations are collected in an __export symbol - b.declareSymbol(ast.GetExports(b.container.Symbol()), b.container.Symbol(), node, ast.SymbolFlagsExportStar, ast.SymbolFlagsNone) + b.declareSymbol(ast.GetExports(b.container.Symbol(), &b.symbolExtraArena), b.container.Symbol(), node, ast.SymbolFlagsExportStar, ast.SymbolFlagsNone) } else if ast.IsNamespaceExport(decl.ExportClause) { - b.declareSymbol(ast.GetExports(b.container.Symbol()), b.container.Symbol(), decl.ExportClause, ast.SymbolFlagsAlias, ast.SymbolFlagsAliasExcludes) + b.declareSymbol(ast.GetExports(b.container.Symbol(), &b.symbolExtraArena), b.container.Symbol(), decl.ExportClause, ast.SymbolFlagsAlias, ast.SymbolFlagsAliasExcludes) } } @@ -868,7 +869,7 @@ func (b *Binder) bindExportAssignment(node *ast.Node) { // If there is an `export default x;` alias declaration, can't `export default` anything else. // (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.) flags := core.IfElse(ast.ExpressionIsAlias(node.Expression()), ast.SymbolFlagsAlias, ast.SymbolFlagsProperty) - symbol := b.declareSymbol(ast.GetExports(container.Symbol()), container.Symbol(), node, flags, ast.SymbolFlagsAll) + symbol := b.declareSymbol(ast.GetExports(container.Symbol(), &b.symbolExtraArena), container.Symbol(), node, flags, ast.SymbolFlagsAll) if node.AsExportAssignment().IsExportEquals { // Ensure export assignments have a ValueDeclaration set. SetValueDeclaration(symbol, node) @@ -967,11 +968,11 @@ func (b *Binder) bindClassLikeDeclaration(node *ast.Node) { // module might have an exported variable called 'prototype'. We can't allow that as // that would clash with the built-in 'prototype' for the class. prototypeSymbol := b.newSymbol(ast.SymbolFlagsProperty|ast.SymbolFlagsPrototype, "prototype") - symbolExport := ast.GetExports(symbol)[prototypeSymbol.Name()] + symbolExport := ast.GetExports(symbol, &b.symbolExtraArena)[prototypeSymbol.Name()] if symbolExport != nil { b.errorOnNode(symbolExport.Declarations()[0], diagnostics.Duplicate_identifier_0, ast.SymbolName(prototypeSymbol)) } - ast.GetExports(symbol)[prototypeSymbol.Name()] = prototypeSymbol + ast.GetExports(symbol, &b.symbolExtraArena)[prototypeSymbol.Name()] = prototypeSymbol prototypeSymbol.SetParent(symbol) } @@ -1000,12 +1001,12 @@ func (b *Binder) bindFunctionOrConstructorType(node *ast.Node) { b.addDeclarationToSymbol(symbol, node, ast.SymbolFlagsSignature) typeLiteralSymbol := b.newSymbol(ast.SymbolFlagsTypeLiteral, ast.InternalSymbolNameType) b.addDeclarationToSymbol(typeLiteralSymbol, node, ast.SymbolFlagsTypeLiteral) - typeLiteralSymbol.SetMembers(make(ast.SymbolTable)) + typeLiteralSymbol.SetMembers(make(ast.SymbolTable), &b.symbolExtraArena) typeLiteralSymbol.Members()[symbol.Name()] = symbol } func (b *Binder) addLateBoundAssignmentDeclarationToSymbol(node *ast.Node, symbol *ast.Symbol) { - exports := ast.GetExports(symbol) + exports := ast.GetExports(symbol, &b.symbolExtraArena) assignmentSymbol := exports[ast.InternalSymbolNameAssignmentDeclaration] if assignmentSymbol == nil { assignmentSymbol = b.newSymbol(ast.SymbolFlagsNone, ast.InternalSymbolNameAssignmentDeclaration) @@ -1018,7 +1019,7 @@ func (b *Binder) bindModuleExportsAssignment(node *ast.Node) { if b.setCommonJSModuleIndicator(node) { container := b.file.AsNode() flags := core.IfElse(ast.ExpressionIsAlias(node.AsBinaryExpression().Right), ast.SymbolFlagsAlias, ast.SymbolFlagsProperty) - symbol := b.declareSymbol(ast.GetExports(container.Symbol()), container.Symbol(), node, flags, 0) + symbol := b.declareSymbol(ast.GetExports(container.Symbol(), &b.symbolExtraArena), container.Symbol(), node, flags, 0) SetValueDeclaration(symbol, node) } } @@ -1047,7 +1048,7 @@ func (b *Binder) bindCommonJSTypeExports(moduleSymbol *ast.Symbol) { if exportEquals := moduleExports[ast.InternalSymbolNameExportEquals]; exportEquals != nil { for _, symbol := range moduleExports { if symbol.Name() != ast.InternalSymbolNameExportEquals && symbol.Flags()&(ast.SymbolFlagsType|ast.SymbolFlagsNamespace) != 0 { - ast.GetExports(exportEquals)[symbol.Name()] = symbol + ast.GetExports(exportEquals, &b.symbolExtraArena)[symbol.Name()] = symbol exportEquals.SetFlags(exportEquals.Flags() | ast.SymbolFlagsNamespaceModule) } } @@ -1066,7 +1067,7 @@ func (b *Binder) bindDeferredExpandoAssignment(node *ast.Node) { b.addLateBoundAssignmentDeclarationToSymbol(node, symbol) } else { // We declare expandos only when there are no non-expando declarations for that name. - exports := ast.GetExports(symbol) + exports := ast.GetExports(symbol, &b.symbolExtraArena) if existing := exports[b.getDeclarationName(node)]; existing == nil || existing.Flags()&ast.SymbolFlagsAssignment != 0 { b.declareSymbol(exports, symbol, node, ast.SymbolFlagsProperty|ast.SymbolFlagsAssignment, ast.SymbolFlagsPropertyExcludes) } @@ -1088,7 +1089,7 @@ func (b *Binder) bindExportsOrObjectDefineProperty(node *ast.Node) { if b.setCommonJSModuleIndicator(node) { container := b.file.AsNode() flags := core.IfElse(ast.IsBinaryExpression(node) && ast.ExpressionIsAlias(node.AsBinaryExpression().Right), ast.SymbolFlagsAlias, ast.SymbolFlagsFunctionScopedVariable) - b.declareSymbol(ast.GetExports(container.Symbol()), container.Symbol(), node, flags, ast.SymbolFlagsFunctionScopedVariableExcludes) + b.declareSymbol(ast.GetExports(container.Symbol(), &b.symbolExtraArena), container.Symbol(), node, flags, ast.SymbolFlagsFunctionScopedVariableExcludes) } } @@ -1152,9 +1153,9 @@ func (b *Binder) getThisClassAndSymbolTable() (classSymbol *ast.Symbol, symbolTa // this.property assignment in class member -- bind to the containing class classSymbol = b.thisContainer.Parent.Symbol() if ast.IsStatic(b.thisContainer) { - symbolTable = ast.GetExports(classSymbol) + symbolTable = ast.GetExports(classSymbol, &b.symbolExtraArena) } else { - symbolTable = ast.GetMembers(classSymbol) + symbolTable = ast.GetMembers(classSymbol, &b.symbolExtraArena) } } return classSymbol, symbolTable @@ -1211,7 +1212,7 @@ func (b *Binder) bindParameter(node *ast.Node) { if ast.IsParameterPropertyDeclaration(node, node.Parent) { classDeclaration := node.Parent.Parent flags := ast.SymbolFlagsProperty | core.IfElse(decl.QuestionToken != nil, ast.SymbolFlagsOptional, ast.SymbolFlagsNone) - b.declareSymbol(ast.GetMembers(classDeclaration.Symbol()), classDeclaration.Symbol(), node, flags, ast.SymbolFlagsPropertyExcludes) + b.declareSymbol(ast.GetMembers(classDeclaration.Symbol(), &b.symbolExtraArena), classDeclaration.Symbol(), node, flags, ast.SymbolFlagsPropertyExcludes) } } @@ -1635,7 +1636,7 @@ func (b *Binder) declareCommonJSVariable(name string) { exportsProperty.SetDeclarations(symbol.Declarations()) exportsProperty.SetValueDeclaration(symbol.ValueDeclaration()) exportsProperty.SetParent(symbol) - symbol.SetMembers(make(ast.SymbolTable, 1)) + symbol.SetMembers(make(ast.SymbolTable, 1), &b.symbolExtraArena) symbol.Members()["exports"] = exportsProperty } locals[name] = symbol diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index b03cebf741b22..68d421190de8b 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -285,6 +285,7 @@ type InferenceContext struct { outerReturnMapper *TypeMapper // Type mapper for inferences from return types of outer function (if any) inferredTypeParameters []*Type // Inferred type parameters for function result intraExpressionInferenceSites []IntraExpressionInferenceSite + mapperStorage [2]InferenceTypeMapper } type InferenceInfo struct { @@ -669,15 +670,35 @@ type Checker struct { suggestionDiagnostics ast.DiagnosticsCollection symbolArena core.Arena[ast.Symbol] symbolWithDataArena core.Arena[ast.SymbolWithData] + symbolExtraArena ast.SymbolExtraArena signatureArena core.Arena[Signature] + signatureExtraArena core.Arena[signatureExtra] indexInfoArena core.Arena[IndexInfo] + literalTypeArena core.Arena[LiteralType] + objectTypeArena core.Arena[ObjectType] + typeReferenceArena core.Arena[TypeReference] + interfaceTypeArena core.Arena[InterfaceType] + mappedTypeArena core.Arena[MappedType] + unionTypeArena core.Arena[UnionType] + intersectionTypeArena core.Arena[IntersectionType] + typeParameterArena core.Arena[TypeParameter] + indexedAccessTypeArena core.Arena[IndexedAccessType] + conditionalTypeArena core.Arena[ConditionalType] + typeListArena core.Arena[*Type] + outerTypeParameterListArena core.Arena[[]*Type] + valueSymbolExtraArena core.Arena[valueSymbolExtra] + structuredTypeExtraArena core.Arena[structuredTypeExtra] + memberIndexArena core.Arena[memberIndex] + memberIndexSlotsArena core.Arena[uint32] + freeTypeSets *temporaryTypeSet + freePropertyCounts *temporaryPropertyCounts mergedSymbols map[*ast.Symbol]*ast.Symbol mergedExportsChecked collections.Set[*ast.Symbol] factory ast.NodeFactory nodeLinks core.LinkStore[*ast.Node, NodeLinks] - signatureLinks core.LinkStore[*ast.Node, SignatureLinks] + signatureLinks nodeLinkStore[SignatureLinks] symbolNodeLinks nodeLinkStore[SymbolNodeLinks] - typeNodeLinks core.LinkStore[*ast.Node, TypeNodeLinks] + typeNodeLinks nodeLinkStore[TypeNodeLinks] enumMemberLinks core.LinkStore[*ast.Node, EnumMemberLinks] assertionLinks core.LinkStore[*ast.Node, AssertionLinks] arrayLiteralLinks core.LinkStore[*ast.Node, ArrayLiteralLinks] @@ -973,7 +994,7 @@ func NewChecker(program Program, tracer *Tracer) (*Checker, *sync.Mutex) { c.errorTypes = make(map[CacheHashKey]*Type) c.moduleSymbols = make(map[*ast.Node]*ast.Symbol) c.globalThisSymbol = c.newSymbolEx(ast.SymbolFlagsModule, "globalThis", ast.CheckFlagsReadonly) - c.globalThisSymbol.SetExports(c.globals) + c.globalThisSymbol.SetExports(c.globals, &c.symbolExtraArena) c.globals[c.globalThisSymbol.Name()] = c.globalThisSymbol c.resolveName = c.createNameResolver().Resolve c.resolveNameForSymbolSuggestion = c.createNameResolverForSuggestion().Resolve @@ -4370,7 +4391,7 @@ func (c *Checker) checkClassLikeDeclaration(node *ast.Node) { if len(baseTypeNode.TypeArguments()) != 0 { c.checkSourceElements(baseTypeNode.TypeArguments()) for _, constructor := range c.getConstructorsForTypeArguments(staticBaseType, baseTypeNode.TypeArguments(), baseTypeNode) { - if !c.checkTypeArgumentConstraints(baseTypeNode, constructor.typeParameters) { + if !c.checkTypeArgumentConstraints(baseTypeNode, constructor.TypeParameters()) { break } } @@ -4589,7 +4610,7 @@ func (c *Checker) getTypeWithoutSignatures(t *Type) *Type { switch { case t.flags&TypeFlagsObject != 0: resolved := c.resolveStructuredTypeMembers(t) - if len(resolved.signatures) != 0 { + if len(resolved.getSignatures()) != 0 { result := c.newObjectType(ObjectFlagsAnonymous, t.symbol) result.objectFlags |= ObjectFlagsMembersResolved result.AsObjectType().members = resolved.members @@ -7589,7 +7610,7 @@ func (c *Checker) getQuickTypeOfExpression(node *ast.Node) *Type { func (c *Checker) getReturnTypeOfSingleNonGenericSignature(funcType *Type, kind SignatureKind) *Type { signature := c.getSingleSignature(funcType, kind, true /*allowMembers*/) - if signature != nil && len(signature.typeParameters) == 0 { + if signature != nil && len(signature.TypeParameters()) == 0 { return c.getReturnTypeOfSignature(signature) } return nil @@ -7806,7 +7827,7 @@ func (c *Checker) instantiateTypeWithSingleGenericCallSignature(node *ast.Node, callSignature := c.getSingleSignature(t, SignatureKindCall, true /*allowMembers*/) constructSignature := c.getSingleSignature(t, SignatureKindConstruct, true /*allowMembers*/) signature := core.OrElse(callSignature, constructSignature) - if signature == nil || len(signature.typeParameters) == 0 { + if signature == nil || len(signature.TypeParameters()) == 0 { return t } contextualType := c.getApparentTypeOfContextualType(node, ContextFlagsNoConstraints) @@ -7814,7 +7835,7 @@ func (c *Checker) instantiateTypeWithSingleGenericCallSignature(node *ast.Node, return t } contextualSignature := c.getSingleSignature(c.GetNonNullableType(contextualType), core.IfElse(callSignature != nil, SignatureKindCall, SignatureKindConstruct), false /*allowMembers*/) - if contextualSignature == nil || len(contextualSignature.typeParameters) != 0 { + if contextualSignature == nil || len(contextualSignature.TypeParameters()) != 0 { return t } if checkMode&CheckModeSkipGenericFunctions != 0 { @@ -7835,10 +7856,10 @@ func (c *Checker) instantiateTypeWithSingleGenericCallSignature(node *ast.Node, returnSignature = c.getSingleCallOrConstructSignature(returnType) } } - if returnSignature != nil && len(returnSignature.typeParameters) == 0 && !core.Every(context.inferences, hasInferenceCandidates) { + if returnSignature != nil && len(returnSignature.TypeParameters()) == 0 && !core.Every(context.inferences, hasInferenceCandidates) { // Instantiate the signature with its own type parameters as type arguments, possibly // renaming the type parameters to ensure they have unique names. - uniqueTypeParameters := c.getUniqueTypeParameters(context, signature.typeParameters) + uniqueTypeParameters := c.getUniqueTypeParameters(context, signature.TypeParameters()) instantiatedSignature := c.getSignatureInstantiationWithoutFillingInTypeArguments(signature, uniqueTypeParameters) // Infer from the parameters of the instantiated signature to the parameters of the // contextual signature starting with an empty set of inference candidates. @@ -8927,7 +8948,7 @@ func (c *Checker) typeHasProtectedAccessibleBase(target *ast.Symbol, t *Type) bo func someSignature(signatures []*Signature, f func(s *Signature) bool) bool { for _, sig := range signatures { - if sig.composite != nil && sig.composite.isUnion && core.Some(sig.composite.signatures, f) || sig.composite == nil && f(sig) { + if sig.getComposite() != nil && sig.getComposite().isUnion && core.Some(sig.getComposite().signatures, f) || sig.getComposite() == nil && f(sig) { return true } } @@ -9098,7 +9119,7 @@ func (c *Checker) resolveCall(node *ast.Node, signatures []*Signature, candidate // // For a decorator, no arguments are susceptible to contextual typing due to the fact // decorators are applied to a declaration by the emitter, and not to an expression. - s.isSingleNonGenericCandidate = len(s.candidates) == 1 && len(s.candidates[0].typeParameters) == 0 + s.isSingleNonGenericCandidate = len(s.candidates) == 1 && len(s.candidates[0].TypeParameters()) == 0 if !isDecorator && !s.isSingleNonGenericCandidate && core.Some(s.args, c.isContextSensitive) { s.argCheckMode = CheckModeSkipContextSensitive } else { @@ -9265,7 +9286,7 @@ func (c *Checker) chooseOverload(s *CallState, relation *Relation) *Signature { } var checkCandidate *Signature var inferenceContext *InferenceContext - if len(candidate.typeParameters) != 0 { + if len(candidate.TypeParameters()) != 0 { var typeArgumentTypes []*Type if len(s.typeArguments) != 0 { typeArgumentTypes = c.checkTypeArguments(candidate, s.typeArguments, false /*reportErrors*/, nil) @@ -9278,7 +9299,7 @@ func (c *Checker) chooseOverload(s *CallState, relation *Relation) *Signature { // type inference to avoid circularity errors. For example, see #64192. inferenceFlags := core.IfElse(s.recursiveResolution && len(s.candidates) == 1, InferenceFlagsNoConstraintChecks, InferenceFlagsNone) | core.IfElse(ast.IsInJSFile(s.node), InferenceFlagsAnyDefault, InferenceFlagsNone) - inferenceContext = c.newInferenceContext(candidate.typeParameters, candidate, inferenceFlags /*flags*/, nil) + inferenceContext = c.newInferenceContext(candidate.TypeParameters(), candidate, inferenceFlags /*flags*/, nil) typeArgumentTypes = c.inferTypeArguments(s.node, candidate, s.args, s.argCheckMode|CheckModeSkipGenericFunctions, inferenceContext) if inferenceContext.flags&InferenceFlagsSkippedGenericFunction != 0 { s.argCheckMode |= CheckModeSkipGenericFunctions @@ -9440,14 +9461,14 @@ func (c *Checker) getLegacyDecoratorArgumentCount(node *ast.Node, signature *Sig func (c *Checker) hasCorrectTypeArgumentArity(signature *Signature, typeArguments []*ast.Node) bool { // If the user supplied type arguments, but the number of type arguments does not match // the declared number of type parameters, the call has an incorrect arity. - numTypeParameters := len(signature.typeParameters) - minTypeArgumentCount := c.getMinTypeArgumentCount(signature.typeParameters) + numTypeParameters := len(signature.TypeParameters()) + minTypeArgumentCount := c.getMinTypeArgumentCount(signature.TypeParameters()) return len(typeArguments) == 0 || len(typeArguments) >= minTypeArgumentCount && len(typeArguments) <= numTypeParameters } func (c *Checker) checkTypeArguments(signature *Signature, typeArgumentNodes []*ast.Node, reportErrors bool, headMessage *diagnostics.Message) []*Type { isJavaScript := ast.IsInJSFile(signature.declaration) - typeParameters := signature.typeParameters + typeParameters := signature.TypeParameters() typeArgumentTypes := c.fillMissingTypeArguments(core.Map(typeArgumentNodes, c.getTypeFromTypeNode), typeParameters, c.getMinTypeArgumentCount(typeParameters), isJavaScript) var mapper *TypeMapper for i := range typeArgumentNodes { @@ -9622,7 +9643,7 @@ func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the // return type of 'wrap'. if !ast.IsDecorator(node) && !ast.IsBinaryExpression(node) { - skipBindingPatterns := core.Every(signature.typeParameters, func(p *Type) bool { return c.getDefaultFromTypeParameter(p) != nil }) + skipBindingPatterns := core.Every(signature.TypeParameters(), func(p *Type) bool { return c.getDefaultFromTypeParameter(p) != nil }) contextualType := c.getContextualType(node, core.IfElse(skipBindingPatterns, ContextFlagsSkipBindingPatterns, ContextFlagsNone)) if contextualType != nil { inferenceTargetType := c.getReturnTypeOfSignature(signature) @@ -9654,8 +9675,8 @@ func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args // Above, the type of the 'value' parameter is inferred to be 'A'. contextualSignature := c.getSingleCallSignature(instantiatedType) var inferenceSourceType *Type - if contextualSignature != nil && len(contextualSignature.typeParameters) != 0 { - inferenceSourceType = c.getOrCreateTypeFromSignature(c.getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) + if contextualSignature != nil && len(contextualSignature.TypeParameters()) != 0 { + inferenceSourceType = c.getOrCreateTypeFromSignature(c.getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.TypeParameters())) } else { inferenceSourceType = instantiatedType } @@ -9670,7 +9691,7 @@ func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args // replaced with inferences produced from the outer return type or preceding outer arguments. // This protects against circular inferences, i.e. avoiding situations where inferences reference // type parameters for which the inferences are being made. - returnContext := c.newInferenceContext(signature.typeParameters, signature, context.flags, nil) + returnContext := c.newInferenceContext(signature.TypeParameters(), signature, context.flags, nil) var outerReturnMapper *TypeMapper if outerContext != nil { outerReturnMapper = c.createOuterReturnMapper(outerContext) @@ -9727,7 +9748,7 @@ func (c *Checker) getCandidateForOverloadFailure(node *ast.Node, candidates []*S // Normally we will combine overloads. Skip this if they have type parameters since that's hard to combine. // Don't do this if there is a `candidatesOutArray`, // because then we want the chosen best candidate to be one of the overloads, not a combination. - if hasCandidatesOutArray || len(candidates) == 1 || core.Some(candidates, func(s *Signature) bool { return len(s.typeParameters) != 0 }) { + if hasCandidatesOutArray || len(candidates) == 1 || core.Some(candidates, func(s *Signature) bool { return len(s.TypeParameters()) != 0 }) { return c.pickLongestCandidateSignature(node, candidates, args, checkMode) } return c.createUnionOfSignaturesForOverloadFailure(candidates) @@ -9746,7 +9767,7 @@ func (c *Checker) pickLongestCandidateSignature(node *ast.Node, candidates []*Si } bestIndex := c.getLongestCandidateIndex(candidates, argCount) candidate := candidates[bestIndex] - typeParameters := candidate.typeParameters + typeParameters := candidate.TypeParameters() if len(typeParameters) == 0 { return candidate } @@ -9805,7 +9826,7 @@ func (c *Checker) inferSignatureInstantiationForOverloadFailure(node *ast.Node, } func (c *Checker) createUnionOfSignaturesForOverloadFailure(candidates []*Signature) *Signature { - thisParameters := core.MapNonNil(candidates, func(c *Signature) *ast.Symbol { return c.thisParameter }) + thisParameters := core.MapNonNil(candidates, func(c *Signature) *ast.Symbol { return c.ThisParameter() }) var thisParameter *ast.Symbol if len(thisParameters) != 0 { thisParameter = c.createCombinedSymbolFromTypes(thisParameters, core.Map(thisParameters, c.getTypeOfParameter)) @@ -9919,7 +9940,7 @@ func (c *Checker) addImplementationSuccessElaboration(s *CallState, failed *Sign candidate := c.getSignatureFromDeclaration(implementation) localState := *s localState.candidates = []*Signature{candidate} - localState.isSingleNonGenericCandidate = len(candidate.typeParameters) == 0 + localState.isSingleNonGenericCandidate = len(candidate.TypeParameters()) == 0 if c.chooseOverload(&localState, c.assignableRelation) != nil { diagnostic.AddRelatedInfo(NewDiagnosticForNode(implementation, diagnostics.The_call_would_have_succeeded_against_this_implementation_but_implementation_signatures_of_overloads_are_not_externally_visible)) } @@ -10001,7 +10022,7 @@ func (c *Checker) getArgumentArityError(node *ast.Node, signatures []*Signature, } var parameter *ast.Node if closestSignature != nil && closestSignature.declaration != nil { - parameter = core.ElementOrNil(closestSignature.declaration.Parameters(), len(args)+core.IfElse(closestSignature.thisParameter != nil, 1, 0)) + parameter = core.ElementOrNil(closestSignature.declaration.Parameters(), len(args)+core.IfElse(closestSignature.ThisParameter() != nil, 1, 0)) } if parameter != nil { var related *ast.Diagnostic @@ -10085,8 +10106,8 @@ func (c *Checker) getTypeArgumentArityError(node *ast.Node, signatures []*Signat if len(signatures) == 1 { // No overloads exist sig := signatures[0] - minCount := c.getMinTypeArgumentCount(sig.typeParameters) - maxCount := len(sig.typeParameters) + minCount := c.getMinTypeArgumentCount(sig.TypeParameters()) + maxCount := len(sig.TypeParameters()) expected := strconv.Itoa(minCount) if minCount < maxCount { expected = expected + "-" + strconv.Itoa(maxCount) @@ -10097,8 +10118,8 @@ func (c *Checker) getTypeArgumentArityError(node *ast.Node, signatures []*Signat belowArgCount := math.MinInt aboveArgCount := math.MaxInt for _, sig := range signatures { - minCount := c.getMinTypeArgumentCount(sig.typeParameters) - maxCount := len(sig.typeParameters) + minCount := c.getMinTypeArgumentCount(sig.TypeParameters()) + maxCount := len(sig.TypeParameters()) if minCount > argCount { aboveArgCount = min(aboveArgCount, minCount) } else if maxCount < argCount { @@ -10245,7 +10266,7 @@ func (c *Checker) invocationErrorRecovery(apparentType *Type, kind SignatureKind } func (c *Checker) isGenericFunctionReturningFunction(signature *Signature) bool { - return len(signature.typeParameters) != 0 && c.isFunctionType(c.getReturnTypeOfSignature(signature)) + return len(signature.TypeParameters()) != 0 && c.isFunctionType(c.getReturnTypeOfSignature(signature)) } func (c *Checker) skippedGenericFunction(node *ast.Node, checkMode CheckMode) { @@ -10526,7 +10547,7 @@ func (c *Checker) getContextualSignature(node *ast.Node) *Signature { func (c *Checker) createUnionSignature(sig *Signature, unionSignatures []*Signature) *Signature { result := c.cloneSignature(sig) - result.composite = &CompositeSignature{isUnion: true, signatures: unionSignatures} + result.setComposite(c, &CompositeSignature{isUnion: true, signatures: unionSignatures}) result.target = nil result.mapper = nil return result @@ -10552,7 +10573,7 @@ func (c *Checker) getIntersectedSignatures(signatures []*Signature) *Signature { switch { case combined == sig || combined == nil: combined = sig - case c.compareTypeParametersIdentical(combined.typeParameters, sig.typeParameters): + case c.compareTypeParametersIdentical(combined.TypeParameters(), sig.TypeParameters()): combined = c.combineUnionOrIntersectionMemberSignatures(combined, sig, false /*isUnion*/) default: return nil @@ -10579,20 +10600,20 @@ func (c *Checker) isAritySmaller(signature *Signature, target *ast.Node) bool { } func (c *Checker) assignContextualParameterTypes(sig *Signature, context *Signature) { - if len(context.typeParameters) != 0 { - if len(sig.typeParameters) != 0 { + if len(context.TypeParameters()) != 0 { + if len(sig.TypeParameters()) != 0 { // This signature has already has a contextual inference performed and cached on it return } - sig.typeParameters = context.typeParameters + sig.setTypeParameters(c, context.TypeParameters()) } - if context.thisParameter != nil { - parameter := sig.thisParameter + if context.ThisParameter() != nil { + parameter := sig.ThisParameter() if parameter == nil || parameter.ValueDeclaration() != nil && parameter.ValueDeclaration().Type() == nil { if parameter == nil { - sig.thisParameter = c.createSymbolWithType(context.thisParameter, nil /*type*/) + sig.setThisParameter(c, c.createSymbolWithType(context.ThisParameter(), nil /*type*/)) } - c.assignParameterType(sig.thisParameter, c.getTypeOfSymbol(context.thisParameter)) + c.assignParameterType(sig.ThisParameter(), c.getTypeOfSymbol(context.ThisParameter())) } } length := len(sig.parameters) - core.IfElse(signatureHasRestParameter(sig), 1, 0) @@ -10625,8 +10646,8 @@ func (c *Checker) assignContextualParameterTypes(sig *Signature, context *Signat } func (c *Checker) assignNonContextualParameterTypes(signature *Signature) { - if signature.thisParameter != nil { - c.assignParameterType(signature.thisParameter, nil) + if signature.ThisParameter() != nil { + c.assignParameterType(signature.ThisParameter(), nil) } for _, parameter := range signature.parameters { c.assignParameterType(parameter, nil) @@ -10902,7 +10923,7 @@ func (c *Checker) getInstantiationExpressionType(exprType *Type, node *ast.Node) var nonApplicableType *Type getInstantiatedSignatures := func(signatures []*Signature) []*Signature { applicableSignatures := core.Filter(signatures, func(sig *Signature) bool { - return len(sig.typeParameters) != 0 && c.hasCorrectTypeArgumentArity(sig, typeArguments.Nodes) + return len(sig.TypeParameters()) != 0 && c.hasCorrectTypeArgumentArity(sig, typeArguments.Nodes) }) return core.SameMap(applicableSignatures, func(sig *Signature) *Signature { typeArgumentTypes := c.checkTypeArguments(sig, typeArguments.Nodes, true /*reportErrors*/, nil) @@ -10929,7 +10950,7 @@ func (c *Checker) getInstantiationExpressionType(exprType *Type, node *ast.Node) debug.Assert(t.symbol != nil, "Instantiation expression source type must have a symbol") symbol.SetDeclarations(t.symbol.Declarations()) result := c.newObjectType(ObjectFlagsAnonymous|ObjectFlagsInstantiationExpressionType, symbol) - c.setStructuredTypeMembers(result, resolved.members, callSignatures, constructSignatures, resolved.indexInfos) + c.setStructuredTypeMembers(result, resolved.getMembers(), callSignatures, constructSignatures, resolved.getIndexInfos()) result.AsInstantiationExpressionType().node = node return result } @@ -12147,7 +12168,7 @@ func (c *Checker) forEachProperty(prop *ast.Symbol, callback func(p *ast.Symbol) if prop.CheckFlags()&ast.CheckFlagsSynthetic == 0 { return callback(prop) } - for _, t := range c.valueSymbolLinks.Get(prop).containingType.Types() { + for _, t := range c.valueSymbolLinks.Get(prop).getContainingType().Types() { p := c.getPropertyOfType(t, prop.Name()) if p != nil && c.forEachProperty(p, callback) { return true @@ -12265,7 +12286,7 @@ func (c *Checker) getContextualThisParameterType(fn *ast.Node) *Type { if c.isContextSensitiveFunctionOrObjectLiteralMethod(fn) { contextualSignature := c.getContextualSignature(fn) if contextualSignature != nil { - thisParameter := contextualSignature.thisParameter + thisParameter := contextualSignature.ThisParameter() if thisParameter != nil { return c.getTypeOfSymbol(thisParameter) } @@ -13489,7 +13510,7 @@ func (c *Checker) checkObjectLiteral(node *ast.Node, checkMode CheckMode) *Type } links := c.valueSymbolLinks.Get(prop) if nameType != nil { - links.nameType = nameType + links.setNameType(c, nameType) } if inDestructuringPattern && c.hasDefaultValue(memberDecl) { // If object literal is an assignment pattern and if the assignment pattern specifies a default value @@ -13734,7 +13755,7 @@ func (c *Checker) getSpreadType(left *Type, right *Type, symbol *ast.Symbol, obj c.spreadLinks.Get(result).leftSpread = leftProp c.spreadLinks.Get(result).rightSpread = rightProp result.SetDeclarations(declarations) - links.nameType = c.valueSymbolLinks.Get(leftProp).nameType + links.setNameType(c, c.valueSymbolLinks.Get(leftProp).getNameType()) members[leftProp.Name()] = result } } else { @@ -13821,7 +13842,7 @@ func (c *Checker) tryMergeUnionOfObjectTypeAndEmptyObject(t *Type, readonly bool links.resolvedType = c.addOptionalityEx(c.getTypeOfSymbol(prop), true /*isProperty*/, true /*isOptional*/) } result.SetDeclarations(prop.Declarations()) - links.nameType = c.valueSymbolLinks.Get(prop).nameType + links.setNameType(c, c.valueSymbolLinks.Get(prop).getNameType()) c.mappedSymbolLinks.Get(result).syntheticOrigin = prop members[prop.Name()] = result } @@ -13851,7 +13872,7 @@ func (c *Checker) getSpreadSymbol(prop *ast.Symbol, readonly bool) *ast.Symbol { links.resolvedType = c.getTypeOfSymbol(prop) } result.SetDeclarations(prop.Declarations()) - links.nameType = c.valueSymbolLinks.Get(prop).nameType + links.setNameType(c, c.valueSymbolLinks.Get(prop).getNameType()) c.mappedSymbolLinks.Get(result).syntheticOrigin = prop return result } @@ -14457,10 +14478,10 @@ func (c *Checker) mergeSymbol(target *ast.Symbol, source *ast.Symbol, unidirecti } target.SetDeclarations(append(target.Declarations(), source.Declarations()...)) if source.Members() != nil { - c.mergeSymbolTable(ast.GetMembers(target), source.Members(), unidirectional, nil) + c.mergeSymbolTable(ast.GetMembers(target, &c.symbolExtraArena), source.Members(), unidirectional, nil) } if source.Exports() != nil { - c.mergeSymbolTable(ast.GetExports(target), source.Exports(), unidirectional, target) + c.mergeSymbolTable(ast.GetExports(target, &c.symbolExtraArena), source.Exports(), unidirectional, target) } if !unidirectional { c.recordMergedSymbol(target, source) @@ -14620,8 +14641,8 @@ func (c *Checker) cloneSymbol(symbol *ast.Symbol) *ast.Symbol { result.SetDeclarations(symbol.Declarations()[0:len(symbol.Declarations()):len(symbol.Declarations())]) result.SetParent(symbol.Parent()) result.SetValueDeclaration(symbol.ValueDeclaration()) - result.SetMembers(maps.Clone(symbol.Members())) - result.SetExports(maps.Clone(symbol.Exports())) + result.SetMembers(maps.Clone(symbol.Members()), &c.symbolExtraArena) + result.SetExports(maps.Clone(symbol.Exports()), &c.symbolExtraArena) c.recordMergedSymbol(result, symbol) return result } @@ -15084,8 +15105,8 @@ func (c *Checker) combineValueAndTypeSymbols(valueSymbol *ast.Symbol, typeSymbol result.SetParent(typeSymbol.Parent()) } result.SetValueDeclaration(valueSymbol.ValueDeclaration()) - result.SetMembers(maps.Clone(typeSymbol.Members())) - result.SetExports(maps.Clone(valueSymbol.Exports())) + result.SetMembers(maps.Clone(typeSymbol.Members()), &c.symbolExtraArena) + result.SetExports(maps.Clone(valueSymbol.Exports()), &c.symbolExtraArena) return result } @@ -16103,7 +16124,7 @@ func (c *Checker) createDefaultPropertyWrapperForModule(symbol *ast.Symbol, orig memberTable := make(ast.SymbolTable) newSymbol := c.newSymbol(ast.SymbolFlagsAlias, ast.InternalSymbolNameDefault) newSymbol.SetParent(originalSymbol) - c.valueSymbolLinks.Get(newSymbol).nameType = c.getStringLiteralType("default") + c.valueSymbolLinks.Get(newSymbol).setNameType(c, c.getStringLiteralType("default")) c.aliasSymbolLinks.Get(newSymbol).aliasTarget = c.resolveSymbol(symbol) memberTable[ast.InternalSymbolNameDefault] = newSymbol if anonymousSymbol == nil && originalSymbol != nil { @@ -16117,14 +16138,14 @@ func (c *Checker) cloneTypeAsModuleType(symbol *ast.Symbol, moduleType *Type, re result := c.newSymbol(symbol.Flags(), symbol.Name()) result.SetDeclarations(slices.Clone(symbol.Declarations())) result.SetValueDeclaration(symbol.ValueDeclaration()) - result.SetMembers(maps.Clone(symbol.Members())) - result.SetExports(maps.Clone(symbol.Exports())) + result.SetMembers(maps.Clone(symbol.Members()), &c.symbolExtraArena) + result.SetExports(maps.Clone(symbol.Exports()), &c.symbolExtraArena) result.SetParent(symbol.Parent()) links := c.exportTypeLinks.Get(result) links.target = symbol links.originatingImport = referenceParent resolvedModuleType := c.resolveStructuredTypeMembers(moduleType) - c.valueSymbolLinks.Get(result).resolvedType = c.newAnonymousType(result, resolvedModuleType.members, nil, nil, resolvedModuleType.indexInfos) + c.valueSymbolLinks.Get(result).resolvedType = c.newAnonymousType(result, resolvedModuleType.getMembers(), nil, nil, resolvedModuleType.getIndexInfos()) return result } @@ -16449,7 +16470,7 @@ func (c *Checker) lateBindMember(parent *ast.Symbol, earlySymbols ast.SymbolTabl } lateSymbol = c.newSymbolEx(ast.SymbolFlagsNone, memberName, ast.CheckFlagsLate) } - c.valueSymbolLinks.Get(lateSymbol).nameType = t + c.valueSymbolLinks.Get(lateSymbol).setNameType(c, t) c.addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags) if lateSymbol.Parent() == nil { lateSymbol.SetParent(parent) @@ -16808,19 +16829,19 @@ func (c *Checker) getTypeOfSymbolWithDeferredType(symbol *ast.Symbol) *Type { func (c *Checker) getWriteTypeOfSymbolWithDeferredType(symbol *ast.Symbol) *Type { links := c.valueSymbolLinks.Get(symbol) - if links.writeType == nil { + if links.getWriteType() == nil { deferred := c.deferredSymbolLinks.Get(symbol) if len(deferred.writeConstituents) != 0 { if deferred.parent.flags&TypeFlagsUnion != 0 { - links.writeType = c.getUnionType(deferred.writeConstituents) + links.setWriteType(c, c.getUnionType(deferred.writeConstituents)) } else { - links.writeType = c.getIntersectionType(deferred.writeConstituents) + links.setWriteType(c, c.getIntersectionType(deferred.writeConstituents)) } } else { - links.writeType = c.getTypeOfSymbolWithDeferredType(symbol) + links.setWriteType(c, c.getTypeOfSymbolWithDeferredType(symbol)) } } - return links.writeType + return links.getWriteType() } // Distinct write types come only from set accessors, but synthetic union and intersection @@ -16832,7 +16853,7 @@ func (c *Checker) getWriteTypeOfSymbol(symbol *ast.Symbol) *Type { return c.getWriteTypeOfSymbolWithDeferredType(symbol) } links := c.valueSymbolLinks.Get(symbol) - return core.OrElse(links.writeType, links.resolvedType) + return core.OrElse(links.getWriteType(), links.resolvedType) } if symbol.Flags()&ast.SymbolFlagsProperty != 0 { return c.removeMissingType(c.getTypeOfSymbol(symbol), symbol.Flags()&ast.SymbolFlagsOptional != 0) @@ -16930,10 +16951,10 @@ func (c *Checker) getTypeOfInstantiatedSymbol(symbol *ast.Symbol) *Type { func (c *Checker) getWriteTypeOfInstantiatedSymbol(symbol *ast.Symbol) *Type { links := c.valueSymbolLinks.Get(symbol) - if links.writeType == nil { - links.writeType = c.instantiateType(c.getWriteTypeOfSymbol(links.target), links.mapper) + if links.getWriteType() == nil { + links.setWriteType(c, c.instantiateType(c.getWriteTypeOfSymbol(links.target), links.mapper)) } - return links.writeType + return links.getWriteType() } func (c *Checker) getTypeOfVariableOrParameterOrProperty(symbol *ast.Symbol) *Type { @@ -17119,7 +17140,7 @@ func (c *Checker) getTypeForVariableLikeDeclaration(declaration *ast.Node, inclu if thisParameter != nil && declaration == thisParameter { // Use the type from the *getter* debug.Assert(thisParameter.Type() == nil) - return c.getTypeOfSymbol(getterSignature.thisParameter) + return c.getTypeOfSymbol(getterSignature.ThisParameter()) } return c.getReturnTypeOfSignature(getterSignature) } @@ -17423,7 +17444,7 @@ func (c *Checker) isMixinConstructorType(t *Type) bool { signatures := c.getSignaturesOfType(t, SignatureKindConstruct) if len(signatures) == 1 { s := signatures[0] - if len(s.typeParameters) == 0 && len(s.parameters) == 1 && signatureHasRestParameter(s) { + if len(s.TypeParameters()) == 0 && len(s.parameters) == 1 && signatureHasRestParameter(s) { paramType := c.getTypeOfParameter(s.parameters[0]) return IsTypeAny(paramType) || c.getElementTypeOfArrayType(paramType) == c.anyType } @@ -17796,6 +17817,12 @@ func (b *keyBuilder) spill() { b.inlineLength = 0 } +func (b *keyBuilder) reserve(size int) { + if b.overflowBuffer != nil || b.inlineLength+size > len(b.inlineBuffer) { + b.overflowBuffer = slices.Grow(b.overflowBuffer, b.inlineLength+size) + } +} + func (b *keyBuilder) writeByte(c byte) { if b.inlineLength == len(b.inlineBuffer) { b.spill() @@ -17844,6 +17871,7 @@ func (b *keyBuilder) writeType(t *Type) { } func (b *keyBuilder) writeTypes(types []*Type) { + b.reserve(8 + 4*len(types)) b.writeInt(len(types)) for _, t := range types { b.writeType(t) @@ -18022,7 +18050,7 @@ func getConditionalTypeKey(typeArguments []*Type, alias *TypeAlias, forConstrain return b.hash() } -func getRelationKey(source *Type, target *Type, intersectionState IntersectionState, isIdentity bool, ignoreConstraints bool) (CacheHashKey, bool) { +func getRelationKey(source *Type, target *Type, intersectionState IntersectionState, isIdentity bool, ignoreConstraints bool) (relationKey, bool) { if isIdentity && source.id > target.id { source, target = target, source } @@ -18032,12 +18060,15 @@ func getRelationKey(source *Type, target *Type, intersectionState IntersectionSt b.writeByte('g') constrained = b.writeGenericTypeReferences(source, target, ignoreConstraints) } else { - b.writeByte('s') - b.writeType(source) - b.writeType(target) + // Ordinary relationships need only the two exact IDs. Intersection + // states select separate maps, leaving generic hashes unmodified. + return relationKey{value: CacheHashKey{ + Lo: uint64(source.id)<<32 | uint64(target.id), + Hi: uint64(intersectionState), + }}, false } b.writeUint32(uint32(intersectionState)) - return b.hash(), constrained + return relationKey{value: b.hash(), generic: true}, constrained } func getNodeListKey(nodes []*ast.Node) CacheHashKey { @@ -18981,7 +19012,7 @@ func (c *Checker) getTypeOfAccessors(symbol *ast.Symbol) *Type { func (c *Checker) getWriteTypeOfAccessors(symbol *ast.Symbol) *Type { links := c.valueSymbolLinks.Get(symbol) - if links.writeType == nil { + if links.getWriteType() == nil { if !c.pushTypeResolution(symbol, TypeSystemPropertyNameWriteType) { return c.errorType } @@ -19000,15 +19031,15 @@ func (c *Checker) getWriteTypeOfAccessors(symbol *ast.Symbol) *Type { writeType = c.anyType } // Absent an explicit setter type annotation we use the read type of the accessor. - if links.writeType == nil { + if links.getWriteType() == nil { if writeType != nil { - links.writeType = writeType + links.setWriteType(c, writeType) } else { - links.writeType = c.getTypeOfAccessors(symbol) + links.setWriteType(c, c.getTypeOfAccessors(symbol)) } } } - return links.writeType + return links.getWriteType() } func (c *Checker) getTypeOfAlias(symbol *ast.Symbol) *Type { @@ -19228,7 +19259,7 @@ func (c *Checker) typeResolutionHasProperty(r *TypeResolution) bool { case TypeSystemPropertyNameInitializerIsUndefined: return c.nodeLinks.Get(r.target.(*ast.Node)).flags&NodeCheckFlagsInitializerIsUndefinedComputed != 0 case TypeSystemPropertyNameWriteType: - return c.valueSymbolLinks.Get(r.target.(*ast.Symbol)).writeType != nil + return c.valueSymbolLinks.Get(r.target.(*ast.Symbol)).getWriteType() != nil case TypeSystemPropertyNameAliasTarget: return c.aliasSymbolLinks.Get(r.target.(*ast.Symbol)).aliasTarget != nil } @@ -19317,7 +19348,7 @@ func (c *Checker) getPropertyOfTypeEx(t *Type, name string, skipObjectFunctionPr switch { case t.flags&TypeFlagsObject != 0: resolved := c.resolveStructuredTypeMembers(t) - symbol := resolved.members[name] + symbol := resolved.getMember(name) if symbol != nil { if !includeTypeOnlyMembers && t.symbol != nil && t.symbol.Flags()&ast.SymbolFlagsValueModule != 0 && c.moduleSymbolLinks.Get(t.symbol).typeOnlyExportStarMap[name] != nil { // If this is the type of a module, `resolved.members.get(name)` might have effectively skipped over @@ -19381,10 +19412,13 @@ func (c *Checker) getSignaturesOfStructuredType(t *Type, kind SignatureKind) []* return nil } resolved := c.resolveStructuredTypeMembers(t) + if resolved.extra == nil { + return nil + } if kind == SignatureKindCall { - return resolved.signatures[:resolved.callSignatureCount] + return resolved.extra.signatures[:resolved.extra.callSignatureCount] } - return resolved.signatures[resolved.callSignatureCount:] + return resolved.extra.signatures[resolved.extra.callSignatureCount:] } func (c *Checker) getIndexInfosOfType(t *Type) []*IndexInfo { @@ -19393,7 +19427,7 @@ func (c *Checker) getIndexInfosOfType(t *Type) []*IndexInfo { func (c *Checker) getIndexInfosOfStructuredType(t *Type) []*IndexInfo { if t.flags&TypeFlagsStructuredType != 0 { - return c.resolveStructuredTypeMembers(t).indexInfos + return c.resolveStructuredTypeMembers(t).getIndexInfos() } return nil } @@ -19522,6 +19556,7 @@ func (c *Checker) resolveTypeReferenceMembers(t *Type) { func (c *Checker) resolveObjectTypeMembers(t *Type, source *Type, typeParameters []*Type, typeArguments []*Type) { var mapper *TypeMapper var members ast.SymbolTable + var properties []*ast.Symbol var callSignatures []*Signature var constructSignatures []*Signature var indexInfos []*IndexInfo @@ -19535,7 +19570,14 @@ func (c *Checker) resolveObjectTypeMembers(t *Type, source *Type, typeParameters } else { instantiated = true mapper = newTypeMapper(typeParameters, typeArguments) - members = c.instantiateSymbolTable(resolved.declaredMembers, mapper) + if symbolTableKeysMatchNames(resolved.declaredMembers) { + properties = c.getNamedMembers(resolved.declaredMembers, t.symbol) + for i, symbol := range properties { + properties[i] = c.instantiateSymbol(symbol, mapper) + } + } else { + members = c.instantiateSymbolTable(resolved.declaredMembers, mapper) + } callSignatures = c.instantiateSignatures(resolved.declaredCallSignatures, mapper) constructSignatures = c.instantiateSignatures(resolved.declaredConstructSignatures, mapper) indexInfos = c.instantiateIndexInfos(resolved.declaredIndexInfos, mapper) @@ -19544,6 +19586,11 @@ func (c *Checker) resolveObjectTypeMembers(t *Type, source *Type, typeParameters if len(baseTypes) != 0 { if !instantiated { members = maps.Clone(members) + } else if members == nil { + members = make(ast.SymbolTable, len(properties)) + for _, symbol := range properties { + members[symbol.Name()] = symbol + } } thisArgument := core.LastOrNil(typeArguments) for _, baseType := range baseTypes { @@ -19566,6 +19613,11 @@ func (c *Checker) resolveObjectTypeMembers(t *Type, source *Type, typeParameters } } c.setStructuredTypeMembers(t, members, callSignatures, constructSignatures, indexInfos) + if instantiated && len(baseTypes) == 0 && members == nil { + data := t.AsStructuredType() + data.properties = properties + data.members = c.newPropertyIndex(properties, nil) + } } func findIndexInfo(indexInfos []*IndexInfo, keyType *Type) *IndexInfo { @@ -19689,7 +19741,7 @@ func (c *Checker) getInstantiatedConstructorsForTypeArguments(t *Type, typeArgum signatures := c.getConstructorsForTypeArguments(t, typeArgumentNodes, location) typeArguments := core.Map(typeArgumentNodes, c.getTypeFromTypeNode) return core.SameMap(signatures, func(sig *Signature) *Signature { - if len(sig.typeParameters) != 0 { + if len(sig.TypeParameters()) != 0 { return c.getSignatureInstantiation(sig, typeArguments, ast.IsInJSFile(location), nil) } return sig @@ -19699,17 +19751,17 @@ func (c *Checker) getInstantiatedConstructorsForTypeArguments(t *Type, typeArgum func (c *Checker) getConstructorsForTypeArguments(t *Type, typeArgumentNodes []*ast.Node, location *ast.Node) []*Signature { typeArgCount := len(typeArgumentNodes) return core.Filter(c.getSignaturesOfType(t, SignatureKindConstruct), func(sig *Signature) bool { - return typeArgCount >= c.getMinTypeArgumentCount(sig.typeParameters) && typeArgCount <= len(sig.typeParameters) + return typeArgCount >= c.getMinTypeArgumentCount(sig.TypeParameters()) && typeArgCount <= len(sig.TypeParameters()) }) } func (c *Checker) getSignatureInstantiation(sig *Signature, typeArguments []*Type, isJavaScript bool, inferredTypeParameters []*Type) *Signature { - instantiatedSignature := c.getSignatureInstantiationWithoutFillingInTypeArguments(sig, c.fillMissingTypeArguments(typeArguments, sig.typeParameters, c.getMinTypeArgumentCount(sig.typeParameters), isJavaScript)) + instantiatedSignature := c.getSignatureInstantiationWithoutFillingInTypeArguments(sig, c.fillMissingTypeArguments(typeArguments, sig.TypeParameters(), c.getMinTypeArgumentCount(sig.TypeParameters()), isJavaScript)) if len(inferredTypeParameters) != 0 { returnSignature := c.getSingleCallOrConstructSignature(c.getReturnTypeOfSignature(instantiatedSignature)) if returnSignature != nil { newReturnSignature := c.cloneSignature(returnSignature) - newReturnSignature.typeParameters = inferredTypeParameters + newReturnSignature.setTypeParameters(c, inferredTypeParameters) newReturnType := c.getOrCreateTypeFromSignature(newReturnSignature) newReturnType.AsObjectType().mapper = instantiatedSignature.mapper newInstantiatedSignature := c.cloneSignature(instantiatedSignature) @@ -19721,10 +19773,10 @@ func (c *Checker) getSignatureInstantiation(sig *Signature, typeArguments []*Typ } func (c *Checker) cloneSignature(sig *Signature) *Signature { - result := c.newSignature(sig.flags&SignatureFlagsPropagatingFlags, sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, nil, nil, int(sig.minArgumentCount)) + result := c.newSignature(sig.flags&SignatureFlagsPropagatingFlags, sig.declaration, sig.TypeParameters(), sig.ThisParameter(), sig.parameters, nil, nil, int(sig.minArgumentCount)) result.target = sig.target result.mapper = sig.mapper - result.composite = sig.composite + result.setComposite(c, sig.getComposite()) return result } @@ -19747,7 +19799,7 @@ func (c *Checker) createSignatureTypeMapper(sig *Signature, typeArguments []*Typ } func (c *Checker) getTypeParametersForMapper(sig *Signature) []*Type { - return core.SameMap(sig.typeParameters, func(tp *Type) *Type { return c.instantiateType(tp, tp.Mapper()) }) + return core.SameMap(sig.TypeParameters(), func(tp *Type) *Type { return c.instantiateType(tp, tp.Mapper()) }) } // If type has a single call signature and no other members, return that signature. Otherwise, return nil. @@ -19766,7 +19818,7 @@ func (c *Checker) getSingleCallOrConstructSignature(t *Type) *Signature { func (c *Checker) getSingleSignature(t *Type, kind SignatureKind, allowMembers bool) *Signature { if t.flags&TypeFlagsObject != 0 { resolved := c.resolveStructuredTypeMembers(t) - if allowMembers || len(resolved.properties) == 0 && len(resolved.indexInfos) == 0 { + if allowMembers || len(resolved.properties) == 0 && len(resolved.getIndexInfos()) == 0 { if kind == SignatureKindCall && len(resolved.CallSignatures()) == 1 && len(resolved.ConstructSignatures()) == 0 { return resolved.CallSignatures()[0] } @@ -19783,7 +19835,7 @@ func (c *Checker) getOrCreateTypeFromSignature(sig *Signature) *Type { // using the constructor keyword, and the other is declaring a bare construct signature in an // object type literal or interface (using the new keyword). Each way of declaring a constructor // will result in a different declaration kind. - if sig.isolatedSignatureType == nil { + if sig.getIsolatedSignatureType() == nil { var kind ast.Kind if sig.declaration != nil { kind = sig.declaration.Kind @@ -19801,26 +19853,26 @@ func (c *Checker) getOrCreateTypeFromSignature(sig *Signature) *Type { } else { c.setStructuredTypeMembers(t, nil, []*Signature{sig}, nil, nil) } - sig.isolatedSignatureType = t + sig.ensureExtra(c).isolatedSignatureType = t } - return sig.isolatedSignatureType + return sig.getIsolatedSignatureType() } func (c *Checker) getErasedSignature(signature *Signature) *Signature { - if len(signature.typeParameters) == 0 { + if len(signature.TypeParameters()) == 0 { return signature } key := CachedSignatureKey{sig: signature, key: SignatureKeyErased} erased := c.cachedSignatures[key] if erased == nil { - erased = c.instantiateSignatureEx(signature, newArrayToSingleTypeMapper(signature.typeParameters, c.anyType), true /*eraseTypeParameters*/) + erased = c.instantiateSignatureEx(signature, newArrayToSingleTypeMapper(signature.TypeParameters(), c.anyType), true /*eraseTypeParameters*/) c.cachedSignatures[key] = erased } return erased } func (c *Checker) getCanonicalSignature(signature *Signature) *Signature { - if len(signature.typeParameters) == 0 { + if len(signature.TypeParameters()) == 0 { return signature } key := CachedSignatureKey{sig: signature, key: SignatureKeyCanonical} @@ -19839,7 +19891,7 @@ func (c *Checker) createCanonicalSignature(signature *Signature) *Signature { // where different generations of the same type parameter are in scope). This leads to a lot of new type // identities, and potentially a lot of work comparing those identities, so here we create an instantiation // that uses the original type identities for all unconstrained type parameters. - typeArguments := core.Map(signature.typeParameters, func(tp *Type) *Type { + typeArguments := core.Map(signature.TypeParameters(), func(tp *Type) *Type { if tp.Target() != nil && c.getConstraintOfTypeParameter(tp.Target()) == nil { return tp.Target() } @@ -19849,7 +19901,7 @@ func (c *Checker) createCanonicalSignature(signature *Signature) *Signature { } func (c *Checker) getBaseSignature(signature *Signature) *Signature { - typeParameters := signature.typeParameters + typeParameters := signature.TypeParameters() if len(typeParameters) == 0 { return signature } @@ -20422,8 +20474,8 @@ func (c *Checker) getReturnTypeOfSignature(sig *Signature) *Type { switch { case sig.target != nil: t = c.instantiateType(c.getReturnTypeOfSignature(sig.target), sig.mapper) - case sig.composite != nil: - t = c.instantiateType(c.getUnionOrIntersectionType(core.Map(sig.composite.signatures, c.getReturnTypeOfSignature), sig.composite.isUnion, UnionReductionSubtype), sig.mapper) + case sig.getComposite() != nil: + t = c.instantiateType(c.getUnionOrIntersectionType(core.Map(sig.getComposite().signatures, c.getReturnTypeOfSignature), sig.getComposite().isUnion, UnionReductionSubtype), sig.mapper) default: t = c.getReturnTypeFromAnnotation(sig.declaration) if t == nil { @@ -21031,12 +21083,12 @@ func (c *Checker) instantiateSignature(sig *Signature, m *TypeMapper) *Signature func (c *Checker) instantiateSignatureEx(sig *Signature, m *TypeMapper, eraseTypeParameters bool) *Signature { var freshTypeParameters []*Type - if len(sig.typeParameters) != 0 && !eraseTypeParameters { + if len(sig.TypeParameters()) != 0 && !eraseTypeParameters { // First create a fresh set of type parameters, then include a mapping from the old to the // new type parameters in the mapper function. Finally store this mapper in the new type // parameters such that we can use it when instantiating constraints. - freshTypeParameters = core.Map(sig.typeParameters, c.cloneTypeParameter) - m = c.combineTypeMappers(newTypeMapper(sig.typeParameters, freshTypeParameters), m) + freshTypeParameters = core.Map(sig.TypeParameters(), c.cloneTypeParameter) + m = c.combineTypeMappers(newTypeMapper(sig.TypeParameters(), freshTypeParameters), m) for _, tp := range freshTypeParameters { tp.AsTypeParameter().mapper = m } @@ -21045,7 +21097,7 @@ func (c *Checker) instantiateSignatureEx(sig *Signature, m *TypeMapper, eraseTyp // because using `mapper` now could trigger inferences to become fixed. (See `createInferenceContext`.) // See GH#17600. result := c.newSignature(sig.flags&SignatureFlagsPropagatingFlags, sig.declaration, freshTypeParameters, - c.instantiateSymbol(sig.thisParameter, m), c.instantiateSymbols(sig.parameters, m), + c.instantiateSymbol(sig.ThisParameter(), m), c.instantiateSymbols(sig.parameters, m), nil /*resolvedReturnType*/, nil /*resolvedTypePredicate*/, int(sig.minArgumentCount)) result.target = sig result.mapper = m @@ -21119,14 +21171,20 @@ func (c *Checker) resolveAnonymousTypeMembers(t *Type) { indexInfos = append(indexInfos, c.enumNumberIndexInfo) } } - d.indexInfos = indexInfos + if indexInfos != nil || d.extra != nil { + d.ensureExtra(c).indexInfos = indexInfos + } // We resolve the members before computing the signatures because a signature may use // typeof with a qualified name expression that circularly references the type we are // in the process of resolving (see issue #6072). The temporarily empty signature list // will never be observed because a qualified name can't reference signatures. if symbol.Flags()&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod) != 0 { - d.signatures = c.getSignaturesOfSymbol(symbol) - d.callSignatureCount = len(d.signatures) + signatures := c.getSignaturesOfSymbol(symbol) + if signatures != nil || d.extra != nil { + extra := d.ensureExtra(c) + extra.signatures = signatures + extra.callSignatureCount = len(signatures) + } } // And likewise for construct signatures for classes if symbol.Flags()&ast.SymbolFlagsClass != 0 { @@ -21135,7 +21193,10 @@ func (c *Checker) resolveAnonymousTypeMembers(t *Type) { if len(constructSignatures) == 0 { constructSignatures = c.getDefaultConstructSignatures(classType) } - d.signatures = append(d.signatures, constructSignatures...) + if len(constructSignatures) != 0 { + extra := d.ensureExtra(c) + extra.signatures = append(extra.signatures, constructSignatures...) + } } } @@ -21178,7 +21239,7 @@ func (c *Checker) instantiateSymbol(symbol *ast.Symbol, m *TypeMapper) *ast.Symb return symbol } // If we're a setter, check writeType. - if links.writeType != nil && !c.couldContainTypeVariables(links.writeType) { + if links.getWriteType() != nil && !c.couldContainTypeVariables(links.getWriteType()) { return symbol } } @@ -21195,7 +21256,7 @@ func (c *Checker) instantiateSymbol(symbol *ast.Symbol, m *TypeMapper) *ast.Symb resultLinks := c.valueSymbolLinks.Get(result) resultLinks.target = symbol resultLinks.mapper = m - resultLinks.nameType = links.nameType + resultLinks.setNameType(c, links.getNameType()) return result } @@ -21278,16 +21339,16 @@ func (c *Checker) getDefaultConstructSignatures(classType *Type) []*Signature { typeArgCount := len(typeArguments) var result []*Signature for _, baseSig := range baseSignatures { - minTypeArgumentCount := c.getMinTypeArgumentCount(baseSig.typeParameters) - typeParamCount := len(baseSig.typeParameters) + minTypeArgumentCount := c.getMinTypeArgumentCount(baseSig.TypeParameters()) + typeParamCount := len(baseSig.TypeParameters()) if isJavaScript || typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount { var sig *Signature if typeParamCount != 0 { - sig = c.createSignatureInstantiation(baseSig, c.fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) + sig = c.createSignatureInstantiation(baseSig, c.fillMissingTypeArguments(typeArguments, baseSig.TypeParameters(), minTypeArgumentCount, isJavaScript)) } else { sig = c.cloneSignature(baseSig) } - sig.typeParameters = classType.AsInterfaceType().LocalTypeParameters() + sig.setTypeParameters(c, classType.AsInterfaceType().LocalTypeParameters()) sig.resolvedReturnType = classType if isAbstract { sig.flags |= SignatureFlagsAbstract @@ -21327,7 +21388,7 @@ func (c *Checker) resolveMappedTypeMembers(t *Type) { // property symbol's name type be the union of those enum member types. if existingProp := members[propName]; existingProp != nil { valueLinks := c.valueSymbolLinks.Get(existingProp) - valueLinks.nameType = c.getUnionType([]*Type{valueLinks.nameType, propNameType}) + valueLinks.setNameType(c, c.getUnionType([]*Type{valueLinks.getNameType(), propNameType})) mappedLinks := c.mappedSymbolLinks.Get(existingProp) mappedLinks.keyType = c.getUnionType([]*Type{mappedLinks.keyType, keyType}) } else { @@ -21345,8 +21406,8 @@ func (c *Checker) resolveMappedTypeMembers(t *Type) { prop := c.newSymbol(ast.SymbolFlagsProperty|core.IfElse(isOptional, ast.SymbolFlagsOptional, 0), propName) prop.SetCheckFlags(lateFlag | ast.CheckFlagsMapped | core.IfElse(isReadonly, ast.CheckFlagsReadonly, 0) | core.IfElse(stripOptional, ast.CheckFlagsStripOptional, 0)) valueLinks := c.valueSymbolLinks.Get(prop) - valueLinks.containingType = t - valueLinks.nameType = propNameType + valueLinks.setContainingType(c, t) + valueLinks.setNameType(c, propNameType) mappedLinks := c.mappedSymbolLinks.Get(prop) mappedLinks.keyType = keyType if modifiersProp != nil { @@ -21393,7 +21454,7 @@ func (c *Checker) resolveMappedTypeMembers(t *Type) { func (c *Checker) getTypeOfMappedSymbol(symbol *ast.Symbol) *Type { links := c.valueSymbolLinks.Get(symbol) if links.resolvedType == nil { - mappedType := links.containingType + mappedType := links.getContainingType() if !c.pushTypeResolution(symbol, TypeSystemPropertyNameType) { mappedType.AsMappedType().containsError = true return c.errorType @@ -21538,21 +21599,21 @@ func (c *Checker) getUnionSignatures(signatureLists [][]*Signature) []*Signature s := signature // Union the result types when more than one signature matches if len(unionSignatures) > 1 { - thisParameter := signature.thisParameter + thisParameter := signature.ThisParameter() firstThisParameterOfUnionSignatures := core.FirstNonNil(unionSignatures, func(sig *Signature) *ast.Symbol { - return sig.thisParameter + return sig.ThisParameter() }) if firstThisParameterOfUnionSignatures != nil { thisType := c.getIntersectionType(core.MapNonNil(unionSignatures, func(sig *Signature) *Type { - if sig.thisParameter != nil { - return c.getTypeOfSymbol(sig.thisParameter) + if sig.ThisParameter() != nil { + return c.getTypeOfSymbol(sig.ThisParameter()) } return nil })) thisParameter = c.createSymbolWithType(firstThisParameterOfUnionSignatures, thisType) } s = c.createUnionSignature(signature, unionSignatures) - s.thisParameter = thisParameter + s.setThisParameter(c, thisParameter) } result = append(result, s) } @@ -21570,8 +21631,8 @@ func (c *Checker) getUnionSignatures(signatureLists [][]*Signature) []*Signature if !core.Same(signatures, masterList) { signature := signatures[0] debug.Assert(signature != nil, "getUnionSignatures bails early on empty signature lists and should not have empty lists on second pass") - if len(signature.typeParameters) != 0 && core.Some(results, func(s *Signature) bool { - return len(s.typeParameters) != 0 && !c.compareTypeParametersIdentical(signature.typeParameters, s.typeParameters) + if len(signature.TypeParameters()) != 0 && core.Some(results, func(s *Signature) bool { + return len(s.TypeParameters()) != 0 && !c.compareTypeParametersIdentical(signature.TypeParameters(), s.TypeParameters()) }) { results = nil } else { @@ -21590,14 +21651,14 @@ func (c *Checker) getUnionSignatures(signatureLists [][]*Signature) []*Signature } func (c *Checker) combineUnionOrIntersectionMemberSignatures(left *Signature, right *Signature, isUnion bool) *Signature { - typeParams := left.typeParameters + typeParams := left.TypeParameters() if len(typeParams) == 0 { - typeParams = right.typeParameters + typeParams = right.TypeParameters() } var paramMapper *TypeMapper - if len(left.typeParameters) != 0 && len(right.typeParameters) != 0 { + if len(left.TypeParameters()) != 0 && len(right.TypeParameters()) != 0 { // We just use the type parameter defaults from the first signature - paramMapper = newTypeMapper(right.typeParameters, left.typeParameters) + paramMapper = newTypeMapper(right.TypeParameters(), left.TypeParameters()) } flags := (left.flags | right.flags) & (SignatureFlagsPropagatingFlags & ^SignatureFlagsHasRestParameter) declaration := left.declaration @@ -21606,23 +21667,23 @@ func (c *Checker) combineUnionOrIntersectionMemberSignatures(left *Signature, ri if lastParam != nil && lastParam.CheckFlags()&ast.CheckFlagsRestParameter != 0 { flags |= SignatureFlagsHasRestParameter } - thisParam := c.combineUnionOrIntersectionThisParam(left.thisParameter, right.thisParameter, paramMapper, isUnion) + thisParam := c.combineUnionOrIntersectionThisParam(left.ThisParameter(), right.ThisParameter(), paramMapper, isUnion) minArgCount := int(max(left.minArgumentCount, right.minArgumentCount)) result := c.newSignature(flags, declaration, typeParams, thisParam, params, nil, nil, minArgCount) var leftSignatures []*Signature - if left.composite != nil && left.composite.isUnion { - leftSignatures = left.composite.signatures + if left.getComposite() != nil && left.getComposite().isUnion { + leftSignatures = left.getComposite().signatures } else { leftSignatures = []*Signature{left} } - result.composite = &CompositeSignature{isUnion: isUnion, signatures: append(leftSignatures, right)} + result.setComposite(c, &CompositeSignature{isUnion: isUnion, signatures: append(leftSignatures, right)}) if paramMapper != nil { - if left.composite != nil && left.composite.isUnion == isUnion && left.mapper != nil { + if left.getComposite() != nil && left.getComposite().isUnion == isUnion && left.mapper != nil { result.mapper = c.combineTypeMappers(left.mapper, paramMapper) } else { result.mapper = paramMapper } - } else if left.composite != nil && left.composite.isUnion == isUnion { + } else if left.getComposite() != nil && left.getComposite().isUnion == isUnion { result.mapper = left.mapper } return result @@ -21812,7 +21873,7 @@ func (c *Checker) includeMixinType(t *Type, types []*Type, mixinFlags []bool, in func (c *Checker) getPropertyOfObjectType(t *Type, name string) *ast.Symbol { if t.flags&TypeFlagsObject != 0 { resolved := c.resolveStructuredTypeMembers(t) - symbol := resolved.members[name] + symbol := resolved.getMember(name) if symbol != nil && c.symbolIsValue(symbol) { return symbol } @@ -21835,24 +21896,35 @@ func (c *Checker) getPropertyOfUnionOrIntersectionType(t *Type, name string, ski // these partial properties when identifying discriminant properties, but otherwise they are filtered out // and do not appear to be present in the union type. func (c *Checker) getUnionOrIntersectionProperty(t *Type, name string, skipObjectFunctionPropertyAugment bool) *ast.Symbol { - var cache ast.SymbolTable + data := t.AsUnionOrIntersectionType() if skipObjectFunctionPropertyAugment { - cache = ast.GetSymbolTable(&t.AsUnionOrIntersectionType().propertyCacheWithoutFunctionPropertyAugment) + if prop := data.propertyCacheWithoutFunctionPropertyAugment[name]; prop != nil { + return prop + } } else { - cache = ast.GetSymbolTable(&t.AsUnionOrIntersectionType().propertyCache) - } - if prop := cache[name]; prop != nil { - return prop + if data.propertyCache != nil { + if prop := data.propertyCache[name]; prop != nil { + return prop + } + } + // Complete non-augmented properties are also valid for augmented + // lookup. Share the entry instead of retaining it in both tables. + if prop := data.propertyCacheWithoutFunctionPropertyAugment[name]; prop != nil && prop.CheckFlags()&ast.CheckFlagsPartial == 0 { + return prop + } } prop := c.createUnionOrIntersectionProperty(t, name, skipObjectFunctionPropertyAugment) if prop != nil { - cache[name] = prop - // Propagate an entry from the non-augmented cache to the augmented cache unless the property is partial. - if skipObjectFunctionPropertyAugment && prop.CheckFlags()&ast.CheckFlagsPartial == 0 { - augmentedCache := ast.GetSymbolTable(&t.AsUnionOrIntersectionType().propertyCache) - if augmentedCache[name] == nil { - augmentedCache[name] = prop + if skipObjectFunctionPropertyAugment { + ast.GetSymbolTable(&data.propertyCacheWithoutFunctionPropertyAugment)[name] = prop + if prop.CheckFlags()&ast.CheckFlagsPartial == 0 && data.propertyCache[name] == prop { + delete(data.propertyCache, name) + if len(data.propertyCache) == 0 { + data.propertyCache = nil + } } + } else { + ast.GetSymbolTable(&data.propertyCache)[name] = prop } } return prop @@ -22007,9 +22079,9 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s clone.SetParent(singleProp.ValueDeclaration().Symbol().Parent()) } links := c.valueSymbolLinks.Get(clone) - links.containingType = containingType + links.setContainingType(c, containingType) links.mapper = singlePropMapper - links.writeType = c.getWriteTypeOfSymbol(singleProp) + links.setWriteType(c, c.getWriteTypeOfSymbol(singleProp)) return clone } if propSet.Size() == 0 { @@ -22034,7 +22106,7 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s t := c.getTypeOfSymbol(prop) if firstType == nil { firstType = t - nameType = c.valueSymbolLinks.Get(prop).nameType + nameType = c.valueSymbolLinks.Get(prop).getNameType() } writeType := c.getWriteTypeOfSymbol(prop) if writeTypes != nil || writeType != t { @@ -22063,8 +22135,8 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s result.SetParent(firstValueDeclaration.Symbol().Parent()) } links := c.valueSymbolLinks.Get(result) - links.containingType = containingType - links.nameType = nameType + links.setContainingType(c, containingType) + links.setNameType(c, nameType) if len(propTypes) > 2 { // When `propTypes` has the potential to explode in size when normalized, defer normalization until absolutely needed result.SetCheckFlags(result.CheckFlags() | ast.CheckFlagsDeferredType) @@ -22081,9 +22153,9 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s } if writeTypes != nil { if isUnion { - links.writeType = c.getUnionType(writeTypes) + links.setWriteType(c, c.getUnionType(writeTypes)) } else { - links.writeType = c.getIntersectionType(writeTypes) + links.setWriteType(c, c.getIntersectionType(writeTypes)) } } return result @@ -22138,7 +22210,7 @@ func (c *Checker) createSymbolWithType(source *ast.Symbol, t *Type) *ast.Symbol links := c.valueSymbolLinks.Get(symbol) links.resolvedType = t links.target = source - links.nameType = c.valueSymbolLinks.Get(source).nameType + links.setNameType(c, c.valueSymbolLinks.Get(source).getNameType()) return symbol } @@ -22287,7 +22359,8 @@ func (c *Checker) isMappingOfSameObjectType(types []*Type) bool { func (c *Checker) somePropertyReducesToNever(t *Type) bool { // Collect declaration counts for each property across all constituent types of the intersection. - var counts collections.OrderedMap[string, int] + counts := c.getTemporaryPropertyCounts() + defer c.releaseTemporaryPropertyCounts(counts) for _, t := range t.Types() { for _, prop := range c.getPropertiesOfType(t) { counts.Set(prop.Name(), counts.GetOrZero(prop.Name())+1) @@ -22815,7 +22888,7 @@ func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *Type default: target = t } - typeParameters = links.outerTypeParameters + typeParameters = links.getOuterTypeParameters() if typeParameters == nil { // The first time an anonymous type is instantiated we compute and store a list of the type // parameters that are in scope (and therefore potentially referenced). For type literals that @@ -22838,7 +22911,7 @@ func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *Type if typeParameters == nil { typeParameters = []*Type{} } - links.outerTypeParameters = typeParameters + links.setOuterTypeParameters(c, typeParameters) } if len(typeParameters) == 0 { return t @@ -24306,8 +24379,8 @@ func (c *Checker) getOuterTypeParameters(node *ast.Node, includeThisTypes bool) outerTypeParameters := c.getOuterTypeParameters(node, includeThisTypes) if (kind == ast.KindFunctionExpression || kind == ast.KindArrowFunction || ast.IsObjectLiteralMethod(node)) && c.isContextSensitive(node) { signature := core.FirstOrNil(c.getSignaturesOfType(c.getTypeOfSymbol(c.getSymbolOfDeclaration(node)), SignatureKindCall)) - if signature != nil && len(signature.typeParameters) != 0 { - return append(outerTypeParameters, signature.typeParameters...) + if signature != nil && len(signature.TypeParameters()) != 0 { + return append(outerTypeParameters, signature.TypeParameters()...) } } if kind == ast.KindMappedType { @@ -25227,7 +25300,7 @@ func (c *Checker) getGlobalImportMetaExpressionType() *Type { metaPropertySymbol.SetParent(symbol) c.valueSymbolLinks.Get(metaPropertySymbol).resolvedType = importMetaType members := createSymbolTable([]*ast.Symbol{metaPropertySymbol}) - symbol.SetMembers(members) + symbol.SetMembers(members, &c.symbolExtraArena) c.deferredGlobalImportMetaExpressionType = c.newAnonymousType(symbol, members, nil, nil, nil) } return c.deferredGlobalImportMetaExpressionType @@ -25539,14 +25612,13 @@ func isUnaryTupleTypeNode(node *ast.Node) bool { return ast.IsTupleTypeNode(node) && len(node.Elements()) == 1 } -func (c *Checker) newType(flags TypeFlags, objectFlags ObjectFlags, data TypeData) *Type { +func (c *Checker) newType(flags TypeFlags, objectFlags ObjectFlags, t *Type, kind typeKind) *Type { c.TypeCount++ - t := data.AsType() t.flags = flags t.objectFlags = objectFlags &^ (ObjectFlagsCouldContainTypeVariablesComputed | ObjectFlagsCouldContainTypeVariables | ObjectFlagsMembersResolved) t.id = TypeId(c.TypeCount) + t.kind = kind t.checker = c - t.data = data if c.tracer != nil { c.tracer.RecordType(t) } @@ -25560,7 +25632,7 @@ func (c *Checker) newIntrinsicType(flags TypeFlags, intrinsicName string) *Type func (c *Checker) newIntrinsicTypeEx(flags TypeFlags, intrinsicName string, objectFlags ObjectFlags) *Type { data := &IntrinsicType{} data.intrinsicName = intrinsicName - return c.newType(flags, objectFlags, data) + return c.newType(flags, objectFlags, data.AsType(), typeKindIntrinsic) } func (c *Checker) createWideningType(nonWideningType *Type) *Type { @@ -25580,9 +25652,9 @@ func (c *Checker) createUnknownUnionType() *Type { } func (c *Checker) newLiteralType(flags TypeFlags, value any, regularType *Type) *Type { - data := &LiteralType{} + data := c.literalTypeArena.New() data.value = value - t := c.newType(flags, ObjectFlagsNone, data) + t := c.newType(flags, ObjectFlagsNone, data.AsType(), typeKindLiteral) if regularType != nil { data.regularType = regularType } else { @@ -25594,34 +25666,33 @@ func (c *Checker) newLiteralType(flags TypeFlags, value any, regularType *Type) func (c *Checker) newUniqueESSymbolType(symbol *ast.Symbol, name string) *Type { data := &UniqueESSymbolType{} data.name = name - t := c.newType(TypeFlagsUniqueESSymbol, ObjectFlagsNone, data) + t := c.newType(TypeFlagsUniqueESSymbol, ObjectFlagsNone, data.AsType(), typeKindUniqueESSymbol) t.symbol = symbol return t } func (c *Checker) newObjectType(objectFlags ObjectFlags, symbol *ast.Symbol) *Type { - var data TypeData + var t *Type switch { case objectFlags&ObjectFlagsClassOrInterface != 0: - data = &InterfaceType{} + t = c.newType(TypeFlagsObject, objectFlags, c.interfaceTypeArena.New().AsType(), typeKindInterface) case objectFlags&ObjectFlagsTuple != 0: - data = &TupleType{} + t = c.newType(TypeFlagsObject, objectFlags, (&TupleType{}).AsType(), typeKindTuple) case objectFlags&ObjectFlagsReference != 0: - data = &TypeReference{} + t = c.newType(TypeFlagsObject, objectFlags, c.typeReferenceArena.New().AsType(), typeKindTypeReference) case objectFlags&ObjectFlagsMapped != 0: - data = &MappedType{} + t = c.newType(TypeFlagsObject, objectFlags, c.mappedTypeArena.New().AsType(), typeKindMapped) case objectFlags&ObjectFlagsReverseMapped != 0: - data = &ReverseMappedType{} + t = c.newType(TypeFlagsObject, objectFlags, (&ReverseMappedType{}).AsType(), typeKindReverseMapped) case objectFlags&ObjectFlagsEvolvingArray != 0: - data = &EvolvingArrayType{} + t = c.newType(TypeFlagsObject, objectFlags, (&EvolvingArrayType{}).AsType(), typeKindEvolvingArray) case objectFlags&ObjectFlagsInstantiationExpressionType != 0: - data = &InstantiationExpressionType{} + t = c.newType(TypeFlagsObject, objectFlags, (&InstantiationExpressionType{}).AsType(), typeKindInstantiationExpression) case objectFlags&ObjectFlagsAnonymous != 0: - data = &ObjectType{} + t = c.newType(TypeFlagsObject, objectFlags, c.objectTypeArena.New().AsType(), typeKindObject) default: panic("Unhandled case in newObjectType") } - t := c.newType(TypeFlagsObject, objectFlags, data) t.symbol = symbol return t } @@ -25684,28 +25755,46 @@ func (c *Checker) cloneTypeReference(source *Type) *Type { func (c *Checker) setStructuredTypeMembers(t *Type, members ast.SymbolTable, callSignatures []*Signature, constructSignatures []*Signature, indexInfos []*IndexInfo) { t.objectFlags |= ObjectFlagsMembersResolved data := t.AsStructuredType() - data.members = members + // Named-member filtering may recursively query this type before it finishes. + data.members = nil + if members != nil { + data.members = c.memberIndexArena.New() + data.members.fallback = members + } data.properties = c.getNamedMembers(members, t.symbol) + if data.members != nil && t.symbol != nil && t.symbol.Flags()&ast.SymbolFlagsValueModule != 0 { + data.members.fallback = members + } else { + data.members = c.newMemberIndex(members, data.properties, data.members) + } + c.setStructuredTypeSignatures(data, callSignatures, constructSignatures, indexInfos) +} + +func (c *Checker) setStructuredTypeSignatures(data *StructuredType, callSignatures []*Signature, constructSignatures []*Signature, indexInfos []*IndexInfo) { + if data.extra == nil && callSignatures == nil && constructSignatures == nil && indexInfos == nil { + return + } + extra := data.ensureExtra(c) if len(callSignatures) != 0 { if len(constructSignatures) != 0 { - data.signatures = core.Concatenate(callSignatures, constructSignatures) + extra.signatures = core.Concatenate(callSignatures, constructSignatures) } else { - data.signatures = slices.Clip(callSignatures) + extra.signatures = slices.Clip(callSignatures) } - data.callSignatureCount = len(callSignatures) + extra.callSignatureCount = len(callSignatures) } else { if len(constructSignatures) != 0 { - data.signatures = slices.Clip(constructSignatures) + extra.signatures = slices.Clip(constructSignatures) } else { - data.signatures = nil + extra.signatures = nil } - data.callSignatureCount = 0 + extra.callSignatureCount = 0 } - data.indexInfos = slices.Clip(indexInfos) + extra.indexInfos = slices.Clip(indexInfos) } func (c *Checker) newTypeParameter(symbol *ast.Symbol) *Type { - t := c.newType(TypeFlagsTypeParameter, ObjectFlagsNone, &TypeParameter{}) + t := c.newType(TypeFlagsTypeParameter, ObjectFlagsNone, c.typeParameterArena.New().AsType(), typeKindTypeParameter) t.symbol = symbol return t } @@ -25725,62 +25814,62 @@ func (c *Checker) getPropagatingFlagsOfTypes(types []*Type, excludeKinds TypeFla } func (c *Checker) newUnionType(objectFlags ObjectFlags, types []*Type) *Type { - data := &UnionType{} - data.types = types - return c.newType(TypeFlagsUnion, objectFlags, data) + data := c.unionTypeArena.New() + data.types = c.typeListArena.Clone(types) + return c.newType(TypeFlagsUnion, objectFlags, data.AsType(), typeKindUnion) } func (c *Checker) newIntersectionType(objectFlags ObjectFlags, types []*Type) *Type { - data := &IntersectionType{} - data.types = types - return c.newType(TypeFlagsIntersection, objectFlags, data) + data := c.intersectionTypeArena.New() + data.types = c.typeListArena.Clone(types) + return c.newType(TypeFlagsIntersection, objectFlags, data.AsType(), typeKindIntersection) } func (c *Checker) newIndexedAccessType(objectType *Type, indexType *Type, accessFlags AccessFlags) *Type { - data := &IndexedAccessType{} + data := c.indexedAccessTypeArena.New() data.objectType = objectType data.indexType = indexType data.accessFlags = accessFlags - return c.newType(TypeFlagsIndexedAccess, ObjectFlagsNone, data) + return c.newType(TypeFlagsIndexedAccess, ObjectFlagsNone, data.AsType(), typeKindIndexedAccess) } func (c *Checker) newIndexType(target *Type, indexFlags IndexFlags) *Type { data := &IndexType{} data.target = target data.indexFlags = indexFlags - return c.newType(TypeFlagsIndex, ObjectFlagsNone, data) + return c.newType(TypeFlagsIndex, ObjectFlagsNone, data.AsType(), typeKindIndex) } func (c *Checker) newTemplateLiteralType(texts []string, types []*Type) *Type { data := &TemplateLiteralType{} data.texts = texts data.types = types - return c.newType(TypeFlagsTemplateLiteral, ObjectFlagsNone, data) + return c.newType(TypeFlagsTemplateLiteral, ObjectFlagsNone, data.AsType(), typeKindTemplateLiteral) } func (c *Checker) newStringMappingType(symbol *ast.Symbol, target *Type) *Type { data := &StringMappingType{} data.target = target - t := c.newType(TypeFlagsStringMapping, ObjectFlagsNone, data) + t := c.newType(TypeFlagsStringMapping, ObjectFlagsNone, data.AsType(), typeKindStringMapping) t.symbol = symbol return t } func (c *Checker) newConditionalType(root *ConditionalRoot, mapper *TypeMapper, combinedMapper *TypeMapper) *Type { - data := &ConditionalType{} + data := c.conditionalTypeArena.New() data.root = root data.checkType = c.instantiateType(root.checkType, mapper) data.extendsType = c.instantiateType(root.extendsType, mapper) data.mapper = mapper data.combinedMapper = combinedMapper - return c.newType(TypeFlagsConditional, ObjectFlagsNone, data) + return c.newType(TypeFlagsConditional, ObjectFlagsNone, data.AsType(), typeKindConditional) } func (c *Checker) newSubstitutionType(baseType *Type, constraint *Type) *Type { data := &SubstitutionType{} data.baseType = baseType data.constraint = constraint - return c.newType(TypeFlagsSubstitution, ObjectFlagsNone, data) + return c.newType(TypeFlagsSubstitution, ObjectFlagsNone, data.AsType(), typeKindSubstitution) } func (c *Checker) newSignature(flags SignatureFlags, declaration *ast.Node, typeParameters []*Type, thisParameter *ast.Symbol, parameters []*ast.Symbol, resolvedReturnType *Type, resolvedTypePredicate *TypePredicate, minArgumentCount int) *Signature { @@ -25789,11 +25878,11 @@ func (c *Checker) newSignature(flags SignatureFlags, declaration *ast.Node, type sig.id = SignatureId(c.SignatureCount) sig.flags = flags sig.declaration = declaration - sig.typeParameters = typeParameters + sig.setTypeParameters(c, typeParameters) sig.parameters = parameters - sig.thisParameter = thisParameter + sig.setThisParameter(c, thisParameter) sig.resolvedReturnType = resolvedReturnType - sig.resolvedTypePredicate = resolvedTypePredicate + sig.setResolvedTypePredicate(c, resolvedTypePredicate) sig.minArgumentCount = int32(minArgumentCount) sig.resolvedMinArgumentCount = -1 return sig @@ -26113,27 +26202,37 @@ func (c *Checker) mapTypeEx(t *Type, f func(*Type) *Type, noReductions bool) *Ty if u.origin != nil && u.origin.flags&TypeFlagsUnion != 0 { types = u.origin.Types() } - mappedTypes := make([]*Type, 0, 16) + var set *temporaryTypeSet + defer func() { + if set != nil { + c.releaseTemporaryTypeSet(set) + } + }() + var mappedTypes []*Type var changed bool - for _, s := range types { + for i, s := range types { var mapped *Type if s.flags&TypeFlagsUnion != 0 { mapped = c.mapTypeEx(s, f, noReductions) } else { mapped = f(s) } - if mapped != s { + if mapped != s && !changed { changed = true + set = c.getTemporaryTypeSet() + mappedTypes = set.values[:0] + mappedTypes = append(mappedTypes, types[:i]...) } - if mapped != nil { + if changed && mapped != nil { mappedTypes = append(mappedTypes, mapped) } } if changed { + set.values = mappedTypes if len(mappedTypes) == 0 { return nil } - return c.getUnionTypeEx(slices.Clone(mappedTypes), core.IfElse(noReductions, UnionReductionNone, UnionReductionLiteral), nil /*alias*/, nil /*origin*/) + return c.getUnionTypeEx(mappedTypes, core.IfElse(noReductions, UnionReductionNone, UnionReductionLiteral), nil /*alias*/, nil /*origin*/) } return t } @@ -26190,7 +26289,10 @@ func (c *Checker) getUnionTypeEx(types []*Type, unionReduction UnionReduction, a } func (c *Checker) getUnionTypeWorker(types []*Type, unionReduction UnionReduction, alias *TypeAlias, origin *Type) *Type { - typeSet, includes := c.addTypesToUnion(types) + set := c.getTemporaryTypeSet() + defer c.releaseTemporaryTypeSet(set) + typeSet, includes := c.addTypesToUnion(types, set.values[:0]) + set.values = typeSet if unionReduction != UnionReductionNone { if includes&TypeFlagsAnyOrUnknown != 0 { if includes&TypeFlagsAny != 0 { @@ -26297,8 +26399,7 @@ func (c *Checker) UnionTypes() iter.Seq[*Type] { return maps.Values(c.unionTypes) } -func (c *Checker) addTypesToUnion(sourceTypes []*Type) ([]*Type, TypeFlags) { - types := make([]*Type, 0, len(sourceTypes)) +func (c *Checker) addTypesToUnion(sourceTypes []*Type, types []*Type) ([]*Type, TypeFlags) { var includes TypeFlags addType := func(t *Type) { flags := t.flags @@ -26556,8 +26657,9 @@ func (c *Checker) removeSubtypes(types []*Type, hasObjectTypes bool) []*Type { } } } - c.subtypeReductionCache[key] = types - return types + reduced := c.typeListArena.Clone(types) + c.subtypeReductionCache[key] = reduced + return reduced } func (c *Checker) intersectTypes(type1 *Type, type2 *Type) *Type { @@ -26593,10 +26695,10 @@ func (c *Checker) getIntersectionType(types []*Type) *Type { } func (c *Checker) getIntersectionTypeEx(types []*Type, flags IntersectionFlags, alias *TypeAlias) *Type { - var orderedTypes orderedSet[*Type] - orderedTypes.values = make([]*Type, 0, len(types)) - includes := c.addTypesToIntersection(&orderedTypes, 0, types) - typeSet := orderedTypes.values + set := c.getTemporaryTypeSet() + defer c.releaseTemporaryTypeSet(set) + includes := c.addTypesToIntersection(&set.orderedSet, 0, types) + typeSet := set.values objectFlags := ObjectFlagsNone // An intersection type is considered empty if it contains // the type never, or @@ -27018,7 +27120,7 @@ func (c *Checker) IsEmptyAnonymousObjectType(t *Type) bool { } func (c *Checker) isEmptyResolvedType(t *StructuredType) bool { - return t.AsType() != c.anyFunctionType && len(t.properties) == 0 && len(t.signatures) == 0 && len(t.indexInfos) == 0 + return t.AsType() != c.anyFunctionType && len(t.properties) == 0 && len(t.getSignatures()) == 0 && len(t.getIndexInfos()) == 0 } func (c *Checker) isEmptyObjectType(t *Type) bool { @@ -27146,7 +27248,11 @@ func (c *Checker) removeType(t *Type, targetType *Type) *Type { return types[1-i] } // Remove the target type from the slice. - filtered := append(types[:i:i], types[i+1:]...) + set := c.getTemporaryTypeSet() + defer c.releaseTemporaryTypeSet(set) + set.values = append(set.values[:0], types[:i]...) + set.values = append(set.values, types[i+1:]...) + filtered := set.values return c.getUnionTypeFromSortedList(filtered, t.AsUnionType().objectFlags&(ObjectFlagsPrimitiveUnion|ObjectFlagsContainsIntersections), nil /*alias*/, nil /*origin*/) } return t @@ -27284,7 +27390,7 @@ func (c *Checker) getLiteralTypeFromProperties(t *Type, include TypeFlags, inclu func (c *Checker) getLiteralTypeFromProperty(prop *ast.Symbol, include TypeFlags, includeNonPublic bool) *Type { if includeNonPublic || getDeclarationModifierFlagsFromSymbol(prop)&ast.ModifierFlagsNonPublicAccessibilityModifier == 0 { - t := c.valueSymbolLinks.Get(c.getLateBoundSymbol(prop)).nameType + t := c.valueSymbolLinks.Get(c.getLateBoundSymbol(prop)).getNameType() if t == nil { if prop.Name() == ast.InternalSymbolNameDefault { t = c.getStringLiteralType("default") @@ -28398,7 +28504,7 @@ func (c *Checker) containsUndefinedType(t *Type) bool { } func (c *Checker) typeHasCallOrConstructSignatures(t *Type) bool { - return t.flags&TypeFlagsStructuredType != 0 && len(c.resolveStructuredTypeMembers(t).signatures) != 0 + return t.flags&TypeFlagsStructuredType != 0 && len(c.resolveStructuredTypeMembers(t).getSignatures()) != 0 } func (c *Checker) getNormalizedType(t *Type, writing bool) *Type { @@ -28705,7 +28811,7 @@ func (c *Checker) getRegularTypeOfObjectLiteral(t *Type) *Type { } resolved := c.resolveStructuredTypeMembers(t) members := c.transformTypeOfMembers(t, c.getRegularTypeOfObjectLiteral) - regular := c.newAnonymousType(t.symbol, members, resolved.CallSignatures(), resolved.ConstructSignatures(), resolved.indexInfos) + regular := c.newAnonymousType(t.symbol, members, resolved.CallSignatures(), resolved.ConstructSignatures(), resolved.getIndexInfos()) regular.flags = resolved.flags regular.objectFlags |= resolved.objectFlags & ^ObjectFlagsFreshLiteral c.cachedTypes[key] = regular @@ -30483,7 +30589,7 @@ func (c *Checker) getContextualTypeForObjectLiteralElement(element *ast.Node, co // in the type. It will just be "__computed", which does not appear in any // SymbolTable. symbol := c.getSymbolOfDeclaration(element) - return c.getTypeOfPropertyOfContextualTypeEx(t, symbol.Name(), c.valueSymbolLinks.Get(symbol).nameType) + return c.getTypeOfPropertyOfContextualTypeEx(t, symbol.Name(), c.valueSymbolLinks.Get(symbol).getNameType()) } if ast.HasDynamicName(element) { name := ast.GetNameOfDeclaration(element) @@ -31698,7 +31804,7 @@ func (c *Checker) isFunctionObjectType(t *Type) bool { // We do a quick check for a "bind" property before performing the more expensive subtype // check. This gives us a quicker out in the common case where an object type is not a function. resolved := c.resolveStructuredTypeMembers(t) - return len(resolved.signatures) != 0 || resolved.members["bind"] != nil && c.isTypeSubtypeOf(t, c.globalFunctionType) + return len(resolved.getSignatures()) != 0 || resolved.getMember("bind") != nil && c.isTypeSubtypeOf(t, c.globalFunctionType) } func (c *Checker) getTypeWithFacts(t *Type, include TypeFacts) *Type { @@ -32194,7 +32300,7 @@ func (c *Checker) getSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Sy // member should more exactly be the kind of (declarationless) symbol we want. // (See #44364 and #45031 for relevant implementation PRs) if metaProp.KeywordToken == ast.KindImportKeyword && node.Text() == "meta" { - return c.getGlobalImportMetaExpressionType().AsObjectType().members["meta"] + return c.getGlobalImportMetaExpressionType().AsObjectType().getMember("meta") } // no other meta properties are valid syntax, thus no others should have symbols return nil @@ -32219,8 +32325,8 @@ func (c *Checker) getSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Sy container := c.getThisContainer(node, false /*includeArrowFunctions*/, false /*includeClassComputedPropertyName*/) if ast.IsFunctionLike(container) { sig := c.getSignatureFromDeclaration(container) - if sig.thisParameter != nil { - return sig.thisParameter + if sig.ThisParameter() != nil { + return sig.ThisParameter() } } if ast.IsInExpressionContext(node) { diff --git a/tsc/internal/checker/checker_test.go b/tsc/internal/checker/checker_test.go index 2ed189904d64b..474a3f24eddcc 100644 --- a/tsc/internal/checker/checker_test.go +++ b/tsc/internal/checker/checker_test.go @@ -1,7 +1,10 @@ package checker_test import ( + "fmt" "path/filepath" + "strconv" + "strings" "testing" "github.com/microsoft/TypeScript/tsc/internal/ast" @@ -115,6 +118,51 @@ export type E = D;`, assert.Equal(t, defaultClause, defaultReference) } +func TestUnionPropertyFunctionAugmentation(t *testing.T) { + t.Parallel() + for _, lookupFirst := range []bool{false, true} { + t.Run(strconv.FormatBool(lookupFirst), func(t *testing.T) { + t.Parallel() + fs := bundled.WrapFS(vfstest.FromMap(map[string]string{ + "/main.ts": `type Callable = { (): string; shared: string }; +type Other = { call: number; shared: number }; +declare const instance: Callable | Other; +instance;`, + "/function.d.ts": `interface Function { + call(thisArg: any, ...args: any[]): any; +} +interface CallableFunction extends Function {}`, + "/tsconfig.json": `{"compilerOptions":{"strict":true,"noLib":true},"files":["main.ts","function.d.ts"]}`, + }, tspath.CaseInsensitive)) + host := compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil) + parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, nil, fs, nil) + assert.Equal(t, len(errors), 0) + program := compiler.NewProgram(compiler.ProgramOptions{Config: parsed, Host: host}) + program.BindSourceFiles() + c, done := program.GetTypeChecker(t.Context()) + defer done() + file := program.GetSourceFile("/main.ts") + typ := c.GetTypeAtLocation(file.Statements.Nodes[3].Expression()) + var call *ast.Symbol + if lookupFirst { + call = c.GetPropertyOfType(typ, "call") + assert.Assert(t, call != nil) + } + properties := c.GetPropertiesOfType(typ) + assert.Equal(t, len(properties), 1) + assert.Equal(t, properties[0].Name(), "shared") + if call == nil { + call = c.GetPropertyOfType(typ, "call") + assert.Assert(t, call != nil) + } + assert.Equal(t, c.GetPropertyOfType(typ, "call"), call) + assert.Equal(t, c.GetPropertyOfType(typ, "shared"), properties[0]) + assert.Equal(t, len(c.GetPropertiesOfType(typ)), 1) + assert.Equal(t, len(c.GetDiagnostics(t.Context(), file)), 0) + }) + } +} + func BenchmarkNewChecker(b *testing.B) { fs := bundled.WrapFS(osvfs.FS()) rootPath := tspath.RootedDirectoryPathFromAbsolute(filepath.Join(repo.TestDataPath(), "fixtures/compiler")) @@ -131,3 +179,82 @@ func BenchmarkNewChecker(b *testing.B) { checker.NewChecker(program, nil) } } + +func BenchmarkCheck(b *testing.B) { + fs := bundled.WrapFS(osvfs.FS()) + rootPath := tspath.RootedDirectoryPathFromAbsolute(filepath.Join(repo.TestDataPath(), "fixtures/compiler")) + host := compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil) + parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(rootPath.ResolveFile("tsconfig.json"), &core.CompilerOptions{}, nil, fs, nil) + assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line") + program := compiler.NewProgram(compiler.ProgramOptions{ + Config: parsed, + Host: host, + }) + program.BindSourceFiles() + ctx := b.Context() + + b.ReportAllocs() + for b.Loop() { + c, _ := checker.NewChecker(program, nil) + for _, file := range program.GetSourceFiles() { + c.GetDiagnostics(ctx, file) + } + c.GetGlobalDiagnostics() + } +} + +func BenchmarkCheckFreshProgram(b *testing.B) { + fs := bundled.WrapFS(osvfs.FS()) + rootPath := tspath.RootedDirectoryPathFromAbsolute(filepath.Join(repo.TestDataPath(), "fixtures/compiler")) + host := compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil) + parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(rootPath.ResolveFile("tsconfig.json"), &core.CompilerOptions{}, nil, fs, nil) + for _, diagnostic := range errors { + b.Fatal(diagnostic.String()) + } + ctx := b.Context() + + b.ReportAllocs() + for b.Loop() { + program := compiler.NewProgram(compiler.ProgramOptions{Config: parsed, Host: host}) + program.BindSourceFiles() + c, _ := checker.NewChecker(program, nil) + for _, file := range program.GetSourceFiles() { + for _, diagnostic := range c.GetDiagnostics(ctx, file) { + b.Fatal(diagnostic.String()) + } + } + assert.Equal(b, len(c.GetGlobalDiagnostics()), 0) + } +} + +func TestTypeAllocationAcrossCheckerGrowth(t *testing.T) { + t.Parallel() + var content strings.Builder + content.WriteString(`interface Box { value: T } +export type Initial = Box<"first">; +`) + for i := range 1024 { + fmt.Fprintf(&content, "export type T%d = Box<\"value%d\">;\n", i, i) + } + fs := bundled.WrapFS(vfstest.FromMap(map[string]string{ + "/foo.ts": content.String(), + }, tspath.CaseSensitive)) + opts := &core.CompilerOptions{NoLib: core.TSTrue} + program := compiler.NewProgram(compiler.ProgramOptions{ + Config: tsoptions.NewParsedCommandLine(opts, []tspath.RootedFilePath{"/foo.ts"}, nil, "/", fs.CaseSensitivity()), + Host: compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil), + }) + program.BindSourceFiles() + c, done := program.GetTypeChecker(t.Context()) + defer done() + file := program.GetSourceFile("/foo.ts") + initial := c.GetTypeAtLocation(file.Statements.Nodes[1].AsTypeAliasDeclaration().Type) + for i := range 1024 { + node := file.Statements.Nodes[i+2].AsTypeAliasDeclaration().Type + typ := c.GetTypeAtLocation(node) + assert.Equal(t, c.TypeToString(typ), fmt.Sprintf("T%d", i)) + } + assert.Equal(t, c.GetTypeAtLocation(file.Statements.Nodes[1].AsTypeAliasDeclaration().Type), initial) + assert.Equal(t, c.TypeToString(initial), "Initial") + assert.Equal(t, len(c.GetDiagnostics(t.Context(), file)), 0) +} diff --git a/tsc/internal/checker/exports.go b/tsc/internal/checker/exports.go index f77488e783142..1a7afc78e9acb 100644 --- a/tsc/internal/checker/exports.go +++ b/tsc/internal/checker/exports.go @@ -83,7 +83,7 @@ func (c *Checker) GetUnionType(types []*Type) *Type { func (c *Checker) GetNameTypeOfSymbol(symbol *ast.Symbol) *Type { if links := c.valueSymbolLinks.TryGet(symbol); links != nil { - return links.nameType + return links.getNameType() } return nil } diff --git a/tsc/internal/checker/flow.go b/tsc/internal/checker/flow.go index 24d2f4f48b566..d2831231772fe 100644 --- a/tsc/internal/checker/flow.go +++ b/tsc/internal/checker/flow.go @@ -2071,7 +2071,7 @@ func (c *Checker) getEffectsSignature(node *ast.Node) *Signature { } signatures := c.getSignaturesOfType(core.OrElse(apparentType, c.unknownType), SignatureKindCall) switch { - case len(signatures) == 1 && len(signatures[0].typeParameters) == 0: + case len(signatures) == 1 && len(signatures[0].TypeParameters()) == 0: signature = signatures[0] case core.Some(signatures, c.hasTypePredicateOrNeverReturnType): signature = c.getResolvedSignature(node, nil, CheckModeNormal) @@ -2216,8 +2216,8 @@ func (c *Checker) getExplicitThisType(node *ast.Node) *Type { container := ast.GetThisContainer(node, false /*includeArrowFunctions*/, false /*includeClassComputedPropertyName*/) if ast.IsFunctionLike(container) { signature := c.getSignatureFromDeclaration(container) - if signature.thisParameter != nil { - return c.getExplicitTypeOfSymbol(signature.thisParameter, nil) + if signature.ThisParameter() != nil { + return c.getExplicitTypeOfSymbol(signature.ThisParameter(), nil) } } if container.Parent != nil && ast.IsClassLike(container.Parent) { diff --git a/tsc/internal/checker/inference.go b/tsc/internal/checker/inference.go index c71e412fef47f..02c7d009b9ec5 100644 --- a/tsc/internal/checker/inference.go +++ b/tsc/internal/checker/inference.go @@ -1132,7 +1132,7 @@ func (c *Checker) resolveReverseMappedTypeMembers(t *Type) { checkFlags := ast.CheckFlagsReverseMapped | core.IfElse(readonlyMask && c.isReadonlySymbol(prop), ast.CheckFlagsReadonly, 0) inferredProp := c.newSymbolEx(ast.SymbolFlagsProperty|prop.Flags()&optionalMask, prop.Name(), checkFlags) inferredProp.SetDeclarations(prop.Declarations()) - c.valueSymbolLinks.Get(inferredProp).nameType = c.valueSymbolLinks.Get(prop).nameType + c.valueSymbolLinks.Get(inferredProp).setNameType(c, c.valueSymbolLinks.Get(prop).getNameType()) links := c.ReverseMappedSymbolLinks.Get(inferredProp) links.propertyType = c.getTypeOfSymbol(prop) constraintTarget := r.constraintType.AsIndexType().target @@ -1288,8 +1288,8 @@ func (c *Checker) newInferenceContextWorker(inferences []*InferenceInfo, signatu flags: flags, compareTypes: compareTypes, } - n.mapper = c.newInferenceTypeMapper(n, true /*fixing*/) - n.nonFixingMapper = c.newInferenceTypeMapper(n, false /*fixing*/) + n.mapper = c.initInferenceTypeMapper(&n.mapperStorage[0], n, true /*fixing*/) + n.nonFixingMapper = c.initInferenceTypeMapper(&n.mapperStorage[1], n, false /*fixing*/) return n } diff --git a/tsc/internal/checker/jsx.go b/tsc/internal/checker/jsx.go index 4e7dc902d23c6..7f35f796957cf 100644 --- a/tsc/internal/checker/jsx.go +++ b/tsc/internal/checker/jsx.go @@ -987,14 +987,14 @@ func (c *Checker) getJsxPropsTypeFromClassType(sig *Signature, context *ast.Node } func (c *Checker) getJsxPropsTypeForSignatureFromMember(sig *Signature, forcedLookupLocation string) *Type { - if sig.composite != nil { + if sig.getComposite() != nil { // JSX Elements using the legacy `props`-field based lookup (eg, react class components) need to treat the `props` member as an input // instead of an output position when resolving the signature. We need to go back to the input signatures of the composite signature, // get the type of `props` on each return type individually, and then _intersect them_, rather than union them (as would normally occur // for a union signature). It's an unfortunate quirk of looking in the output of the signature for the type we want to use for the input. // The default behavior of `getTypeOfFirstParameterOfSignatureWithFallback` when no `props` member name is defined is much more sane. var results []*Type - for _, signature := range sig.composite.signatures { + for _, signature := range sig.getComposite().signatures { instance := c.getReturnTypeOfSignature(signature) if IsTypeAny(instance) { return instance diff --git a/tsc/internal/checker/mapper.go b/tsc/internal/checker/mapper.go index 24a94c94ffdf1..1eebf157dbdc3 100644 --- a/tsc/internal/checker/mapper.go +++ b/tsc/internal/checker/mapper.go @@ -2,6 +2,7 @@ package checker import ( "slices" + "unsafe" "github.com/microsoft/TypeScript/tsc/internal/core" ) @@ -20,19 +21,91 @@ const ( // TypeMapper type TypeMapper struct { - data TypeMapperData + kind typeMapperKind } -func (m *TypeMapper) Map(t *Type) *Type { return m.data.Map(t) } -func (m *TypeMapper) Kind() TypeMapperKind { return m.data.Kind() } -func (m *TypeMapper) MapsThisOnly() bool { return m.data.MapsThisOnly() } +type typeMapperKind uint8 -// TypeMapperData +const ( + typeMapperSimple typeMapperKind = iota + 1 + typeMapperArray + typeMapperArrayToSingle + typeMapperDeferred + typeMapperFunction + typeMapperMerged + typeMapperComposite + typeMapperInference +) + +// Each concrete mapper embeds the immutable kind header at offset zero. +func castTypeMapper[T any](m *TypeMapper, kind typeMapperKind) *T { + if m.kind != kind { + panic("Incorrect type mapper kind") + } + return (*T)(unsafe.Pointer(m)) +} + +var ( + _ [0 - unsafe.Offsetof(SimpleTypeMapper{}.TypeMapperBase)]byte + _ [0 - unsafe.Offsetof(ArrayTypeMapper{}.TypeMapperBase)]byte + _ [0 - unsafe.Offsetof(ArrayToSingleTypeMapper{}.TypeMapperBase)]byte + _ [0 - unsafe.Offsetof(DeferredTypeMapper{}.TypeMapperBase)]byte + _ [0 - unsafe.Offsetof(FunctionTypeMapper{}.TypeMapperBase)]byte + _ [0 - unsafe.Offsetof(MergedTypeMapper{}.TypeMapperBase)]byte + _ [0 - unsafe.Offsetof(CompositeTypeMapper{}.TypeMapperBase)]byte + _ [0 - unsafe.Offsetof(InferenceTypeMapper{}.TypeMapperBase)]byte + _ [0 - unsafe.Offsetof(TypeMapperBase{}.TypeMapper)]byte +) + +func (m *TypeMapper) Map(t *Type) *Type { + switch m.kind { + case typeMapperSimple: + return castTypeMapper[SimpleTypeMapper](m, typeMapperSimple).Map(t) + case typeMapperArray: + return castTypeMapper[ArrayTypeMapper](m, typeMapperArray).Map(t) + case typeMapperArrayToSingle: + return castTypeMapper[ArrayToSingleTypeMapper](m, typeMapperArrayToSingle).Map(t) + case typeMapperDeferred: + return castTypeMapper[DeferredTypeMapper](m, typeMapperDeferred).Map(t) + case typeMapperFunction: + return castTypeMapper[FunctionTypeMapper](m, typeMapperFunction).Map(t) + case typeMapperMerged: + return castTypeMapper[MergedTypeMapper](m, typeMapperMerged).Map(t) + case typeMapperComposite: + return castTypeMapper[CompositeTypeMapper](m, typeMapperComposite).Map(t) + case typeMapperInference: + return castTypeMapper[InferenceTypeMapper](m, typeMapperInference).Map(t) + default: + panic("Invalid type mapper kind") + } +} + +func (m *TypeMapper) Kind() TypeMapperKind { + switch m.kind { + case typeMapperSimple: + return TypeMapperKindSimple + case typeMapperArray: + return TypeMapperKindArray + case typeMapperMerged: + return TypeMapperKindMerged + default: + return TypeMapperKindUnknown + } +} -type TypeMapperData interface { - Map(t *Type) *Type - Kind() TypeMapperKind - MapsThisOnly() bool +func (m *TypeMapper) MapsThisOnly() bool { + switch m.kind { + case typeMapperSimple: + return castTypeMapper[SimpleTypeMapper](m, typeMapperSimple).MapsThisOnly() + case typeMapperArray: + return castTypeMapper[ArrayTypeMapper](m, typeMapperArray).MapsThisOnly() + case typeMapperArrayToSingle: + return castTypeMapper[ArrayToSingleTypeMapper](m, typeMapperArrayToSingle).MapsThisOnly() + case typeMapperDeferred: + return castTypeMapper[DeferredTypeMapper](m, typeMapperDeferred).MapsThisOnly() + default: + return false + } } // Factory functions @@ -117,7 +190,7 @@ type SimpleTypeMapper struct { func newSimpleTypeMapper(source *Type, target *Type) *TypeMapper { m := &SimpleTypeMapper{} - m.data = m + m.kind = typeMapperSimple m.source = source m.target = target return &m.TypeMapper @@ -148,7 +221,7 @@ type ArrayTypeMapper struct { func newArrayTypeMapper(sources []*Type, targets []*Type) *TypeMapper { m := &ArrayTypeMapper{} - m.data = m + m.kind = typeMapperArray m.sources = sources m.targets = targets return &m.TypeMapper @@ -181,7 +254,7 @@ type ArrayToSingleTypeMapper struct { func newArrayToSingleTypeMapper(sources []*Type, target *Type) *TypeMapper { m := &ArrayToSingleTypeMapper{} - m.data = m + m.kind = typeMapperArrayToSingle m.sources = sources m.target = target return &m.TypeMapper @@ -208,7 +281,7 @@ type DeferredTypeMapper struct { func newDeferredTypeMapper(sources []*Type, targets []func() *Type) *TypeMapper { m := &DeferredTypeMapper{} - m.data = m + m.kind = typeMapperDeferred m.sources = sources m.targets = targets return &m.TypeMapper @@ -236,7 +309,7 @@ type FunctionTypeMapper struct { func newFunctionTypeMapper(fn func(*Type) *Type) *TypeMapper { m := &FunctionTypeMapper{} - m.data = m + m.kind = typeMapperFunction m.fn = fn return &m.TypeMapper } @@ -255,7 +328,7 @@ type MergedTypeMapper struct { func newMergedTypeMapper(m1 *TypeMapper, m2 *TypeMapper) *TypeMapper { m := &MergedTypeMapper{} - m.data = m + m.kind = typeMapperMerged m.m1 = m1 m.m2 = m2 return &m.TypeMapper @@ -280,7 +353,7 @@ type CompositeTypeMapper struct { func newCompositeTypeMapper(c *Checker, m1 *TypeMapper, m2 *TypeMapper) *TypeMapper { m := &CompositeTypeMapper{} - m.data = m + m.kind = typeMapperComposite m.c = c m.m1 = m1 m.m2 = m2 @@ -304,9 +377,8 @@ type InferenceTypeMapper struct { fixing bool } -func (c *Checker) newInferenceTypeMapper(n *InferenceContext, fixing bool) *TypeMapper { - m := &InferenceTypeMapper{} - m.data = m +func (c *Checker) initInferenceTypeMapper(m *InferenceTypeMapper, n *InferenceContext, fixing bool) *TypeMapper { + m.kind = typeMapperInference m.c = c m.n = n m.fixing = fixing diff --git a/tsc/internal/checker/nodebuilderimpl.go b/tsc/internal/checker/nodebuilderimpl.go index cd4643ac6f273..5f939e9e7ec54 100644 --- a/tsc/internal/checker/nodebuilderimpl.go +++ b/tsc/internal/checker/nodebuilderimpl.go @@ -566,19 +566,19 @@ func (b *NodeBuilderImpl) getResolvedTypeWithoutAbstractConstructSignatures(t *S if len(t.ConstructSignatures()) == 0 { return t.AsType() } - if t.objectTypeWithoutAbstractConstructSignatures != nil { - return t.objectTypeWithoutAbstractConstructSignatures + if t.extra.objectTypeWithoutAbstractConstructSignatures != nil { + return t.extra.objectTypeWithoutAbstractConstructSignatures } constructSignatures := core.Filter(t.ConstructSignatures(), func(signature *Signature) bool { return signature.flags&SignatureFlagsAbstract == 0 }) if len(constructSignatures) == len(t.ConstructSignatures()) { - t.objectTypeWithoutAbstractConstructSignatures = t.AsType() + t.extra.objectTypeWithoutAbstractConstructSignatures = t.AsType() return t.AsType() } - typeCopy := b.ch.newAnonymousType(t.symbol, t.members, t.CallSignatures(), core.IfElse(len(constructSignatures) > 0, constructSignatures, []*Signature{}), t.indexInfos) - t.objectTypeWithoutAbstractConstructSignatures = typeCopy - typeCopy.AsStructuredType().objectTypeWithoutAbstractConstructSignatures = typeCopy + typeCopy := b.ch.newAnonymousType(t.symbol, t.getMembers(), t.CallSignatures(), core.IfElse(len(constructSignatures) > 0, constructSignatures, []*Signature{}), t.getIndexInfos()) + t.extra.objectTypeWithoutAbstractConstructSignatures = typeCopy + typeCopy.AsStructuredType().ensureExtra(b.ch).objectTypeWithoutAbstractConstructSignatures = typeCopy return typeCopy } @@ -591,7 +591,7 @@ func (b *NodeBuilderImpl) symbolToNode(symbol *ast.Symbol, meaning ast.SymbolFla } } if b.ch.valueSymbolLinks.Has(symbol) { - nameType := b.ch.valueSymbolLinks.Get(symbol).nameType + nameType := b.ch.valueSymbolLinks.Get(symbol).getNameType() if nameType != nil && nameType.flags&(TypeFlagsEnumLiteral|TypeFlagsUniqueESSymbol) != 0 { oldEnclosing := b.ctx.enclosingDeclaration b.ctx.enclosingDeclaration = nameType.symbol.ValueDeclaration() @@ -936,7 +936,7 @@ func isDefaultBindingContext(location *ast.Node) bool { func (b *NodeBuilderImpl) getNameOfSymbolFromNameType(symbol *ast.Symbol) string { if b.ch.valueSymbolLinks.Has(symbol) { - nameType := b.ch.valueSymbolLinks.Get(symbol).nameType + nameType := b.ch.valueSymbolLinks.Get(symbol).getNameType() if nameType == nil { return "" } @@ -993,7 +993,7 @@ func (b *NodeBuilderImpl) getNameOfSymbolAsWritten(symbol *ast.Symbol) string { // return symbol.Name // } if ast.IsComputedPropertyName(name) && symbol.CheckFlags()&ast.CheckFlagsLate == 0 { - if b.ch.valueSymbolLinks.Has(symbol) && b.ch.valueSymbolLinks.Get(symbol).nameType != nil && b.ch.valueSymbolLinks.Get(symbol).nameType.flags&TypeFlagsStringOrNumberLiteral != 0 { + if b.ch.valueSymbolLinks.Has(symbol) && b.ch.valueSymbolLinks.Get(symbol).getNameType() != nil && b.ch.valueSymbolLinks.Get(symbol).getNameType().flags&TypeFlagsStringOrNumberLiteral != 0 { result := b.getNameOfSymbolFromNameType(symbol) if len(result) > 0 { return result @@ -1869,12 +1869,12 @@ func (b *NodeBuilderImpl) signatureToSignatureDeclarationHelper(signature *Signa b.ctx.approximateLength += 3 // Usually a signature contributes a few more characters than this, but 3 is the minimum - if b.ctx.flags&nodebuilder.FlagsWriteTypeArgumentsOfSignature != 0 && signature.target != nil && signature.mapper != nil && len(signature.target.typeParameters) != 0 { - for _, parameter := range signature.target.typeParameters { + if b.ctx.flags&nodebuilder.FlagsWriteTypeArgumentsOfSignature != 0 && signature.target != nil && signature.mapper != nil && len(signature.target.TypeParameters()) != 0 { + for _, parameter := range signature.target.TypeParameters() { typeParameters = append(typeParameters, b.typeToTypeNode(b.ch.instantiateType(parameter, signature.mapper))) } } else { - for _, parameter := range signature.typeParameters { + for _, parameter := range signature.TypeParameters() { typeParameters = append(typeParameters, b.typeParameterToDeclaration(parameter)) } } @@ -2071,8 +2071,8 @@ func (c *Checker) getExpandedParameters(sig *Signature, skipUnionExpanding bool) } func (b *NodeBuilderImpl) tryGetThisParameterDeclaration(signature *Signature) *ast.Node { - if signature.thisParameter != nil { - return b.symbolToParameterDeclaration(signature.thisParameter, false) + if signature.ThisParameter() != nil { + return b.symbolToParameterDeclaration(signature.ThisParameter(), false) } if signature.declaration != nil && ast.IsInJSFile(signature.declaration) { // !!! JSDoc Support @@ -2531,7 +2531,7 @@ func (b *NodeBuilderImpl) getPropertyNameNodeForSymbolFromNameType(symbol *ast.S if !b.ch.valueSymbolLinks.Has(symbol) { return nil } - nameType := b.ch.valueSymbolLinks.TryGet(symbol).nameType + nameType := b.ch.valueSymbolLinks.TryGet(symbol).getNameType() if nameType == nil { return nil } @@ -2737,7 +2737,7 @@ func (b *NodeBuilderImpl) createTypeNodesFromResolvedType(resolvedType *Structur } typeElements = append(typeElements, b.signatureToSignatureDeclarationHelper(signature, ast.KindConstructSignature, nil)) } - for _, info := range resolvedType.indexInfos { + for _, info := range resolvedType.getIndexInfos() { var typeNode *ast.TypeNode if resolvedType.objectFlags&ObjectFlagsReverseMapped != 0 && b.ctx.flags&nodebuilder.FlagsAllowAnonymousIdentifier != 0 { typeNode = b.createElidedInformationPlaceholder() @@ -2794,7 +2794,7 @@ func (b *NodeBuilderImpl) createTypeNodeFromObjectType(t *Type) *ast.TypeNode { resolved := b.ch.resolveStructuredTypeMembers(t) callSigs := resolved.CallSignatures() ctorSigs := resolved.ConstructSignatures() - if len(resolved.properties) == 0 && len(resolved.indexInfos) == 0 { + if len(resolved.properties) == 0 && len(resolved.getIndexInfos()) == 0 { if len(callSigs) == 0 && len(ctorSigs) == 0 { b.ctx.approximateLength += 2 result := b.f.NewTypeLiteralNode(b.f.NewNodeList([]*ast.Node{})) @@ -2823,7 +2823,7 @@ func (b *NodeBuilderImpl) createTypeNodeFromObjectType(t *Type) *ast.TypeNode { return b.ch.getOrCreateTypeFromSignature(s) }) // count the number of type elements excluding abstract constructors - typeElementCount := len(callSigs) + (len(ctorSigs) - len(abstractSignatures)) + len(resolved.indexInfos) + core.IfElse(b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0, core.CountWhere(resolved.properties, func(p *ast.Symbol) bool { + typeElementCount := len(callSigs) + (len(ctorSigs) - len(abstractSignatures)) + len(resolved.getIndexInfos()) + core.IfElse(b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0, core.CountWhere(resolved.properties, func(p *ast.Symbol) bool { return p.Flags()&ast.SymbolFlagsPrototype == 0 }), len(resolved.properties)) // don't include an empty object literal if there were no other static-side diff --git a/tsc/internal/checker/nodebuilderscopes.go b/tsc/internal/checker/nodebuilderscopes.go index 244d598682c59..05f033bf05b7d 100644 --- a/tsc/internal/checker/nodebuilderscopes.go +++ b/tsc/internal/checker/nodebuilderscopes.go @@ -52,7 +52,7 @@ func (b *NodeBuilderImpl) addSymbolTypeToContext(symbol *ast.Symbol, t *Type) fu func (b *NodeBuilderImpl) enterSignatureScope(signature *Signature) (expandedParams []*ast.Symbol, cleanup func()) { expandedParams = b.ch.getExpandedParameters(signature, true /*skipUnionExpanding*/)[0] - cleanup = b.enterNewScope(signature.declaration, expandedParams, signature.typeParameters, signature.parameters, signature.mapper) + cleanup = b.enterNewScope(signature.declaration, expandedParams, signature.TypeParameters(), signature.parameters, signature.mapper) return expandedParams, cleanup } diff --git a/tsc/internal/checker/nodecopy.go b/tsc/internal/checker/nodecopy.go index c098604800dc0..1cf0e628f5ca6 100644 --- a/tsc/internal/checker/nodecopy.go +++ b/tsc/internal/checker/nodecopy.go @@ -838,7 +838,7 @@ func getExistingNodeTreeVisitor(b *NodeBuilderImpl, bound *recoveryBoundary) *as if ast.IsFunctionLike(node) { sig := b.ch.getSignatureFromDeclaration(node) params = sig.parameters - typeParams = sig.typeParameters + typeParams = sig.TypeParameters() } else if ast.IsConditionalTypeNode(node) { // !!! TODO: impossible in combination with the scope start check??? typeParams = b.ch.getInferTypeParameters(node) } else if ast.IsMappedTypeNode(node) { diff --git a/tsc/internal/checker/pseudotypenodebuilder.go b/tsc/internal/checker/pseudotypenodebuilder.go index 40ca59da0ebec..8f1e2bf1700e1 100644 --- a/tsc/internal/checker/pseudotypenodebuilder.go +++ b/tsc/internal/checker/pseudotypenodebuilder.go @@ -178,7 +178,7 @@ func (b *NodeBuilderImpl) pseudoTypeToNode(t *pseudochecker.PseudoType) *ast.Nod d := t.AsPseudoTypeSingleCallSignature() signature := b.ch.getSignatureFromDeclaration(d.Signature) expandedParams := b.ch.getExpandedParameters(signature, true /*skipUnionExpanding*/)[0] - cleanup := b.enterNewScope(d.Signature, expandedParams, signature.typeParameters, signature.parameters, signature.mapper) + cleanup := b.enterNewScope(d.Signature, expandedParams, signature.TypeParameters(), signature.parameters, signature.mapper) defer cleanup() var typeParams *ast.NodeList if len(d.TypeParameters) > 0 { @@ -233,7 +233,7 @@ func (b *NodeBuilderImpl) pseudoTypeToNode(t *pseudochecker.PseudoType) *ast.Nod if e.Kind != pseudochecker.PseudoObjectElementKindPropertyAssignment { signature := b.ch.getSignatureFromDeclaration(e.Signature()) expandedParams := b.ch.getExpandedParameters(signature, true /*skipUnionExpanding*/)[0] - cleanup = b.enterNewScope(e.Signature(), expandedParams, signature.typeParameters, signature.parameters, signature.mapper) + cleanup = b.enterNewScope(e.Signature(), expandedParams, signature.TypeParameters(), signature.parameters, signature.mapper) } var newProp *ast.Node switch e.Kind { @@ -549,7 +549,7 @@ func (b *NodeBuilderImpl) pseudoTypeEquivalentToType(t *pseudochecker.PseudoType return false } pt := t.AsPseudoTypeSingleCallSignature() - if len(targetSig.typeParameters) != len(pt.TypeParameters) { + if len(targetSig.TypeParameters()) != len(pt.TypeParameters) { if reportErrors { b.ctx.tracker.ReportInferenceFallback(pt.Signature) } @@ -583,13 +583,13 @@ func (b *NodeBuilderImpl) pseudoTypeEquivalentToType(t *pseudochecker.PseudoType } func (b *NodeBuilderImpl) pseudoParametersEquivalentToParameters(params []*pseudochecker.PseudoParameter, targetSig *Signature, reportErrors bool, nonParamErrorLocation *ast.Node) bool { - if targetSig.thisParameter != nil && len(params) == 0 { + if targetSig.ThisParameter() != nil && len(params) == 0 { if reportErrors { b.ctx.tracker.ReportInferenceFallback(nonParamErrorLocation) // missing `this` param } return false - } else if targetSig.thisParameter != nil && ast.IsThisIdentifier(params[0].Name) { - targetParam := targetSig.thisParameter + } else if targetSig.ThisParameter() != nil && ast.IsThisIdentifier(params[0].Name) { + targetParam := targetSig.ThisParameter() paramType := b.ch.getTypeOfParameter(targetParam) if !b.pseudoTypeEquivalentToType(params[0].Type, paramType, params[0].Optional, false) { if reportErrors { @@ -598,7 +598,7 @@ func (b *NodeBuilderImpl) pseudoParametersEquivalentToParameters(params []*pseud return false } params = params[1:] - } else if targetSig.thisParameter != nil { + } else if targetSig.ThisParameter() != nil { if reportErrors { b.ctx.tracker.ReportInferenceFallback(nonParamErrorLocation) } diff --git a/tsc/internal/checker/relater.go b/tsc/internal/checker/relater.go index a9bc484fef1d2..a47dfbcb8a971 100644 --- a/tsc/internal/checker/relater.go +++ b/tsc/internal/checker/relater.go @@ -96,22 +96,43 @@ func asRecursionId[T *ast.Node | *ast.Symbol | *Type](value T) RecursionId { } type Relation struct { - results map[CacheHashKey]RelationComparisonResult + genericResults map[CacheHashKey]RelationComparisonResult + simpleResults [4]map[uint64]RelationComparisonResult } -func (r *Relation) get(key CacheHashKey) RelationComparisonResult { - return r.results[key] +type relationKey struct { + value CacheHashKey + generic bool } -func (r *Relation) set(key CacheHashKey, result RelationComparisonResult) { - if r.results == nil { - r.results = make(map[CacheHashKey]RelationComparisonResult) +func (r *Relation) get(key relationKey) RelationComparisonResult { + if key.generic { + return r.genericResults[key.value] + } + return r.simpleResults[key.value.Hi][key.value.Lo] +} + +func (r *Relation) set(key relationKey, result RelationComparisonResult) { + if key.generic { + if r.genericResults == nil { + r.genericResults = make(map[CacheHashKey]RelationComparisonResult) + } + r.genericResults[key.value] = result + } else { + results := &r.simpleResults[key.value.Hi] + if *results == nil { + *results = make(map[uint64]RelationComparisonResult) + } + (*results)[key.value.Lo] = result } - r.results[key] = result } func (r *Relation) size() int { - return len(r.results) + size := len(r.genericResults) + for _, results := range r.simpleResults { + size += len(results) + } + return size } func (c *Checker) isTypeIdenticalTo(source *Type, target *Type) bool { @@ -679,7 +700,7 @@ func (c *Checker) elaborateArrowFunction(node *ast.Node, source *Type, target *T func (c *Checker) isWeakType(t *Type) bool { if t.flags&TypeFlagsObject != 0 { resolved := c.resolveStructuredTypeMembers(t) - return len(resolved.signatures) == 0 && len(resolved.indexInfos) == 0 && len(resolved.properties) > 0 && core.Every(resolved.properties, func(p *ast.Symbol) bool { + return len(resolved.getSignatures()) == 0 && len(resolved.getIndexInfos()) == 0 && len(resolved.properties) > 0 && core.Every(resolved.properties, func(p *ast.Symbol) bool { return p.Flags()&ast.SymbolFlagsOptional != 0 }) } @@ -1515,7 +1536,7 @@ func (c *Checker) compareSignaturesRelated(source *Signature, target *Signature, } return TernaryFalse } - if len(source.typeParameters) != 0 && !core.Same(source.typeParameters, target.typeParameters) { + if len(source.TypeParameters()) != 0 && !core.Same(source.TypeParameters(), target.TypeParameters()) { target = c.getCanonicalSignature(target) source = c.instantiateSignatureInContextOf(source, target /*inferenceContext*/, nil, compareTypes) } @@ -1706,7 +1727,7 @@ func (c *Checker) compareTypePredicateRelatedTo(source *TypePredicate, target *T // Returns true if `s` is `(...args: A) => R` where `A` is `any`, `any[]`, `never`, or `never[]`, and `R` is `any` or `unknown`. func (c *Checker) isTopSignature(s *Signature) bool { - if len(s.typeParameters) == 0 && (s.thisParameter == nil || IsTypeAny(c.getTypeOfParameter(s.thisParameter))) && len(s.parameters) == 1 && signatureHasRestParameter(s) { + if len(s.TypeParameters()) == 0 && (s.ThisParameter() == nil || IsTypeAny(c.getTypeOfParameter(s.ThisParameter()))) && len(s.parameters) == 1 && signatureHasRestParameter(s) { paramType := c.getTypeOfParameter(s.parameters[0]) var restType *Type if c.isArrayType(paramType) { @@ -1945,8 +1966,8 @@ func (c *Checker) getRestArrayTypeOfTupleType(t *Type) *Type { } func (c *Checker) getThisTypeOfSignature(signature *Signature) *Type { - if signature.thisParameter != nil { - return c.getTypeOfSymbol(signature.thisParameter) + if signature.ThisParameter() != nil { + return c.getTypeOfSymbol(signature.ThisParameter()) } return nil } @@ -2047,37 +2068,38 @@ func (c *Checker) getTupleElementLabelFromBindingElement(node *ast.Node, index i } func (c *Checker) getTypePredicateOfSignature(sig *Signature) *TypePredicate { - if sig.resolvedTypePredicate == nil { + if sig.getResolvedTypePredicate(c) == nil { switch { case sig.target != nil: targetTypePredicate := c.getTypePredicateOfSignature(sig.target) if targetTypePredicate != nil { - sig.resolvedTypePredicate = c.instantiateTypePredicate(targetTypePredicate, sig.mapper) + sig.setResolvedTypePredicate(c, c.instantiateTypePredicate(targetTypePredicate, sig.mapper)) } - case sig.composite != nil: - sig.resolvedTypePredicate = c.getUnionOrIntersectionTypePredicate(sig.composite.signatures, sig.composite.isUnion) + case sig.getComposite() != nil: + sig.setResolvedTypePredicate(c, c.getUnionOrIntersectionTypePredicate(sig.getComposite().signatures, sig.getComposite().isUnion)) default: if sig.declaration != nil { typeNode := sig.declaration.Type() switch { case typeNode != nil: if ast.IsTypePredicateNode(typeNode) { - sig.resolvedTypePredicate = c.createTypePredicateFromTypePredicateNode(typeNode, sig) + sig.setResolvedTypePredicate(c, c.createTypePredicateFromTypePredicateNode(typeNode, sig)) } case ast.IsFunctionLikeDeclaration(sig.declaration) && (sig.resolvedReturnType == nil || sig.resolvedReturnType.flags&TypeFlagsBoolean != 0) && c.getParameterCount(sig) > 0: - sig.resolvedTypePredicate = c.noTypePredicate // avoid infinite loop - sig.resolvedTypePredicate = c.getTypePredicateFromBody(sig.declaration) + sig.setResolvedTypePredicate(c, c.noTypePredicate) // avoid infinite loop + sig.setResolvedTypePredicate(c, c.getTypePredicateFromBody(sig.declaration)) } } } - if sig.resolvedTypePredicate == nil { - sig.resolvedTypePredicate = c.noTypePredicate + if sig.getResolvedTypePredicate(c) == nil { + sig.setResolvedTypePredicate(c, c.noTypePredicate) } } - if sig.resolvedTypePredicate == c.noTypePredicate { + predicate := sig.getResolvedTypePredicate(c) + if predicate == c.noTypePredicate { return nil } - return sig.resolvedTypePredicate + return predicate } func (c *Checker) getUnionOrIntersectionTypePredicate(signatures []*Signature, isUnion bool) *TypePredicate { @@ -2143,14 +2165,14 @@ func (c *Checker) newTypePredicate(kind TypePredicateKind, parameterName string, } func (c *Checker) isResolvingReturnTypeOfSignature(signature *Signature) bool { - if signature.composite != nil && core.Some(signature.composite.signatures, c.isResolvingReturnTypeOfSignature) { + if signature.getComposite() != nil && core.Some(signature.getComposite().signatures, c.isResolvingReturnTypeOfSignature) { return true } return signature.resolvedReturnType == nil && c.findResolutionCycleStartIndex(signature, TypeSystemPropertyNameResolvedReturnType) >= 0 } func (c *Checker) findMatchingSignatures(signatureLists [][]*Signature, signature *Signature, listIndex int) []*Signature { - if len(signature.typeParameters) != 0 { + if len(signature.TypeParameters()) != 0 { // We require an exact match for generic signatures, so we only return signatures from the first // signature list and only if they have exact matches in the other signature lists. if listIndex > 0 { @@ -2205,16 +2227,16 @@ func (c *Checker) compareSignaturesIdentical(source *Signature, target *Signatur return TernaryFalse } // Check that the two signatures have the same number of type parameters. - if len(source.typeParameters) != len(target.typeParameters) { + if len(source.TypeParameters()) != len(target.TypeParameters()) { return TernaryFalse } // Check that type parameter constraints and defaults match. If they do, instantiate the source // signature with the type parameters of the target signature and continue the comparison. - if len(target.typeParameters) != 0 { - mapper := newTypeMapper(source.typeParameters, target.typeParameters) - for i := range len(target.typeParameters) { - s := source.typeParameters[i] - t := target.typeParameters[i] + if len(target.TypeParameters()) != 0 { + mapper := newTypeMapper(source.TypeParameters(), target.TypeParameters()) + for i := range len(target.TypeParameters()) { + s := source.TypeParameters()[i] + t := target.TypeParameters()[i] if !(s == t || compareTypes(c.instantiateType(c.getConstraintOrUnknownFromTypeParameter(s), mapper), c.getConstraintOrUnknownFromTypeParameter(t)) != TernaryFalse && compareTypes(c.instantiateType(c.getDefaultOrUnknownFromTypeParameter(s), mapper), c.getDefaultOrUnknownFromTypeParameter(t)) != TernaryFalse) { return TernaryFalse @@ -2583,8 +2605,8 @@ type Relater struct { errorNode *ast.Node errorChain *ErrorChain relatedInfo []*ast.Diagnostic - maybeKeys []CacheHashKey - maybeKeysSet collections.Set[CacheHashKey] + maybeKeys []relationKey + maybeKeysSet collections.Set[relationKey] sourceStack []*Type targetStack []*Type maybeCount int diff --git a/tsc/internal/checker/services.go b/tsc/internal/checker/services.go index cdcb404ba271d..4926d142bbde5 100644 --- a/tsc/internal/checker/services.go +++ b/tsc/internal/checker/services.go @@ -154,10 +154,17 @@ func (c *Checker) ForEachExportAndPropertyOfModule(moduleSymbol *ast.Symbol, cb if reducedType.flags&TypeFlagsStructuredType == 0 { return } - for name, symbol := range c.resolveStructuredTypeMembers(reducedType).members { - if c.isNamedMember(symbol, name) { - cb(symbol, name) + resolved := c.resolveStructuredTypeMembers(reducedType) + if resolved.members != nil && resolved.members.fallback != nil { + for name, symbol := range resolved.members.fallback { + if c.isNamedMember(symbol, name) { + cb(symbol, name) + } } + return + } + for _, symbol := range resolved.properties { + cb(symbol, symbol.Name()) } } @@ -413,7 +420,7 @@ func (c *Checker) GetRootSymbols(symbol *ast.Symbol) []*ast.Symbol { func (c *Checker) GetMappedTypeSymbolOfProperty(symbol *ast.Symbol) *ast.Symbol { if valueLinks := c.valueSymbolLinks.TryGet(symbol); valueLinks != nil { - return valueLinks.containingType.symbol + return valueLinks.getContainingType().symbol } return nil } @@ -421,7 +428,7 @@ func (c *Checker) GetMappedTypeSymbolOfProperty(symbol *ast.Symbol) *ast.Symbol func (c *Checker) getImmediateRootSymbols(symbol *ast.Symbol) []*ast.Symbol { if symbol.CheckFlags()&ast.CheckFlagsSynthetic != 0 { return core.MapNonNil( - c.valueSymbolLinks.Get(symbol).containingType.Types(), + c.valueSymbolLinks.Get(symbol).getContainingType().Types(), func(t *Type) *ast.Symbol { return c.getPropertyOfType(t, symbol.Name()) }, @@ -726,10 +733,10 @@ func (c *Checker) getUninstantiatedSignatures(node *ast.Node) []*Signature { func (c *Checker) getTypeParameterConstraintForPositionAcrossSignatures(signatures []*Signature, position int) *Type { var relevantConstraints []*Type for _, signature := range signatures { - if position >= len(signature.typeParameters) { + if position >= len(signature.TypeParameters()) { continue } - relevantTypeParameter := signature.typeParameters[position] + relevantTypeParameter := signature.TypeParameters()[position] relevantConstraint := c.getConstraintOfTypeParameter(relevantTypeParameter) if relevantConstraint != nil { relevantConstraints = append(relevantConstraints, relevantConstraint) diff --git a/tsc/internal/checker/tracer.go b/tsc/internal/checker/tracer.go index 0fd4db6937244..0fea57f8d4d70 100644 --- a/tsc/internal/checker/tracer.go +++ b/tsc/internal/checker/tracer.go @@ -112,11 +112,10 @@ func (a *tracedTypeAdapter) IntrinsicName() string { if a.t.flags&TypeFlagsIntrinsic == 0 { return "" } - data, ok := a.t.data.(*IntrinsicType) - if !ok { + if a.t.kind != typeKindIntrinsic { return "" } - return data.intrinsicName + return a.t.AsIntrinsicType().intrinsicName } func (a *tracedTypeAdapter) UnionTypes() []tracing.TracedType { diff --git a/tsc/internal/checker/types.go b/tsc/internal/checker/types.go index 7e4748930262c..eb1b03bfb32b4 100644 --- a/tsc/internal/checker/types.go +++ b/tsc/internal/checker/types.go @@ -4,11 +4,13 @@ import ( "math/bits" "slices" "strings" + "unsafe" "github.com/microsoft/TypeScript/tsc/internal/ast" "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/evaluator" + "github.com/zeebo/xxh3" ) //go:generate npx hereby generate:checker @@ -180,14 +182,69 @@ type SymbolReferenceLinks struct { // Links for value symbols type ValueSymbolLinks struct { - resolvedType *Type // Type of value symbol + resolvedType *Type // Type of value symbol + target *ast.Symbol + mapper *TypeMapper + extra *valueSymbolExtra +} + +type valueSymbolExtra struct { writeType *Type - target *ast.Symbol - mapper *TypeMapper nameType *Type containingType *Type // Mapped type for mapped type property, containing union or intersection type for synthetic property } +func (links *ValueSymbolLinks) getWriteType() *Type { + if links.extra == nil { + return nil + } + return links.extra.writeType +} + +func (links *ValueSymbolLinks) getNameType() *Type { + if links.extra == nil { + return nil + } + return links.extra.nameType +} + +func (links *ValueSymbolLinks) getContainingType() *Type { + if links.extra == nil { + return nil + } + return links.extra.containingType +} + +func (links *ValueSymbolLinks) setWriteType(c *Checker, typ *Type) { + if links.extra == nil { + if typ == nil { + return + } + links.extra = c.valueSymbolExtraArena.New() + } + links.extra.writeType = typ +} + +func (links *ValueSymbolLinks) setNameType(c *Checker, typ *Type) { + if links.extra == nil { + if typ == nil { + return + } + links.extra = c.valueSymbolExtraArena.New() + } + links.extra.nameType = typ +} + +func (links *ValueSymbolLinks) setContainingType(c *Checker, typ *Type) { + if links.extra == nil { + if typ == nil { + return + } + links.extra = c.valueSymbolExtraArena.New() + } + links.extra.containingType = typ +} + // Additional links for mapped symbols type MappedSymbolLinks struct { @@ -382,8 +439,26 @@ type SymbolNodeLinks struct { } type TypeNodeLinks struct { - resolvedType *Type // Resolved type associated with node - outerTypeParameters []*Type // Outer type parameters of anonymous object type + resolvedType *Type // Resolved type associated with node + outerTypeParameters *[]*Type // Outer type parameters of anonymous object type +} + +func (links *TypeNodeLinks) getOuterTypeParameters() []*Type { + if links.outerTypeParameters == nil { + return nil + } + return *links.outerTypeParameters +} + +func (links *TypeNodeLinks) setOuterTypeParameters(c *Checker, types []*Type) { + if types == nil { + links.outerTypeParameters = nil + return + } + if links.outerTypeParameters == nil { + links.outerTypeParameters = c.outerTypeParameterListArena.New() + } + *links.outerTypeParameters = types } type ComputedNameNodeLinks struct { @@ -681,14 +756,73 @@ func (a *TypeAlias) TypeArguments() []*Type { // Type +// The concrete kind is separate from mutable semantic flags. All concrete types +// embed Type at offset zero, so a tag replaces the self-referential interface. +// The ordering groups types by their embedded bases for the base casts below. +type typeKind uint8 + +const ( + typeKindIntrinsic typeKind = iota + 1 + typeKindLiteral + typeKindUniqueESSymbol + typeKindTypeParameter + typeKindIndex + typeKindIndexedAccess + typeKindTemplateLiteral + typeKindStringMapping + typeKindSubstitution + typeKindConditional + typeKindObject + typeKindTypeReference + typeKindInterface + typeKindTuple + typeKindInstantiationExpression + typeKindMapped + typeKindReverseMapped + typeKindEvolvingArray + typeKindUnion + typeKindIntersection +) + type Type struct { flags TypeFlags objectFlags ObjectFlags id TypeId + kind typeKind symbol *ast.Symbol alias *TypeAlias checker *Checker - data TypeData // Type specific data +} + +// Enforce the layout required by the pointer conversions, on every architecture. +var ( + _ [0 - unsafe.Offsetof(IntrinsicType{}.Type)]byte + _ [0 - unsafe.Offsetof(LiteralType{}.Type)]byte + _ [0 - unsafe.Offsetof(UniqueESSymbolType{}.Type)]byte + _ [0 - unsafe.Offsetof(TypeParameter{}.Type)]byte + _ [0 - unsafe.Offsetof(IndexType{}.Type)]byte + _ [0 - unsafe.Offsetof(IndexedAccessType{}.Type)]byte + _ [0 - unsafe.Offsetof(TemplateLiteralType{}.Type)]byte + _ [0 - unsafe.Offsetof(StringMappingType{}.Type)]byte + _ [0 - unsafe.Offsetof(SubstitutionType{}.Type)]byte + _ [0 - unsafe.Offsetof(ConditionalType{}.Type)]byte + _ [0 - unsafe.Offsetof(ObjectType{}.Type)]byte + _ [0 - unsafe.Offsetof(TypeReference{}.Type)]byte + _ [0 - unsafe.Offsetof(InterfaceType{}.Type)]byte + _ [0 - unsafe.Offsetof(TupleType{}.Type)]byte + _ [0 - unsafe.Offsetof(InstantiationExpressionType{}.Type)]byte + _ [0 - unsafe.Offsetof(MappedType{}.Type)]byte + _ [0 - unsafe.Offsetof(ReverseMappedType{}.Type)]byte + _ [0 - unsafe.Offsetof(EvolvingArrayType{}.Type)]byte + _ [0 - unsafe.Offsetof(UnionType{}.Type)]byte + _ [0 - unsafe.Offsetof(IntersectionType{}.Type)]byte +) + +func castType[T any](t *Type, kind typeKind) *T { + if t.kind != kind { + panic("Invalid type cast") + } + return (*T)(unsafe.Pointer(t)) } func (t *Type) Id() TypeId { @@ -705,35 +839,94 @@ func (t *Type) ObjectFlags() ObjectFlags { // Casts for concrete struct types -func (t *Type) AsIntrinsicType() *IntrinsicType { return t.data.(*IntrinsicType) } -func (t *Type) AsLiteralType() *LiteralType { return t.data.(*LiteralType) } -func (t *Type) AsUniqueESSymbolType() *UniqueESSymbolType { return t.data.(*UniqueESSymbolType) } -func (t *Type) AsTupleType() *TupleType { return t.data.(*TupleType) } +func (t *Type) AsIntrinsicType() *IntrinsicType { return castType[IntrinsicType](t, typeKindIntrinsic) } +func (t *Type) AsLiteralType() *LiteralType { return castType[LiteralType](t, typeKindLiteral) } +func (t *Type) AsUniqueESSymbolType() *UniqueESSymbolType { + return castType[UniqueESSymbolType](t, typeKindUniqueESSymbol) +} +func (t *Type) AsTupleType() *TupleType { return castType[TupleType](t, typeKindTuple) } func (t *Type) AsInstantiationExpressionType() *InstantiationExpressionType { - return t.data.(*InstantiationExpressionType) -} -func (t *Type) AsMappedType() *MappedType { return t.data.(*MappedType) } -func (t *Type) AsReverseMappedType() *ReverseMappedType { return t.data.(*ReverseMappedType) } -func (t *Type) AsEvolvingArrayType() *EvolvingArrayType { return t.data.(*EvolvingArrayType) } -func (t *Type) AsTypeParameter() *TypeParameter { return t.data.(*TypeParameter) } -func (t *Type) AsUnionType() *UnionType { return t.data.(*UnionType) } -func (t *Type) AsIntersectionType() *IntersectionType { return t.data.(*IntersectionType) } -func (t *Type) AsIndexType() *IndexType { return t.data.(*IndexType) } -func (t *Type) AsIndexedAccessType() *IndexedAccessType { return t.data.(*IndexedAccessType) } -func (t *Type) AsTemplateLiteralType() *TemplateLiteralType { return t.data.(*TemplateLiteralType) } -func (t *Type) AsStringMappingType() *StringMappingType { return t.data.(*StringMappingType) } -func (t *Type) AsSubstitutionType() *SubstitutionType { return t.data.(*SubstitutionType) } -func (t *Type) AsConditionalType() *ConditionalType { return t.data.(*ConditionalType) } + return castType[InstantiationExpressionType](t, typeKindInstantiationExpression) +} +func (t *Type) AsMappedType() *MappedType { return castType[MappedType](t, typeKindMapped) } +func (t *Type) AsReverseMappedType() *ReverseMappedType { + return castType[ReverseMappedType](t, typeKindReverseMapped) +} + +func (t *Type) AsEvolvingArrayType() *EvolvingArrayType { + return castType[EvolvingArrayType](t, typeKindEvolvingArray) +} + +func (t *Type) AsTypeParameter() *TypeParameter { + return castType[TypeParameter](t, typeKindTypeParameter) +} +func (t *Type) AsUnionType() *UnionType { return castType[UnionType](t, typeKindUnion) } +func (t *Type) AsIntersectionType() *IntersectionType { + return castType[IntersectionType](t, typeKindIntersection) +} +func (t *Type) AsIndexType() *IndexType { return castType[IndexType](t, typeKindIndex) } +func (t *Type) AsIndexedAccessType() *IndexedAccessType { + return castType[IndexedAccessType](t, typeKindIndexedAccess) +} + +func (t *Type) AsTemplateLiteralType() *TemplateLiteralType { + return castType[TemplateLiteralType](t, typeKindTemplateLiteral) +} + +func (t *Type) AsStringMappingType() *StringMappingType { + return castType[StringMappingType](t, typeKindStringMapping) +} + +func (t *Type) AsSubstitutionType() *SubstitutionType { + return castType[SubstitutionType](t, typeKindSubstitution) +} + +func (t *Type) AsConditionalType() *ConditionalType { + return castType[ConditionalType](t, typeKindConditional) +} // Casts for embedded struct types -func (t *Type) AsConstrainedType() *ConstrainedType { return t.data.AsConstrainedType() } -func (t *Type) AsStructuredType() *StructuredType { return t.data.AsStructuredType() } -func (t *Type) AsObjectType() *ObjectType { return t.data.AsObjectType() } -func (t *Type) AsTypeReference() *TypeReference { return t.data.AsTypeReference() } -func (t *Type) AsInterfaceType() *InterfaceType { return t.data.AsInterfaceType() } +func (t *Type) AsConstrainedType() *ConstrainedType { + if t.kind >= typeKindTypeParameter && t.kind <= typeKindIntersection { + return (*ConstrainedType)(unsafe.Pointer(t)) + } + return nil +} + +func (t *Type) AsStructuredType() *StructuredType { + if t.kind >= typeKindObject && t.kind <= typeKindIntersection { + return (*StructuredType)(unsafe.Pointer(t)) + } + return nil +} + +func (t *Type) AsObjectType() *ObjectType { + if t.kind >= typeKindObject && t.kind <= typeKindEvolvingArray { + return (*ObjectType)(unsafe.Pointer(t)) + } + return nil +} + +func (t *Type) AsTypeReference() *TypeReference { + if t.kind >= typeKindTypeReference && t.kind <= typeKindTuple { + return (*TypeReference)(unsafe.Pointer(t)) + } + return nil +} + +func (t *Type) AsInterfaceType() *InterfaceType { + if t.kind >= typeKindInterface && t.kind <= typeKindTuple { + return (*InterfaceType)(unsafe.Pointer(t)) + } + return nil +} + func (t *Type) AsUnionOrIntersectionType() *UnionOrIntersectionType { - return t.data.AsUnionOrIntersectionType() + if t.kind >= typeKindUnion && t.kind <= typeKindIntersection { + return (*UnionOrIntersectionType)(unsafe.Pointer(t)) + } + return nil } func (t *Type) Distributed() []*Type { @@ -854,18 +1047,6 @@ func (t *Type) IsTupleType() bool { return isTupleType(t) } -// TypeData - -type TypeData interface { - AsType() *Type - AsConstrainedType() *ConstrainedType - AsStructuredType() *StructuredType - AsObjectType() *ObjectType - AsTypeReference() *TypeReference - AsInterfaceType() *InterfaceType - AsUnionOrIntersectionType() *UnionOrIntersectionType -} - // TypeBase type TypeBase struct { @@ -934,8 +1115,12 @@ func (t *ConstrainedType) AsConstrainedType() *ConstrainedType { return t } type StructuredType struct { ConstrainedType - members ast.SymbolTable - properties []*ast.Symbol + members *memberIndex + properties []*ast.Symbol + extra *structuredTypeExtra +} + +type structuredTypeExtra struct { signatures []*Signature // Signatures (call + construct) callSignatureCount int // Count of call signatures indexInfos []*IndexInfo @@ -946,17 +1131,145 @@ type StructuredType struct { func (t *StructuredType) AsStructuredType() *StructuredType { return t } func (t *StructuredType) CallSignatures() []*Signature { - return slices.Clip(t.signatures[:t.callSignatureCount]) + if t.extra == nil { + return nil + } + return slices.Clip(t.extra.signatures[:t.extra.callSignatureCount]) } func (t *StructuredType) ConstructSignatures() []*Signature { - return slices.Clip(t.signatures[t.callSignatureCount:]) + if t.extra == nil { + return nil + } + return slices.Clip(t.extra.signatures[t.extra.callSignatureCount:]) +} + +func (t *StructuredType) getSignatures() []*Signature { + if t.extra == nil { + return nil + } + return t.extra.signatures +} + +func (t *StructuredType) getIndexInfos() []*IndexInfo { + if t.extra == nil { + return nil + } + return t.extra.indexInfos +} + +func (t *StructuredType) ensureExtra(c *Checker) *structuredTypeExtra { + if t.extra == nil { + t.extra = c.structuredTypeExtraArena.New() + } + return t.extra } func (t *StructuredType) Properties() []*ast.Symbol { return t.properties } +type memberIndex struct { + slots []uint32 + fallback ast.SymbolTable +} + +// Property order is semantic. Keep it unchanged and index it with pointer-free +// slots instead of retaining a second map of names and symbol pointers. +func (c *Checker) newMemberIndex(members ast.SymbolTable, properties []*ast.Symbol, index *memberIndex) *memberIndex { + if len(members) != len(properties) || !symbolTableKeysMatchNames(members) { + if index == nil { + index = c.memberIndexArena.New() + } + index.fallback = members + return index + } + if index != nil { + index.fallback = nil + } + return c.newPropertyIndex(properties, index) +} + +// Reports whether every symbol is stored under its own name. Checking the +// table's pairs, rather than looking each property up by name, also rejects a +// symbol aliased under a second key, which a name-keyed index would drop. +func symbolTableKeysMatchNames(members ast.SymbolTable) bool { + for name, symbol := range members { + if symbol.Name() != name { + return false + } + } + return true +} + +func (c *Checker) newPropertyIndex(properties []*ast.Symbol, index *memberIndex) *memberIndex { + if len(properties) <= 8 { + return nil + } + if uint64(len(properties)) > uint64(^uint32(0)) { + panic("Member index exhausted") + } + if index == nil { + index = c.memberIndexArena.New() + } + size := 1 << bits.Len(uint(len(properties))*2-1) + index.slots = c.memberIndexSlotsArena.NewSlice(size) + mask := uint64(size - 1) + for i, symbol := range properties { + slot := xxh3.HashString(symbol.Name()) & mask + for index.slots[slot] != 0 { + slot = (slot + 1) & mask + } + index.slots[slot] = uint32(i + 1) + } + return index +} + +func (t *StructuredType) getMember(name string) *ast.Symbol { + if t.members == nil { + for _, symbol := range t.properties { + if symbol.Name() == name { + return symbol + } + } + return nil + } + if t.members.fallback != nil { + return t.members.fallback[name] + } + slots := t.members.slots + if len(slots) == 0 { + return nil + } + mask := uint64(len(slots) - 1) + slot := xxh3.HashString(name) & mask + for { + index := slots[slot] + if index == 0 { + return nil + } + symbol := t.properties[index-1] + if symbol.Name() == name { + return symbol + } + slot = (slot + 1) & mask + } +} + +func (t *StructuredType) getMembers() ast.SymbolTable { + if t.members != nil && t.members.fallback != nil { + return t.members.fallback + } + if len(t.properties) == 0 { + return nil + } + members := make(ast.SymbolTable, len(t.properties)) + for _, symbol := range t.properties { + members[symbol.Name()] = symbol + } + return members +} + // Except for tuple type references and reverse mapped types, all object types have an associated symbol. // Possible object type instances are listed in the following. @@ -1151,7 +1464,7 @@ type EvolvingArrayType struct { type UnionOrIntersectionType struct { StructuredType types []*Type - propertyCache ast.SymbolTable + propertyCache ast.SymbolTable // Augmented entries not shared with the non-augmented cache. propertyCacheWithoutFunctionPropertyAugment ast.SymbolTable resolvedProperties []*ast.Symbol } @@ -1299,6 +1612,7 @@ const ( SignatureFlagsIsUntypedSignatureInJSFile SignatureFlags = 1 << 6 // Indicates signature is from a js file and has no types SignatureFlagsIsNonInferrable SignatureFlags = 1 << 7 // Indicates signature comes from a non-inferrable type SignatureFlagsIsSignatureCandidateForOverloadFailure SignatureFlags = 1 << 8 + signatureFlagsNoTypePredicate SignatureFlags = 1 << 9 // We do not propagate `IsInnerCallChain` or `IsOuterCallChain` to instantiated signatures, as that would result in us // attempting to add `| undefined` on each recursive call to `getReturnTypeOfSignature` when // instantiating the return type. @@ -1314,15 +1628,79 @@ type Signature struct { minArgumentCount int32 resolvedMinArgumentCount int32 declaration *ast.Node - typeParameters []*Type parameters []*ast.Symbol - thisParameter *ast.Symbol resolvedReturnType *Type - resolvedTypePredicate *TypePredicate target *Signature mapper *TypeMapper - isolatedSignatureType *Type - composite *CompositeSignature + extra *signatureExtra +} + +type signatureExtra struct { + typeParameters []*Type + thisParameter *ast.Symbol + resolvedTypePredicate *TypePredicate + isolatedSignatureType *Type + composite *CompositeSignature +} + +func (s *Signature) ensureExtra(c *Checker) *signatureExtra { + if s.extra == nil { + s.extra = c.signatureExtraArena.New() + } + return s.extra +} + +func (s *Signature) setTypeParameters(c *Checker, types []*Type) { + if types != nil || s.extra != nil { + s.ensureExtra(c).typeParameters = types + } +} + +func (s *Signature) setThisParameter(c *Checker, parameter *ast.Symbol) { + if parameter != nil || s.extra != nil { + s.ensureExtra(c).thisParameter = parameter + } +} + +func (s *Signature) getResolvedTypePredicate(c *Checker) *TypePredicate { + if s.flags&signatureFlagsNoTypePredicate != 0 { + return c.noTypePredicate + } + if s.extra == nil { + return nil + } + return s.extra.resolvedTypePredicate +} + +func (s *Signature) setResolvedTypePredicate(c *Checker, predicate *TypePredicate) { + s.flags &^= signatureFlagsNoTypePredicate + if predicate != nil && predicate == c.noTypePredicate { + s.flags |= signatureFlagsNoTypePredicate + predicate = nil + } + if predicate != nil || s.extra != nil { + s.ensureExtra(c).resolvedTypePredicate = predicate + } +} + +func (s *Signature) getComposite() *CompositeSignature { + if s.extra == nil { + return nil + } + return s.extra.composite +} + +func (s *Signature) setComposite(c *Checker, composite *CompositeSignature) { + if composite != nil || s.extra != nil { + s.ensureExtra(c).composite = composite + } +} + +func (s *Signature) getIsolatedSignatureType() *Type { + if s.extra == nil { + return nil + } + return s.extra.isolatedSignatureType } func (s *Signature) Id() SignatureId { @@ -1330,11 +1708,14 @@ func (s *Signature) Id() SignatureId { } func (s *Signature) Flags() SignatureFlags { - return s.flags + return s.flags &^ signatureFlagsNoTypePredicate } func (s *Signature) TypeParameters() []*Type { - return s.typeParameters + if s.extra == nil { + return nil + } + return s.extra.typeParameters } func (s *Signature) Declaration() *ast.Node { @@ -1346,7 +1727,10 @@ func (s *Signature) Target() *Signature { } func (s *Signature) ThisParameter() *ast.Symbol { - return s.thisParameter + if s.extra == nil { + return nil + } + return s.extra.thisParameter } func (s *Signature) Parameters() []*ast.Symbol { diff --git a/tsc/internal/checker/types_test.go b/tsc/internal/checker/types_test.go new file mode 100644 index 0000000000000..e00fc2bc45907 --- /dev/null +++ b/tsc/internal/checker/types_test.go @@ -0,0 +1,897 @@ +package checker + +import ( + "encoding/binary" + "runtime" + "slices" + "strconv" + "strings" + "testing" + "unsafe" + + "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/testutil/race" + "github.com/zeebo/xxh3" + "gotest.tools/v3/assert" +) + +func TestCheckerNodeLinkStores(t *testing.T) { + t.Parallel() + f := ast.NewNodeFactory(ast.NodeFactoryHooks{}) + first := &Checker{} + second := &Checker{} + nodes := make([]*ast.Node, 4096) + for i := range nodes { + node := f.NewIdentifier(strconv.Itoa(i)) + if i%2 == 0 { + ast.GetNodeId(node) + } + nodes[i] = node + assert.Assert(t, !first.typeNodeLinks.Has(node)) + assert.Assert(t, !first.signatureLinks.Has(node)) + first.typeNodeLinks.Get(node).resolvedType = &Type{id: TypeId(i + 1)} + first.signatureLinks.Get(node).resolvedSignature = &Signature{id: SignatureId(i + 1)} + second.typeNodeLinks.Get(node).resolvedType = &Type{id: TypeId(i + 2)} + second.signatureLinks.Get(node).resolvedSignature = &Signature{id: SignatureId(i + 2)} + } + f.ReleaseArenas() + runtime.GC() + for i, node := range nodes { + assert.Equal(t, first.typeNodeLinks.Get(node).resolvedType.id, TypeId(i+1)) + assert.Equal(t, first.signatureLinks.Get(node).resolvedSignature.id, SignatureId(i+1)) + assert.Equal(t, second.typeNodeLinks.Get(node).resolvedType.id, TypeId(i+2)) + assert.Equal(t, second.signatureLinks.Get(node).resolvedSignature.id, SignatureId(i+2)) + } + clone := nodes[0].Clone(f) + assert.Assert(t, !first.typeNodeLinks.Has(clone)) + assert.Assert(t, !first.signatureLinks.Has(clone)) +} + +func TestTypeCasts(t *testing.T) { + t.Parallel() + type bases interface { + AsType() *Type + AsConstrainedType() *ConstrainedType + AsStructuredType() *StructuredType + AsObjectType() *ObjectType + AsTypeReference() *TypeReference + AsInterfaceType() *InterfaceType + AsUnionOrIntersectionType() *UnionOrIntersectionType + } + tests := []struct { + kind typeKind + data bases + cast func(*Type) any + }{ + {typeKindIntrinsic, &IntrinsicType{}, func(t *Type) any { return t.AsIntrinsicType() }}, + {typeKindLiteral, &LiteralType{}, func(t *Type) any { return t.AsLiteralType() }}, + {typeKindUniqueESSymbol, &UniqueESSymbolType{}, func(t *Type) any { return t.AsUniqueESSymbolType() }}, + {typeKindTypeParameter, &TypeParameter{}, func(t *Type) any { return t.AsTypeParameter() }}, + {typeKindIndex, &IndexType{}, func(t *Type) any { return t.AsIndexType() }}, + {typeKindIndexedAccess, &IndexedAccessType{}, func(t *Type) any { return t.AsIndexedAccessType() }}, + {typeKindTemplateLiteral, &TemplateLiteralType{}, func(t *Type) any { return t.AsTemplateLiteralType() }}, + {typeKindStringMapping, &StringMappingType{}, func(t *Type) any { return t.AsStringMappingType() }}, + {typeKindSubstitution, &SubstitutionType{}, func(t *Type) any { return t.AsSubstitutionType() }}, + {typeKindConditional, &ConditionalType{}, func(t *Type) any { return t.AsConditionalType() }}, + {typeKindObject, &ObjectType{}, func(t *Type) any { return t.AsObjectType() }}, + {typeKindTypeReference, &TypeReference{}, func(t *Type) any { return t.AsTypeReference() }}, + {typeKindInterface, &InterfaceType{}, func(t *Type) any { return t.AsInterfaceType() }}, + {typeKindTuple, &TupleType{}, func(t *Type) any { return t.AsTupleType() }}, + {typeKindInstantiationExpression, &InstantiationExpressionType{}, func(t *Type) any { return t.AsInstantiationExpressionType() }}, + {typeKindMapped, &MappedType{}, func(t *Type) any { return t.AsMappedType() }}, + {typeKindReverseMapped, &ReverseMappedType{}, func(t *Type) any { return t.AsReverseMappedType() }}, + {typeKindEvolvingArray, &EvolvingArrayType{}, func(t *Type) any { return t.AsEvolvingArrayType() }}, + {typeKindUnion, &UnionType{}, func(t *Type) any { return t.AsUnionType() }}, + {typeKindIntersection, &IntersectionType{}, func(t *Type) any { return t.AsIntersectionType() }}, + } + for _, test := range tests { + c := &Checker{} + typ := c.newType(TypeFlagsAny, ObjectFlagsNone, test.data.AsType(), test.kind) + runtime.GC() + assert.Equal(t, test.cast(typ), any(test.data)) + assert.Equal(t, typ.AsConstrainedType(), test.data.AsConstrainedType()) + assert.Equal(t, typ.AsStructuredType(), test.data.AsStructuredType()) + assert.Equal(t, typ.AsObjectType(), test.data.AsObjectType()) + assert.Equal(t, typ.AsTypeReference(), test.data.AsTypeReference()) + assert.Equal(t, typ.AsInterfaceType(), test.data.AsInterfaceType()) + assert.Equal(t, typ.AsUnionOrIntersectionType(), test.data.AsUnionOrIntersectionType()) + typ.flags = TypeFlagsNever + typ.objectFlags = ObjectFlagsReference + assert.Equal(t, test.cast(typ), any(test.data)) + for _, target := range tests { + switch target.kind { + case typeKindObject: + assert.Equal(t, target.cast(typ), any(test.data.AsObjectType())) + case typeKindTypeReference: + assert.Equal(t, target.cast(typ), any(test.data.AsTypeReference())) + case typeKindInterface: + assert.Equal(t, target.cast(typ), any(test.data.AsInterfaceType())) + default: + assert.Assert(t, didPanic(func() { target.cast(typ) }) == (test.kind != target.kind)) + } + } + } +} + +func didPanic(f func()) (panicked bool) { + defer func() { panicked = recover() != nil }() + f() + return false +} + +func TestTypeHeaderSize(t *testing.T) { + t.Parallel() + assert.Equal(t, unsafe.Sizeof(Type{}), 16+3*unsafe.Sizeof((*Checker)(nil))) +} + +func TestKeyBuilder(t *testing.T) { + t.Parallel() + for _, count := range []int{0, 1, 46, 47, 256, 4096} { + t.Run(strconv.Itoa(count), func(t *testing.T) { + t.Parallel() + types := make([]*Type, count) + var expected []byte + prefix := strings.Repeat("x", count) + expected = append(expected, prefix...) + expected = append(expected, 17) + expected = binary.LittleEndian.AppendUint32(expected, 123) + expected = binary.LittleEndian.AppendUint64(expected, uint64(count)) + for i := range types { + types[i] = &Type{id: TypeId(i + 1)} + expected = binary.LittleEndian.AppendUint32(expected, uint32(i+1)) + } + expected = append(expected, "suffix"...) + var builder keyBuilder + builder.writeString(prefix) + builder.writeByte(17) + builder.writeUint32(123) + builder.writeTypes(types) + builder.writeString("suffix") + assert.Equal(t, builder.hash(), CacheHashKey(xxh3.Hash128(expected))) + assert.Equal(t, builder.hash(), CacheHashKey(xxh3.Hash128(expected))) + }) + } +} + +func TestRelationKeys(t *testing.T) { + t.Parallel() + source := &Type{id: 1} + target := &Type{id: ^TypeId(0)} + var relation Relation + assert.Equal(t, relation.size(), 0) + for state := IntersectionStateNone; state <= IntersectionStateSource|IntersectionStateTarget; state++ { + key, constrained := getRelationKey(source, target, state, false, false) + assert.Assert(t, !constrained) + assert.Equal(t, relation.get(key), RelationComparisonResultNone) + relation.set(key, RelationComparisonResultSucceeded) + reverse, _ := getRelationKey(target, source, state, false, false) + assert.Assert(t, key != reverse) + assert.Equal(t, relation.get(reverse), RelationComparisonResultNone) + identity, _ := getRelationKey(target, source, state, true, false) + assert.Equal(t, key, identity) + relation.set(key, RelationComparisonResultFailed|RelationComparisonResultReportsUnreliable) + assert.Equal(t, relation.get(key), RelationComparisonResultFailed|RelationComparisonResultReportsUnreliable) + } + assert.Equal(t, relation.size(), 4) + for state := IntersectionStateNone; state <= IntersectionStateSource|IntersectionStateTarget; state++ { + key, _ := getRelationKey(source, target, state, false, false) + assert.Equal(t, relation.get(key), RelationComparisonResultFailed|RelationComparisonResultReportsUnreliable) + } +} + +func TestRelationKeyNamespaces(t *testing.T) { + t.Parallel() + simple, _ := getRelationKey(&Type{id: 1}, &Type{id: 2}, IntersectionStateNone, false, false) + generic := relationKey{value: simple.value, generic: true} + var relation Relation + relation.set(simple, RelationComparisonResultSucceeded) + assert.Equal(t, relation.get(generic), RelationComparisonResultNone) + relation.set(generic, RelationComparisonResultFailed) + assert.Equal(t, relation.get(simple), RelationComparisonResultSucceeded) + assert.Equal(t, relation.get(generic), RelationComparisonResultFailed) + assert.Equal(t, relation.size(), 2) +} + +func TestGenericRelationKeys(t *testing.T) { + t.Parallel() + c, types := newCompositeTestChecker() + c.noConstraintType = c.newIntrinsicType(TypeFlagsNever, "no constraint") + root := types[0] + newParameter := func(constraint *Type) *Type { + parameter := &TypeParameter{constraint: constraint} + return c.newType(TypeFlagsTypeParameter, ObjectFlagsNone, parameter.AsType(), typeKindTypeParameter) + } + newReference := func(argument *Type) *Type { + reference := &TypeReference{resolvedTypeArguments: []*Type{argument}} + reference.target = root + return c.newType(TypeFlagsObject, ObjectFlagsReference, reference.AsType(), typeKindTypeReference) + } + left := newReference(newParameter(c.noConstraintType)) + right := newReference(newParameter(c.noConstraintType)) + equivalentLeft := newReference(newParameter(c.noConstraintType)) + equivalentRight := newReference(newParameter(c.noConstraintType)) + key, constrained := getRelationKey(left, right, IntersectionStateNone, false, false) + assert.Assert(t, !constrained) + equivalent, _ := getRelationKey(equivalentLeft, equivalentRight, IntersectionStateNone, false, false) + assert.Equal(t, key, equivalent) + var relation Relation + relation.set(key, RelationComparisonResultSucceeded) + assert.Equal(t, relation.get(equivalent), RelationComparisonResultSucceeded) + constrainedLeft := newReference(newParameter(types[1])) + constrainedKey, constrained := getRelationKey(constrainedLeft, right, IntersectionStateNone, false, false) + assert.Assert(t, constrained) + assert.Assert(t, constrainedKey != key) + broadest, constrained := getRelationKey(constrainedLeft, right, IntersectionStateNone, false, true) + assert.Assert(t, !constrained) + assert.Equal(t, broadest, key) +} + +func TestTypeListKeyAllocations(t *testing.T) { //nolint:paralleltest + if race.Enabled { + t.Skip("race instrumentation changes hashing allocations") + } + for _, count := range []int{8, 46, 47, 256, 4096} { + types := make([]*Type, count) + for i := range types { + types[i] = &Type{id: TypeId(i + 1)} + } + allocations := testing.AllocsPerRun(10, func() { getTypeListKey(types) }) + expected := float64(0) + if count > 46 { + expected = 1 + } + assert.Equal(t, allocations, expected, "type list length %d", count) + } +} + +func BenchmarkTypeListKey(b *testing.B) { + for _, count := range []int{8, 46, 47, 256, 4096} { + b.Run(strconv.Itoa(count), func(b *testing.B) { + types := make([]*Type, count) + for i := range types { + types[i] = &Type{id: TypeId(i + 1)} + } + b.ReportAllocs() + for b.Loop() { + getTypeListKey(types) + } + }) + } +} + +func newCompositeTestChecker() (*Checker, []*Type) { + c := &Checker{ + strictNullChecks: true, + unionTypes: make(map[CacheHashKey]*Type), + unionOfUnionTypes: make(map[UnionOfUnionKey]*Type), + intersectionTypes: make(map[CacheHashKey]*Type), + subtypeReductionCache: make(map[CacheHashKey][]*Type), + } + c.compareSymbols = c.compareSymbolsWorker + c.neverType = c.newIntrinsicType(TypeFlagsNever, "never") + c.unknownType = c.newIntrinsicType(TypeFlagsUnknown, "unknown") + types := []*Type{ + c.newIntrinsicType(TypeFlagsString, "string"), + c.newIntrinsicType(TypeFlagsNumber, "number"), + c.newIntrinsicType(TypeFlagsESSymbol, "symbol"), + } + return c, types +} + +func TestCompositeTypeOwnsConstituents(t *testing.T) { + t.Parallel() + c, types := newCompositeTestChecker() + borrowed := slices.Clone(types) + union := c.getUnionTypeFromSortedList(borrowed, ObjectFlagsNone, nil, nil) + borrowed[0] = c.neverType + assert.Assert(t, slices.Equal(union.Types(), types)) + objects := []*Type{ + c.newObjectType(ObjectFlagsInterface, nil), + c.newObjectType(ObjectFlagsInterface, nil), + c.newObjectType(ObjectFlagsInterface, nil), + } + intersection := c.getIntersectionType(objects) + objects[0] = c.neverType + assert.Assert(t, intersection.Types()[0] != c.neverType) + reduced := c.removeSubtypes(borrowed, false) + expected := slices.Clone(reduced) + borrowed[0] = types[0] + assert.Assert(t, slices.Equal(reduced, expected)) +} + +func TestCompositeTypeCacheHitAllocations(t *testing.T) { //nolint:paralleltest + if race.Enabled { + t.Skip("race instrumentation changes hashing allocations") + } + c, types := newCompositeTestChecker() + union := c.getUnionType(types) + filtered := c.removeType(union, types[1]) + objects := []*Type{ + c.newObjectType(ObjectFlagsInterface, nil), + c.newObjectType(ObjectFlagsInterface, nil), + c.newObjectType(ObjectFlagsInterface, nil), + } + intersection := c.getIntersectionType(objects) + assert.Equal(t, testing.AllocsPerRun(10, func() { c.getUnionType(types) }), float64(0)) + assert.Equal(t, testing.AllocsPerRun(10, func() { c.getIntersectionType(objects) }), float64(0)) + assert.Equal(t, testing.AllocsPerRun(10, func() { c.mapType(union, func(t *Type) *Type { return t }) }), float64(0)) + assert.Equal(t, testing.AllocsPerRun(10, func() { + c.mapType(union, func(t *Type) *Type { + if t == types[1] { + return nil + } + return t + }) + }), float64(0)) + assert.Equal(t, testing.AllocsPerRun(10, func() { c.removeType(union, types[1]) }), float64(0)) + assert.Equal(t, c.removeType(union, types[1]), filtered) + assert.Equal(t, c.getIntersectionType(objects), intersection) +} + +func TestTemporaryTypeSetReuse(t *testing.T) { + t.Parallel() + c, primitives := newCompositeTestChecker() + for _, count := range []int{3, 17, 80, 300, 5000, 3} { + objects := make([]*Type, count) + for i := range objects { + objects[i] = c.newObjectType(ObjectFlagsInterface, nil) + } + intersection := c.getIntersectionType(objects) + assert.Assert(t, slices.Equal(intersection.Types(), objects)) + union := c.getUnionType(objects) + assert.Assert(t, slices.Equal(union.Types(), objects)) + mapped := c.mapType(union, func(typ *Type) *Type { + c.getIntersectionType(objects[:2]) + if typ == objects[1] { + return nil + } + return typ + }) + expected := slices.Clone(objects) + expected = slices.Delete(expected, 1, 2) + assert.Assert(t, slices.Equal(mapped.Types(), expected)) + assert.Equal(t, c.removeType(union, objects[1]), mapped) + assert.Assert(t, c.mapType(union, func(*Type) *Type { return nil }) == nil) + assert.Equal(t, c.getIntersectionType(objects), intersection) + for set := c.freeTypeSets; set != nil; set = set.next { + assert.Equal(t, len(set.values), 0) + assert.Equal(t, len(set.valuesByKey), 0) + assert.Assert(t, cap(set.values) <= 4096) + for _, typ := range set.values[:cap(set.values)] { + assert.Assert(t, typ == nil) + } + for _, typ := range set.inline { + assert.Assert(t, typ == nil) + } + } + } + left := c.getUnionType(primitives[:2]) + right := c.getUnionType(primitives[1:]) + assert.Equal(t, c.getIntersectionType([]*Type{left, right}), primitives[1]) +} + +func TestIntersectionReductionAllocations(t *testing.T) { //nolint:paralleltest + if race.Enabled { + t.Skip("race instrumentation changes hashing allocations") + } + c, _ := newCompositeTestChecker() + members := make(ast.SymbolTable) + for i := range 128 { + name := strconv.Itoa(i) + members[name] = c.newSymbol(ast.SymbolFlagsProperty, name) + } + object := c.newAnonymousType(nil, members, nil, nil, nil) + intersection := c.newIntersectionType(ObjectFlagsNone, []*Type{object, object}) + assert.Assert(t, !c.somePropertyReducesToNever(intersection)) + assert.Equal(t, testing.AllocsPerRun(10, func() { + assert.Assert(t, !c.somePropertyReducesToNever(intersection)) + }), float64(0)) +} + +func TestTemporaryPropertyCounts(t *testing.T) { + t.Parallel() + c := &Checker{} + outer := c.getTemporaryPropertyCounts() + outer.Set("second", 1) + outer.Set("first", 1) + outer.Set("second", 2) + assert.Assert(t, slices.Equal(slices.Collect(outer.Keys()), []string{"second", "first"})) + inner := c.getTemporaryPropertyCounts() + assert.Assert(t, inner != outer) + inner.Set("first", 4) + assert.Equal(t, outer.GetOrZero("first"), 1) + assert.Equal(t, outer.GetOrZero("second"), 2) + c.releaseTemporaryPropertyCounts(inner) + assert.Equal(t, inner.Size(), 0) + assert.Assert(t, !inner.Has("first")) + reused := c.getTemporaryPropertyCounts() + assert.Equal(t, reused, inner) + reused.Set("second", 3) + reused.Set("first", 5) + assert.Assert(t, slices.Equal(slices.Collect(reused.Keys()), []string{"second", "first"})) + assert.Equal(t, outer.GetOrZero("first"), 1) + c.releaseTemporaryPropertyCounts(reused) + c.releaseTemporaryPropertyCounts(outer) + runtime.GC() + reused = c.getTemporaryPropertyCounts() + assert.Equal(t, reused.Size(), 0) + assert.Assert(t, !reused.Has("second")) + for i := range 4097 { + reused.Set(strconv.Itoa(i), i) + } + c.releaseTemporaryPropertyCounts(reused) + for counts := c.freePropertyCounts; counts != nil; counts = counts.next { + assert.Assert(t, counts != reused) + assert.Equal(t, counts.Size(), 0) + } + assert.Assert(t, c.getTemporaryPropertyCounts() != reused) + other := &Checker{} + assert.Assert(t, other.getTemporaryPropertyCounts() != outer) +} + +func TestIntersectionReductionReentrancy(t *testing.T) { + t.Parallel() + c, _ := newCompositeTestChecker() + property := c.newSymbol(ast.SymbolFlagsProperty, "value") + object := c.newAnonymousType(nil, ast.SymbolTable{"value": property}, nil, nil, nil) + inner := c.newIntersectionType(ObjectFlagsNone, []*Type{object, object}) + outer := c.newIntersectionType(ObjectFlagsNone, []*Type{inner, object}) + assert.Equal(t, c.getReducedType(outer), outer) + assert.Equal(t, c.getReducedType(inner), inner) + assert.Equal(t, c.getPropertyOfUnionOrIntersectionType(outer, "value", true), property) + assert.Assert(t, c.freePropertyCounts != nil) + assert.Assert(t, c.freePropertyCounts.next != nil) + workspace := c.freePropertyCounts + conflicting := c.newSymbolEx(ast.SymbolFlagsProperty, "value", ast.CheckFlagsContainsPrivate) + outer.AsUnionOrIntersectionType().propertyCacheWithoutFunctionPropertyAugment["value"] = conflicting + assert.Assert(t, c.somePropertyReducesToNever(outer)) + assert.Equal(t, c.freePropertyCounts, workspace) + for counts := c.freePropertyCounts; counts != nil; counts = counts.next { + assert.Equal(t, counts.Size(), 0) + assert.Assert(t, !counts.Has("value")) + } +} + +func BenchmarkCompositeTypeCacheHit(b *testing.B) { + c, types := newCompositeTestChecker() + union := c.getUnionType(types) + objects := []*Type{ + c.newObjectType(ObjectFlagsInterface, nil), + c.newObjectType(ObjectFlagsInterface, nil), + c.newObjectType(ObjectFlagsInterface, nil), + } + + c.getIntersectionType(objects) + c.removeType(union, types[1]) + b.ReportAllocs() + for b.Loop() { + c.getUnionType(types) + c.getIntersectionType(objects) + c.mapType(union, func(t *Type) *Type { return t }) + c.removeType(union, types[1]) + } +} + +func TestTypeMapperDispatch(t *testing.T) { + t.Parallel() + c, types := newCompositeTestChecker() + source, target, other := types[0], types[1], types[2] + simple := newSimpleTypeMapper(source, target) + array := newArrayTypeMapper([]*Type{source, other}, []*Type{target, source}) + merged := newMergedTypeMapper(simple, array) + for _, test := range []struct { + mapper *TypeMapper + kind TypeMapperKind + result *Type + }{ + {simple, TypeMapperKindSimple, target}, + {array, TypeMapperKindArray, target}, + {merged, TypeMapperKindMerged, target}, + {newArrayToSingleTypeMapper([]*Type{source}, target), TypeMapperKindUnknown, target}, + {newDeferredTypeMapper([]*Type{source}, []func() *Type{func() *Type { return target }}), TypeMapperKindUnknown, target}, + {newFunctionTypeMapper(func(typ *Type) *Type { + if typ == source { + return target + } + return typ + }), TypeMapperKindUnknown, target}, + {newCompositeTypeMapper(c, newSimpleTypeMapper(other, target), simple), TypeMapperKindUnknown, target}, + } { + assert.Equal(t, test.mapper.Kind(), test.kind) + assert.Equal(t, test.mapper.Map(source), test.result) + assert.Assert(t, !test.mapper.MapsThisOnly()) + } + assert.Equal(t, compareTypeMappers(simple, newSimpleTypeMapper(source, target)), 0) + assert.Equal(t, compareTypeMappers(array, newArrayTypeMapper([]*Type{source, other}, []*Type{target, source})), 0) + assert.Equal(t, compareTypeMappers(merged, newMergedTypeMapper(simple, array)), 0) + this := c.newTypeParameter(nil) + this.AsTypeParameter().isThisType = true + for _, mapper := range []*TypeMapper{ + newSimpleTypeMapper(this, target), + newArrayTypeMapper([]*Type{this}, []*Type{target}), + newArrayToSingleTypeMapper([]*Type{this}, target), + newDeferredTypeMapper([]*Type{this}, []func() *Type{func() *Type { return target }}), + } { + assert.Assert(t, mapper.MapsThisOnly()) + assert.Equal(t, mapper.Map(this), target) + assert.Equal(t, mapper.Map(other), other) + } +} + +func TestCompactTypeMapperLayout(t *testing.T) { + t.Parallel() + assert.Assert(t, unsafe.Sizeof(SimpleTypeMapper{}) <= 3*unsafe.Sizeof(uintptr(0))) + assert.Assert(t, unsafe.Sizeof(MergedTypeMapper{}) <= 3*unsafe.Sizeof(uintptr(0))) + c, types := newCompositeTestChecker() + mapper := newSimpleTypeMapper(types[0], types[1]) + assert.Assert(t, castTypeMapper[SimpleTypeMapper](mapper, typeMapperSimple).source == types[0]) + context := c.newInferenceContextWorker(nil, nil, InferenceFlagsNone, nil) + tests := []struct { + kind typeMapperKind + mapper *TypeMapper + cast func(*TypeMapper) any + }{ + {typeMapperSimple, mapper, func(m *TypeMapper) any { return castTypeMapper[SimpleTypeMapper](m, typeMapperSimple) }}, + {typeMapperArray, newArrayTypeMapper(nil, nil), func(m *TypeMapper) any { return castTypeMapper[ArrayTypeMapper](m, typeMapperArray) }}, + {typeMapperArrayToSingle, newArrayToSingleTypeMapper(nil, nil), func(m *TypeMapper) any { return castTypeMapper[ArrayToSingleTypeMapper](m, typeMapperArrayToSingle) }}, + {typeMapperDeferred, newDeferredTypeMapper(nil, nil), func(m *TypeMapper) any { return castTypeMapper[DeferredTypeMapper](m, typeMapperDeferred) }}, + {typeMapperFunction, newFunctionTypeMapper(func(t *Type) *Type { return t }), func(m *TypeMapper) any { return castTypeMapper[FunctionTypeMapper](m, typeMapperFunction) }}, + {typeMapperMerged, newMergedTypeMapper(mapper, mapper), func(m *TypeMapper) any { return castTypeMapper[MergedTypeMapper](m, typeMapperMerged) }}, + {typeMapperComposite, newCompositeTypeMapper(c, mapper, mapper), func(m *TypeMapper) any { return castTypeMapper[CompositeTypeMapper](m, typeMapperComposite) }}, + {typeMapperInference, context.mapper, func(m *TypeMapper) any { return castTypeMapper[InferenceTypeMapper](m, typeMapperInference) }}, + } + runtime.GC() + for _, test := range tests { + assert.Equal(t, test.mapper.kind, test.kind) + for _, target := range tests { + assert.Assert(t, didPanic(func() { target.cast(test.mapper) }) == (test.kind != target.kind)) + } + } + runtime.GC() + assert.Equal(t, mapper.Map(types[0]), types[1]) + runtime.KeepAlive(c) +} + +func TestInferenceContextMappers(t *testing.T) { //nolint:paralleltest + c, types := newCompositeTestChecker() + c.errorType = types[0] + info := newInferenceInfo(types[0]) + info.inferredType = types[1] + info.candidates = []*Type{types[1]} + context := c.newInferenceContextWorker([]*InferenceInfo{info}, nil, InferenceFlagsNone, nil) + assert.Equal(t, context.nonFixingMapper.Map(types[0]), types[1]) + assert.Assert(t, !info.isFixed) + clone := c.cloneInferenceContext(context, InferenceFlagsNone) + clone.inferences[0].candidates[0] = types[2] + assert.Equal(t, info.candidates[0], types[1]) + assert.Equal(t, context.mapper.Map(types[0]), types[0]) + assert.Assert(t, info.isFixed) + assert.Assert(t, !clone.inferences[0].isFixed) + assert.Equal(t, context.mapper.Map(types[2]), types[2]) + runtime.GC() + assert.Equal(t, context.nonFixingMapper.Map(types[0]), types[0]) + if !race.Enabled { + assert.Equal(t, testing.AllocsPerRun(10, func() { + c.newInferenceContextWorker([]*InferenceInfo{info}, nil, InferenceFlagsNone, nil) + }), float64(2)) + } +} + +func TestCompactValueSymbolLinksLayout(t *testing.T) { + t.Parallel() + assert.Equal(t, unsafe.Sizeof(ValueSymbolLinks{}), 4*unsafe.Sizeof(uintptr(0))) + assert.Equal(t, unsafe.Sizeof(valueSymbolExtra{}), 3*unsafe.Sizeof(uintptr(0))) + c, types := newCompositeTestChecker() + var links ValueSymbolLinks + assert.Assert(t, links.getWriteType() == nil) + assert.Assert(t, links.getNameType() == nil) + assert.Assert(t, links.getContainingType() == nil) + links.setWriteType(c, nil) + links.setNameType(c, nil) + links.setContainingType(c, nil) + assert.Assert(t, links.extra == nil) + links.setWriteType(c, types[0]) + extra := links.extra + links.setNameType(c, types[1]) + links.setContainingType(c, types[2]) + assert.Equal(t, links.extra, extra) + for range 1024 { + var other ValueSymbolLinks + other.setNameType(c, types[2]) + } + runtime.GC() + assert.Equal(t, links.getWriteType(), types[0]) + assert.Equal(t, links.getNameType(), types[1]) + assert.Equal(t, links.getContainingType(), types[2]) + links.setNameType(c, nil) + assert.Assert(t, links.getNameType() == nil) + assert.Equal(t, links.getWriteType(), types[0]) + assert.Equal(t, links.getContainingType(), types[2]) +} + +func TestStructuredMembersLookup(t *testing.T) { + t.Parallel() + c, _ := newCompositeTestChecker() + for _, count := range []int{0, 1, 8, 20, 300} { + members := make(ast.SymbolTable, count) + for i := range count { + name := strconv.Itoa(i) + members[name] = c.newSymbol(ast.SymbolFlagsProperty, name) + } + typ := c.newAnonymousType(nil, members, nil, nil, nil) + resolved := typ.AsStructuredType() + assert.Equal(t, len(resolved.properties), count) + for name, symbol := range members { + assert.Equal(t, resolved.getMember(name), symbol) + } + assert.Assert(t, resolved.getMember("missing") == nil) + other := c.newAnonymousType(nil, resolved.getMembers(), nil, nil, nil) + for name, symbol := range members { + assert.Equal(t, other.AsStructuredType().getMember(name), symbol) + } + members["new"] = c.newSymbol(ast.SymbolFlagsProperty, "new") + assert.Assert(t, resolved.getMember("new") == nil) + members[ast.InternalSymbolNameCall] = c.newSymbol(ast.SymbolFlagsSignature, ast.InternalSymbolNameCall) + withReserved := c.newAnonymousType(nil, members, nil, nil, nil).AsStructuredType() + assert.Equal(t, withReserved.getMember(ast.InternalSymbolNameCall), members[ast.InternalSymbolNameCall]) + for range 300 { + c.newMemberIndex(members, withReserved.properties, nil) + } + runtime.GC() + for name, symbol := range members { + assert.Equal(t, withReserved.getMember(name), symbol) + } + } + renamed := c.newSymbol(ast.SymbolFlagsProperty, "original") + member := c.newAnonymousType(nil, ast.SymbolTable{"different": renamed}, nil, nil, nil).AsStructuredType() + assert.Equal(t, member.getMember("different"), renamed) + assert.Assert(t, member.getMember("original") == nil) + aliased := c.newSymbol(ast.SymbolFlagsProperty, "original") + aliasedMembers := ast.SymbolTable{"original": aliased, "different": aliased} + for i := range 10 { + name := "p" + strconv.Itoa(i) + aliasedMembers[name] = c.newSymbol(ast.SymbolFlagsProperty, name) + } + aliasedType := c.newAnonymousType(nil, aliasedMembers, nil, nil, nil).AsStructuredType() + for name, symbol := range aliasedMembers { + assert.Equal(t, aliasedType.getMember(name), symbol) + } +} + +func TestUnionIntersectionPropertyCacheSharing(t *testing.T) { + t.Parallel() + for _, intersection := range []bool{false, true} { + for _, augmentedFirst := range []bool{false, true} { + t.Run(strconv.FormatBool(intersection)+"/"+strconv.FormatBool(augmentedFirst), func(t *testing.T) { + t.Parallel() + c, _ := newCompositeTestChecker() + members := make(ast.SymbolTable) + for i := range 300 { + name := strconv.Itoa(i) + members[name] = c.newSymbol(ast.SymbolFlagsProperty, name) + } + members[""] = c.newSymbol(ast.SymbolFlagsProperty, "") + object := c.newAnonymousType(nil, members, nil, nil, nil) + var typ *Type + if intersection { + typ = c.newIntersectionType(ObjectFlagsNone, []*Type{object, object}) + } else { + typ = c.newUnionType(ObjectFlagsNone, []*Type{object, object}) + } + data := typ.AsUnionOrIntersectionType() + for name, symbol := range members { + assert.Equal(t, c.getUnionOrIntersectionProperty(typ, name, !augmentedFirst), symbol) + assert.Equal(t, c.getUnionOrIntersectionProperty(typ, name, augmentedFirst), symbol) + } + assert.Equal(t, len(data.propertyCacheWithoutFunctionPropertyAugment), len(members)) + assert.Assert(t, data.propertyCache == nil) + runtime.GC() + for name, symbol := range members { + assert.Equal(t, c.getUnionOrIntersectionProperty(typ, name, true), symbol) + assert.Equal(t, c.getUnionOrIntersectionProperty(typ, name, false), symbol) + } + runtime.KeepAlive(c) + }) + } + } +} + +func TestUnionIntersectionPropertyCacheModes(t *testing.T) { + t.Parallel() + for _, intersection := range []bool{false, true} { + t.Run(strconv.FormatBool(intersection), func(t *testing.T) { + t.Parallel() + c, _ := newCompositeTestChecker() + var typ *Type + if intersection { + typ = c.newIntersectionType(ObjectFlagsNone, nil) + } else { + typ = c.newUnionType(ObjectFlagsNone, nil) + } + data := typ.AsUnionOrIntersectionType() + assert.Assert(t, c.getUnionOrIntersectionProperty(typ, "missing", true) == nil) + assert.Assert(t, c.getUnionOrIntersectionProperty(typ, "missing", false) == nil) + assert.Assert(t, data.propertyCache == nil) + assert.Assert(t, data.propertyCacheWithoutFunctionPropertyAugment == nil) + data.propertyCacheWithoutFunctionPropertyAugment = make(ast.SymbolTable) + data.propertyCache = make(ast.SymbolTable) + for _, flags := range []ast.CheckFlags{ast.CheckFlagsReadPartial, ast.CheckFlagsWritePartial} { + name := strconv.Itoa(int(flags)) + partial := c.newSymbolEx(ast.SymbolFlagsProperty, name, flags) + complete := c.newSymbol(ast.SymbolFlagsProperty, name) + data.propertyCacheWithoutFunctionPropertyAugment[name] = partial + assert.Equal(t, c.getUnionOrIntersectionProperty(typ, name, true), partial) + assert.Assert(t, c.getUnionOrIntersectionProperty(typ, name, false) == nil) + assert.Equal(t, c.getPropertyOfUnionOrIntersectionType(typ, name, true) == nil, flags&ast.CheckFlagsReadPartial != 0) + data.propertyCache[name] = complete + assert.Equal(t, c.getUnionOrIntersectionProperty(typ, name, false), complete) + } + nonAugmented := c.newSymbol(ast.SymbolFlagsProperty, "different") + augmented := c.newSymbol(ast.SymbolFlagsProperty, "different") + data.propertyCacheWithoutFunctionPropertyAugment["different"] = nonAugmented + data.propertyCache["different"] = augmented + assert.Equal(t, c.getUnionOrIntersectionProperty(typ, "different", true), nonAugmented) + assert.Equal(t, c.getUnionOrIntersectionProperty(typ, "different", false), augmented) + }) + } +} + +func TestCompactStructuredTypeLayout(t *testing.T) { + t.Parallel() + assert.Equal(t, unsafe.Sizeof(StructuredType{}), unsafe.Sizeof(ConstrainedType{})+5*unsafe.Sizeof(uintptr(0))) +} + +func TestStructuredTypeExtra(t *testing.T) { + t.Parallel() + c, types := newCompositeTestChecker() + data := c.newAnonymousType(nil, nil, nil, nil, nil).AsStructuredType() + assert.Assert(t, data.extra == nil) + assert.Assert(t, data.CallSignatures() == nil) + assert.Assert(t, data.ConstructSignatures() == nil) + assert.Assert(t, data.getIndexInfos() == nil) + c.setStructuredTypeSignatures(data, nil, nil, nil) + assert.Assert(t, data.extra == nil) + + call := &Signature{} + construct := &Signature{} + info := &IndexInfo{keyType: types[0]} + c.setStructuredTypeSignatures(data, []*Signature{call}, []*Signature{construct}, []*IndexInfo{info}) + assert.Equal(t, data.CallSignatures()[0], call) + assert.Equal(t, data.ConstructSignatures()[0], construct) + assert.Equal(t, cap(data.CallSignatures()), 1) + assert.Equal(t, cap(data.ConstructSignatures()), 1) + assert.Equal(t, data.getIndexInfos()[0], info) + extra := data.extra + extra.objectTypeWithoutAbstractConstructSignatures = types[2] + for range 1024 { + other := c.newAnonymousType(nil, nil, []*Signature{call}, nil, nil) + assert.Assert(t, other.AsStructuredType().extra != extra) + } + runtime.GC() + assert.Equal(t, data.CallSignatures()[0], call) + assert.Equal(t, data.ConstructSignatures()[0], construct) + assert.Equal(t, data.getIndexInfos()[0], info) + assert.Equal(t, data.extra.objectTypeWithoutAbstractConstructSignatures, types[2]) + c.setStructuredTypeSignatures(data, nil, []*Signature{construct}, nil) + assert.Equal(t, len(data.CallSignatures()), 0) + assert.Equal(t, data.ConstructSignatures()[0], construct) + assert.Assert(t, data.getIndexInfos() == nil) + c.setStructuredTypeSignatures(data, nil, nil, nil) + assert.Assert(t, data.CallSignatures() == nil) + assert.Assert(t, data.ConstructSignatures() == nil) + assert.Equal(t, data.extra, extra) + assert.Equal(t, extra.objectTypeWithoutAbstractConstructSignatures, types[2]) + c.setStructuredTypeSignatures(data, nil, nil, []*IndexInfo{}) + assert.Assert(t, data.getIndexInfos() != nil) + runtime.KeepAlive(c) +} + +func TestCompactTypeNodeLinksLayout(t *testing.T) { + t.Parallel() + assert.Equal(t, unsafe.Sizeof(TypeNodeLinks{}), 2*unsafe.Sizeof(uintptr(0))) + c, types := newCompositeTestChecker() + var links TypeNodeLinks + links.resolvedType = types[0] + assert.Assert(t, links.getOuterTypeParameters() == nil) + links.setOuterTypeParameters(c, nil) + assert.Assert(t, links.outerTypeParameters == nil) + links.setOuterTypeParameters(c, []*Type{}) + assert.Assert(t, links.getOuterTypeParameters() != nil) + assert.Equal(t, len(links.getOuterTypeParameters()), 0) + entry := links.outerTypeParameters + list := slices.Clone(types) + links.setOuterTypeParameters(c, list) + assert.Equal(t, links.outerTypeParameters, entry) + assert.Equal(t, links.getOuterTypeParameters()[0], types[0]) + list[0] = types[1] + assert.Equal(t, links.getOuterTypeParameters()[0], types[1]) + for range 1024 { + var other TypeNodeLinks + other.setOuterTypeParameters(c, types) + } + runtime.GC() + assert.Equal(t, links.getOuterTypeParameters()[0], types[1]) + assert.Equal(t, links.resolvedType, types[0]) + links.setOuterTypeParameters(c, nil) + assert.Assert(t, links.getOuterTypeParameters() == nil) + assert.Equal(t, links.resolvedType, types[0]) + runtime.KeepAlive(c) +} + +func TestCompactSignatureLayout(t *testing.T) { + t.Parallel() + assert.Equal(t, unsafe.Sizeof(Signature{}), 16+8*unsafe.Sizeof(uintptr(0))) + assert.Equal(t, unsafe.Sizeof(signatureExtra{}), 7*unsafe.Sizeof(uintptr(0))) +} + +func TestSignatureExtra(t *testing.T) { + t.Parallel() + c, types := newCompositeTestChecker() + c.noTypePredicate = &TypePredicate{} + sig := c.newSignature(SignatureFlagsHasRestParameter, nil, nil, nil, nil, types[0], nil, 1) + assert.Assert(t, sig.extra == nil) + assert.Assert(t, sig.TypeParameters() == nil) + assert.Assert(t, sig.ThisParameter() == nil) + assert.Assert(t, sig.getComposite() == nil) + assert.Assert(t, sig.getIsolatedSignatureType() == nil) + assert.Assert(t, sig.getResolvedTypePredicate(c) == nil) + assert.Equal(t, sig.resolvedMinArgumentCount, int32(-1)) + sig.setTypeParameters(c, nil) + sig.setThisParameter(c, nil) + sig.setComposite(c, nil) + sig.setResolvedTypePredicate(c, nil) + assert.Assert(t, sig.extra == nil) + assert.Assert(t, c.getTypePredicateOfSignature(sig) == nil) + assert.Equal(t, sig.getResolvedTypePredicate(c), c.noTypePredicate) + assert.Assert(t, sig.extra == nil) + assert.Assert(t, sig.flags&SignatureFlagsHasRestParameter != 0) + assert.Equal(t, sig.Flags(), SignatureFlagsHasRestParameter) + sig.setResolvedTypePredicate(c, nil) + assert.Assert(t, sig.getResolvedTypePredicate(c) == nil) + sig.setTypeParameters(c, []*Type{}) + assert.Assert(t, sig.TypeParameters() != nil) + entry := sig.extra + list := slices.Clone(types) + sig.setTypeParameters(c, list) + list[0] = types[1] + assert.Equal(t, sig.TypeParameters()[0], types[1]) + parameter := &ast.Symbol{} + sig.setThisParameter(c, parameter) + predicate := c.newTypePredicate(TypePredicateKindIdentifier, "p", 0, types[0]) + sig.setResolvedTypePredicate(c, predicate) + assert.Equal(t, c.getTypePredicateOfSignature(sig), predicate) + composite := &CompositeSignature{isUnion: true, signatures: []*Signature{sig}} + sig.setComposite(c, composite) + sig.ensureExtra(c).isolatedSignatureType = types[2] + clone := c.cloneSignature(sig) + assert.Assert(t, clone.extra != entry) + assert.Equal(t, clone.getComposite(), composite) + assert.Equal(t, clone.ThisParameter(), parameter) + assert.Equal(t, clone.TypeParameters()[0], types[1]) + assert.Assert(t, clone.getResolvedTypePredicate(c) == nil) + assert.Assert(t, clone.getIsolatedSignatureType() == nil) + clone.setThisParameter(c, nil) + assert.Equal(t, sig.ThisParameter(), parameter) + sig.setResolvedTypePredicate(c, c.noTypePredicate) + assert.Assert(t, c.getTypePredicateOfSignature(sig) == nil) + assert.Assert(t, entry.resolvedTypePredicate == nil) + sig.setResolvedTypePredicate(c, predicate) + for range 1024 { + other := c.newSignature(SignatureFlagsNone, nil, types, parameter, nil, nil, predicate, 0) + other.setComposite(c, composite) + } + runtime.GC() + assert.Equal(t, sig.extra, entry) + assert.Equal(t, sig.getResolvedTypePredicate(c), predicate) + assert.Equal(t, sig.Flags(), SignatureFlagsHasRestParameter) + assert.Equal(t, sig.getIsolatedSignatureType(), types[2]) + sig.setTypeParameters(c, nil) + sig.setThisParameter(c, nil) + sig.setComposite(c, nil) + assert.Equal(t, sig.extra, entry) + assert.Assert(t, sig.TypeParameters() == nil) + assert.Equal(t, sig.resolvedReturnType, types[0]) + assert.Equal(t, sig.minArgumentCount, int32(1)) + assert.Equal(t, sig.getResolvedTypePredicate(c), predicate) + runtime.KeepAlive(c) +} diff --git a/tsc/internal/checker/utilities.go b/tsc/internal/checker/utilities.go index ff729bc30b393..007a5eb19b471 100644 --- a/tsc/internal/checker/utilities.go +++ b/tsc/internal/checker/utilities.go @@ -8,6 +8,7 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/ast" "github.com/microsoft/TypeScript/tsc/internal/binder" + "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/debug" "github.com/microsoft/TypeScript/tsc/internal/diagnostics" @@ -513,10 +514,10 @@ func CompareTypes(t1, t2 *Type) int { // instantiateAnonymousType prepends a fresh type parameter mapping. // Compare the effective instantiation, not the identity of that fresh parameter. if m1 != nil { - m1 = m1.data.(*CompositeTypeMapper).m2 + m1 = castTypeMapper[CompositeTypeMapper](m1, typeMapperComposite).m2 } if m2 != nil { - m2 = m2.data.(*CompositeTypeMapper).m2 + m2 = castTypeMapper[CompositeTypeMapper](m2, typeMapperComposite).m2 } } if c := compareTypeMappers(m1, m2); c != 0 { @@ -730,22 +731,22 @@ func compareTypeMappers(m1, m2 *TypeMapper) int { } switch kind1 { case TypeMapperKindSimple: - m1 := m1.data.(*SimpleTypeMapper) - m2 := m2.data.(*SimpleTypeMapper) + m1 := castTypeMapper[SimpleTypeMapper](m1, typeMapperSimple) + m2 := castTypeMapper[SimpleTypeMapper](m2, typeMapperSimple) if c := CompareTypes(m1.source, m2.source); c != 0 { return c } return CompareTypes(m1.target, m2.target) case TypeMapperKindArray: - m1 := m1.data.(*ArrayTypeMapper) - m2 := m2.data.(*ArrayTypeMapper) + m1 := castTypeMapper[ArrayTypeMapper](m1, typeMapperArray) + m2 := castTypeMapper[ArrayTypeMapper](m2, typeMapperArray) if c := compareTypeLists(m1.sources, m2.sources); c != 0 { return c } return compareTypeLists(m1.targets, m2.targets) case TypeMapperKindMerged: - m1 := m1.data.(*MergedTypeMapper) - m2 := m2.data.(*MergedTypeMapper) + m1 := castTypeMapper[MergedTypeMapper](m1, typeMapperMerged) + m2 := castTypeMapper[MergedTypeMapper](m2, typeMapperMerged) if c := compareTypeMappers(m1.m1, m2.m1); c != 0 { return c } @@ -881,6 +882,71 @@ type orderedSet[T comparable] struct { values []T } +// Composite type construction often finds an existing interned type. Borrow +// workspace for normalization, and copy constituents only when publishing a +// new type. Each recursive construction borrows a separate set. +type temporaryTypeSet struct { + orderedSet[*Type] + inline [16]*Type + next *temporaryTypeSet +} + +func (c *Checker) getTemporaryTypeSet() *temporaryTypeSet { + set := c.freeTypeSets + if set == nil { + set = &temporaryTypeSet{} + set.values = set.inline[:0] + } else { + c.freeTypeSets = set.next + set.next = nil + } + return set +} + +func (c *Checker) releaseTemporaryTypeSet(set *temporaryTypeSet) { + clear(set.values) + if cap(set.values) > len(set.inline) { + clear(set.inline[:]) + } + clear(set.valuesByKey) + // Do not retain arbitrarily large temporary unions and their dedup maps. + if cap(set.values) > 4096 { + set.values = set.inline[:0] + set.valuesByKey = nil + } else { + set.values = set.values[:0] + } + set.next = c.freeTypeSets + c.freeTypeSets = set +} + +type temporaryPropertyCounts struct { + collections.OrderedMap[string, int] + next *temporaryPropertyCounts +} + +func (c *Checker) getTemporaryPropertyCounts() *temporaryPropertyCounts { + counts := c.freePropertyCounts + if counts == nil { + return &temporaryPropertyCounts{} + } + c.freePropertyCounts = counts.next + counts.next = nil + return counts +} + +func (c *Checker) releaseTemporaryPropertyCounts(counts *temporaryPropertyCounts) { + size := counts.Size() + counts.Clear() + // Recursive reductions borrow separate maps. Do not retain unusually + // large property tables or references to their names in the free list. + if size > 4096 { + return + } + counts.next = c.freePropertyCounts + c.freePropertyCounts = counts +} + func (s *orderedSet[T]) contains(value T) bool { if s.valuesByKey == nil { return slices.Contains(s.values, value) diff --git a/tsc/internal/core/arena.go b/tsc/internal/core/arena.go index 87e231f70c781..ed795b7eca0f4 100644 --- a/tsc/internal/core/arena.go +++ b/tsc/internal/core/arena.go @@ -1,6 +1,10 @@ package core -import "slices" +import ( + "math/bits" + "slices" + "unsafe" +) // Arena allocator @@ -8,11 +12,11 @@ type Arena[T any] struct { data []T } -// Allocate a single element in the arena and return a pointer to the element. If the arena is at capacity, -// a new arena of the next size up is allocated. +// Allocate a single element at a stable address. Small chunks bound the unused +// capacity and unrelated values retained by a surviving pointer into a chunk. func (a *Arena[T]) New() *T { if len(a.data) == cap(a.data) { - nextSize := nextArenaSize(len(a.data)) + nextSize := nextArenaSize[T](len(a.data)) // Use the same trick as slices.Concat; Grow rounds up to the next size class. a.data = slices.Grow[[]T](nil, nextSize) } @@ -30,7 +34,7 @@ func (a *Arena[T]) NewSlice(size int) []T { return nil } if len(a.data)+size > cap(a.data) { - nextSize := nextArenaSize(len(a.data)) + nextSize := nextArenaSize[T](len(a.data)) if size > nextSize { return make([]T, size) } @@ -58,9 +62,49 @@ func (a *Arena[T]) Clone(t []T) []T { return slice } -func nextArenaSize(size int) int { - // This compiles down branch-free. +func nextArenaSize[T any](size int) int { + // Target 512 bytes before allocator size-class rounding, with at least one + // value. A surviving interior pointer retains and scans the whole chunk. + maxSize := max(512/max(int(unsafe.Sizeof(*new(T))), 1), 1) size = max(size, 1) - size = min(size*2, 256) + size = min(size*2, 256, maxSize) return size } + +// IndexedArena keeps values at stable addresses and references them with uint32 +// indexes instead of Go pointers. Index zero is nil. Unlike Arena, it retains all +// blocks so that an index alone keeps its value reachable through the arena. +type IndexedArena[T any] struct { + blocks [][]T + size uint32 +} + +const indexedArenaPageShift = 8 + +func (a *IndexedArena[T]) New() (uint32, *T) { + if a.size == ^uint32(0) { + panic("IndexedArena exhausted") + } + if len(a.blocks) == 0 || len(a.blocks[len(a.blocks)-1]) == cap(a.blocks[len(a.blocks)-1]) { + size := 1 << min(len(a.blocks), indexedArenaPageShift) + a.blocks = append(a.blocks, make([]T, 0, size)) + } + block := &a.blocks[len(a.blocks)-1] + *block = (*block)[:len(*block)+1] + a.size++ + return a.size, &(*block)[len(*block)-1] +} + +func (a *IndexedArena[T]) Get(index uint32) *T { + if index == 0 { + return nil + } + // The initial blocks have sizes 1, 2, 4, ..., 128. Subsequent + // blocks have 256 entries, avoiding geometric over-allocation. + if index < 1<>indexedArenaPageShift)][index&((1<> LinkPageShift + return int(pageIndex) < len(s.pages) && s.pages[pageIndex] != nil && s.pages[pageIndex][key&LinkPageMask] != 0 } func (s *PagedLinkStore[V]) TryGet(key uint64) *V { pageIndex := key >> LinkPageShift if int(pageIndex) < len(s.pages) { if page := s.pages[pageIndex]; page != nil { - return page[key&LinkPageMask] + return s.arena.Get(page[key&LinkPageMask]) } } return nil diff --git a/tsc/internal/core/linkstore_test.go b/tsc/internal/core/linkstore_test.go new file mode 100644 index 0000000000000..624736e14ed9e --- /dev/null +++ b/tsc/internal/core/linkstore_test.go @@ -0,0 +1,237 @@ +package core_test + +import ( + "runtime" + "strconv" + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/core" + "gotest.tools/v3/assert" +) + +func TestLinkStore(t *testing.T) { + t.Parallel() + type value struct { + number int + text *string + } + var store core.LinkStore[int, value] + assert.Assert(t, !store.Has(0)) + assert.Assert(t, store.TryGet(0) == nil) + + values := make([]*value, 4096) + for i := range values { + v := store.Get(i) + assert.Equal(t, *v, value{}) + v.number = i + v.text = new("retained") + values[i] = v + } + runtime.GC() + for i, v := range values { + assert.Assert(t, store.Has(i)) + assert.Equal(t, store.Get(i), v) + assert.Equal(t, store.TryGet(i), v) + assert.Equal(t, v.number, i) + assert.Equal(t, *v.text, "retained") + } + assert.Assert(t, !store.Has(len(values))) + assert.Assert(t, store.TryGet(len(values)) == nil) +} + +func TestPagedLinkStore(t *testing.T) { + t.Parallel() + var store core.PagedLinkStore[int] + keys := []uint64{0, 255, 256, 65535, 16777215} + values := make([]*int, len(keys)) + for _, key := range keys { + assert.Assert(t, !store.Has(key)) + } + for i, key := range keys { + v := store.Get(key) + assert.Equal(t, *v, 0) + *v = i + 1 + values[i] = v + } + runtime.GC() + for i, key := range keys { + assert.Assert(t, store.Has(key)) + assert.Equal(t, store.Get(key), values[i]) + assert.Equal(t, *store.TryGet(key), i+1) + } + assert.Assert(t, !store.Has(1)) + assert.Assert(t, store.TryGet(1) == nil) +} + +func BenchmarkLinkStore(b *testing.B) { + type value struct { + typ *int + flags uint32 + } + b.ReportAllocs() + for b.Loop() { + var store core.LinkStore[int, value] + for i := range 10000 { + store.Get(i).flags = uint32(i) + } + for i := range 10000 { + if store.Get(i).flags != uint32(i) { + b.Fatal("link changed during arena growth") + } + } + + } +} + +func TestIndexedArena(t *testing.T) { + t.Parallel() + type value struct { + number int + text *string + } + var arena core.IndexedArena[value] + assert.Assert(t, arena.Get(0) == nil) + values := make([]*value, 4096) + for i := range values { + index, v := arena.New() + assert.Equal(t, index, uint32(i+1)) + assert.Equal(t, *v, value{}) + v.number = i + v.text = new("retained") + values[i] = v + } + runtime.GC() + for i, v := range values { + assert.Equal(t, arena.Get(uint32(i+1)), v) + assert.Equal(t, v.number, i) + assert.Equal(t, *v.text, "retained") + } +} + +func TestIndexedArenaReachability(t *testing.T) { + t.Parallel() + var arena core.IndexedArena[*string] + for i := range 4096 { + _, value := arena.New() + *value = new(strconv.Itoa(i)) + } + runtime.GC() + for i := range 4096 { + assert.Equal(t, **arena.Get(uint32(i + 1)), strconv.Itoa(i)) + } +} + +func TestArenaBoundsSingleValueRetention(t *testing.T) { //nolint:paralleltest + type value struct { + pointer *int + padding [65528]byte + } + runtime.GC() + var before runtime.MemStats + runtime.ReadMemStats(&before) + var arena core.Arena[value] + var retained *value + for i := range 300 { + retained = arena.New() + retained.pointer = new(i) + } + arena = core.Arena[value]{} + runtime.GC() + runtime.GC() + var after runtime.MemStats + runtime.ReadMemStats(&after) + assert.Equal(t, *retained.pointer, 299) + assert.Assert(t, after.HeapAlloc < before.HeapAlloc+1024*1024, "one live value retained more than 1 MiB") + runtime.KeepAlive(retained) +} + +func TestArenaMixedSingleValuesAndSlices(t *testing.T) { + t.Parallel() + type value struct { + number int + text *string + } + var arena core.Arena[value] + assert.Assert(t, arena.NewSlice(0) == nil) + first := arena.New() + first.number, first.text = 1, new("first") + small := arena.NewSlice1(value{number: 3, text: new("small")}) + copyOfSmall := arena.Clone(small) + small[0].number = 4 + slices := make([][]value, 0, 7) + for _, size := range []int{1, 2, 31, 32, 33, 64, 100} { + slice := arena.NewSlice(size) + assert.Equal(t, len(slice), size) + assert.Equal(t, cap(slice), size) + for i := range slice { + assert.Equal(t, slice[i], value{}) + slice[i] = value{number: i + size, text: new(strconv.Itoa(size))} + } + slices = append(slices, slice) + assert.Equal(t, *arena.New(), value{}) + } + values := arena.NewSlice(100) + assert.Equal(t, len(values), 100) + assert.Equal(t, cap(values), 100) + for i := range values { + values[i].number = i + } + last := arena.New() + last.number, last.text = 2, new("last") + for range 1024 { + arena.New() + } + arena = core.Arena[value]{} + runtime.GC() + assert.Equal(t, first.number, 1) + assert.Equal(t, *first.text, "first") + assert.Equal(t, last.number, 2) + assert.Equal(t, *last.text, "last") + assert.Equal(t, small[0].number, 4) + assert.Equal(t, *small[0].text, "small") + assert.Equal(t, copyOfSmall[0].number, 3) + assert.Equal(t, *copyOfSmall[0].text, "small") + for _, slice := range slices { + for i := range slice { + assert.Equal(t, slice[i].number, i+len(slice)) + assert.Equal(t, *slice[i].text, strconv.Itoa(len(slice))) + } + } + for i := range values { + assert.Equal(t, values[i].number, i) + } +} + +func TestArenaZeroSizedValues(t *testing.T) { + t.Parallel() + var arena core.Arena[struct{}] + for range 1024 { + assert.Assert(t, arena.New() != nil) + } + values := arena.NewSlice(300) + assert.Equal(t, len(values), 300) + assert.Equal(t, cap(values), 300) +} + +func BenchmarkPagedLinkStore(b *testing.B) { + for _, stride := range []uint64{1, 16, 256} { + b.Run(strconv.FormatUint(stride, 10), func(b *testing.B) { + type value struct { + typ *int + flags uint32 + } + b.ReportAllocs() + for b.Loop() { + var store core.PagedLinkStore[value] + for i := range 10000 { + store.Get(uint64(i) * stride).flags = uint32(i) + } + for i := range 10000 { + if store.Get(uint64(i)*stride).flags != uint32(i) { + b.Fatal("link changed during arena growth") + } + } + } + }) + } +} diff --git a/tsc/internal/transformers/declarations/transform.go b/tsc/internal/transformers/declarations/transform.go index f2bb66a6803cb..3a33028a84153 100644 --- a/tsc/internal/transformers/declarations/transform.go +++ b/tsc/internal/transformers/declarations/transform.go @@ -1723,9 +1723,12 @@ func (tx *DeclarationTransformer) transformTopLevelDeclaration(input *ast.Node) if input.Kind == ast.KindImportDeclaration || input.Kind == ast.KindJSImportDeclaration { res := tx.transformImportDeclaration(input.AsImportDeclaration()) if res != nil && res.Kind != ast.KindImportDeclaration { - res := res.Clone(tx.Factory()) - res.Kind = ast.KindImportDeclaration - return res + decl := res.AsImportDeclaration() + replacement := tx.Factory().NewImportDeclaration(decl.Modifiers(), decl.ImportClause, decl.ModuleSpecifier, decl.Attributes) + replacement.Flags = res.Flags + replacement.Loc = res.Loc + tx.EmitContext().SetOriginal(replacement, res) + return replacement } return res } diff --git a/tsc/testdata/baselines/reference/conformance/importTag5.js b/tsc/testdata/baselines/reference/conformance/importTag5.js index 3d2361c1ad8fb..b8856f6c0ba42 100644 --- a/tsc/testdata/baselines/reference/conformance/importTag5.js +++ b/tsc/testdata/baselines/reference/conformance/importTag5.js @@ -4,6 +4,9 @@ export interface Foo { a: number; } +export interface Unused { + unused: true; +} //// [foo.js] /** @@ -15,6 +18,26 @@ export interface Foo { */ function f(foo) {} +//// [imports.js] +/** + * @import { Foo, Unused } from "./types" + */ +/** + * @param {Foo} foo + */ +export function filtered(foo) { + return foo; +} +/** + * @import * as types from "./types" + */ +/** + * @param {types.Foo} foo + */ +export function namespace(foo) { + return foo; +} + @@ -22,7 +45,10 @@ function f(foo) {} export interface Foo { a: number; } -//// [foo.d.ts] +export interface Unused { + unused: true; +} +//# sourceMappingURL=types.d.ts.map//// [foo.d.ts] /** * @import { Foo } from "./types" */ @@ -31,3 +57,21 @@ import type { Foo } from "./types"; * @param { Foo } foo */ declare function f(foo: Foo): void; +//# sourceMappingURL=foo.d.ts.map//// [imports.d.ts] +import type { Foo } from "./types"; +/** + * @import { Foo, Unused } from "./types" + */ +/** + * @param {Foo} foo + */ +export declare function filtered(foo: Foo): Foo; +import type * as types from "./types"; +/** + * @import * as types from "./types" + */ +/** + * @param {types.Foo} foo + */ +export declare function namespace(foo: types.Foo): Foo; +//# sourceMappingURL=imports.d.ts.map \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/importTag5.js.map b/tsc/testdata/baselines/reference/conformance/importTag5.js.map new file mode 100644 index 0000000000000..e26abef78ca3b --- /dev/null +++ b/tsc/testdata/baselines/reference/conformance/importTag5.js.map @@ -0,0 +1,11 @@ +//// [foo.d.ts.map] +{"version":3,"file":"foo.d.ts","sources":["foo.js"],"names":[],"mappings":"AAAA;;GAEG;AADA,OAAQ,KAAA,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAGjC;;GAEG;AACH,iBAAS,CAAC,CAAC,GAAG,EAFF,GAEE,QAAI"} +//// https://sokra.github.io/source-map-visualization#base64,LyoqDQogKiBAaW1wb3J0IHsgRm9vIH0gZnJvbSAiLi90eXBlcyINCiAqLw0KaW1wb3J0IHR5cGUgeyBGb28gfSBmcm9tICIuL3R5cGVzIjsNCi8qKg0KICogQHBhcmFtIHsgRm9vIH0gZm9vDQogKi8NCmRlY2xhcmUgZnVuY3Rpb24gZihmb286IEZvbyk6IHZvaWQ7DQovLyMgc291cmNlTWFwcGluZ1VSTD1mb28uZC50cy5tYXA=,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9vLmQudHMiLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQURBLE9BQVEsS0FBQSxFQUFFLEdBQUcsRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUdqQzs7R0FFRztBQUNILGlCQUFTLENBQUMsQ0FBQyxHQUFHLEVBRkYsR0FFRSxRQUFJIn0=,LyoqCiAqIEBpbXBvcnQgeyBGb28gfSBmcm9tICIuL3R5cGVzIgogKi8KCi8qKgogKiBAcGFyYW0geyBGb28gfSBmb28KICovCmZ1bmN0aW9uIGYoZm9vKSB7fQo= + +//// [imports.d.ts.map] +{"version":3,"file":"imports.d.ts","sources":["imports.js"],"names":[],"mappings":"AACG,OAAQ,KAAA,EAAE,GAAG,EAAU,MAAM,SAAS,CAAA;AADzC;;GAEG;AACH;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAFjB,GAEiB,OAE3B;AAEE,OAAQ,KAAA,KAAK,KAAK,MAAM,SAAS,CAAA;AADpC;;GAEG;AACH;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAFlB,KAAK,CAAC,GAEY,OAE5B"} +//// https://sokra.github.io/source-map-visualization#base64,aW1wb3J0IHR5cGUgeyBGb28gfSBmcm9tICIuL3R5cGVzIjsNCi8qKg0KICogQGltcG9ydCB7IEZvbywgVW51c2VkIH0gZnJvbSAiLi90eXBlcyINCiAqLw0KLyoqDQogKiBAcGFyYW0ge0Zvb30gZm9vDQogKi8NCmV4cG9ydCBkZWNsYXJlIGZ1bmN0aW9uIGZpbHRlcmVkKGZvbzogRm9vKTogRm9vOw0KaW1wb3J0IHR5cGUgKiBhcyB0eXBlcyBmcm9tICIuL3R5cGVzIjsNCi8qKg0KICogQGltcG9ydCAqIGFzIHR5cGVzIGZyb20gIi4vdHlwZXMiDQogKi8NCi8qKg0KICogQHBhcmFtIHt0eXBlcy5Gb299IGZvbw0KICovDQpleHBvcnQgZGVjbGFyZSBmdW5jdGlvbiBuYW1lc3BhY2UoZm9vOiB0eXBlcy5Gb28pOiBGb287DQovLyMgc291cmNlTWFwcGluZ1VSTD1pbXBvcnRzLmQudHMubWFw,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wb3J0cy5kLnRzIiwic291cmNlcyI6WyJpbXBvcnRzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNHLE9BQVEsS0FBQSxFQUFFLEdBQUcsRUFBVSxNQUFNLFNBQVMsQ0FBQTtBQUR6Qzs7R0FFRztBQUNIOztHQUVHO0FBQ0gsd0JBQWdCLFFBQVEsQ0FBQyxHQUFHLEVBRmpCLEdBRWlCLE9BRTNCO0FBRUUsT0FBUSxLQUFBLEtBQUssS0FBSyxNQUFNLFNBQVMsQ0FBQTtBQURwQzs7R0FFRztBQUNIOztHQUVHO0FBQ0gsd0JBQWdCLFNBQVMsQ0FBQyxHQUFHLEVBRmxCLEtBQUssQ0FBQyxHQUVZLE9BRTVCIn0=,LyoqCiAqIEBpbXBvcnQgeyBGb28sIFVudXNlZCB9IGZyb20gIi4vdHlwZXMiCiAqLwovKioKICogQHBhcmFtIHtGb299IGZvbwogKi8KZXhwb3J0IGZ1bmN0aW9uIGZpbHRlcmVkKGZvbykgewogICAgcmV0dXJuIGZvbzsKfQovKioKICogQGltcG9ydCAqIGFzIHR5cGVzIGZyb20gIi4vdHlwZXMiCiAqLwovKioKICogQHBhcmFtIHt0eXBlcy5Gb299IGZvbwogKi8KZXhwb3J0IGZ1bmN0aW9uIG5hbWVzcGFjZShmb28pIHsKICAgIHJldHVybiBmb287Cn0K + +//// [types.d.ts.map] +{"version":3,"file":"types.d.ts","sources":["types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG;IAChB,CAAC,EAAE,MAAM,CAAC;CACb;AACD,MAAM,WAAW,MAAM;IACnB,MAAM,EAAE,IAAI,CAAC;CAChB"} +//// https://sokra.github.io/source-map-visualization#base64,ZXhwb3J0IGludGVyZmFjZSBGb28gew0KICAgIGE6IG51bWJlcjsNCn0NCmV4cG9ydCBpbnRlcmZhY2UgVW51c2VkIHsNCiAgICB1bnVzZWQ6IHRydWU7DQp9DQovLyMgc291cmNlTWFwcGluZ1VSTD10eXBlcy5kLnRzLm1hcA==,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZXMiOlsidHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxXQUFXLEdBQUc7SUFDaEIsQ0FBQyxFQUFFLE1BQU0sQ0FBQztDQUNiO0FBQ0QsTUFBTSxXQUFXLE1BQU07SUFDbkIsTUFBTSxFQUFFLElBQUksQ0FBQztDQUNoQiJ9,ZXhwb3J0IGludGVyZmFjZSBGb28gewogICAgYTogbnVtYmVyOwp9CmV4cG9ydCBpbnRlcmZhY2UgVW51c2VkIHsKICAgIHVudXNlZDogdHJ1ZTsKfQo= diff --git a/tsc/testdata/baselines/reference/conformance/importTag5.sourcemap.txt b/tsc/testdata/baselines/reference/conformance/importTag5.sourcemap.txt new file mode 100644 index 0000000000000..5afb9fdff1454 --- /dev/null +++ b/tsc/testdata/baselines/reference/conformance/importTag5.sourcemap.txt @@ -0,0 +1,389 @@ +=================================================================== +JsFile: types.d.ts +mapUrl: types.d.ts.map +sourceRoot: +sources: types.ts +=================================================================== +------------------------------------------------------------------- +emittedFile:/types.d.ts +sourceFile:types.ts +------------------------------------------------------------------- +>>>export interface Foo { +1 > +2 >^^^^^^ +3 > ^^^^^^^^^^^ +4 > ^^^ +1 > +2 >export +3 > interface +4 > Foo +1 >Emitted(1, 1) Source(1, 1) + SourceIndex(0) +2 >Emitted(1, 7) Source(1, 7) + SourceIndex(0) +3 >Emitted(1, 18) Source(1, 18) + SourceIndex(0) +4 >Emitted(1, 21) Source(1, 21) + SourceIndex(0) +--- +>>> a: number; +1 >^^^^ +2 > ^ +3 > ^^ +4 > ^^^^^^ +5 > ^ +1 > { + > +2 > a +3 > : +4 > number +5 > ; +1 >Emitted(2, 5) Source(2, 5) + SourceIndex(0) +2 >Emitted(2, 6) Source(2, 6) + SourceIndex(0) +3 >Emitted(2, 8) Source(2, 8) + SourceIndex(0) +4 >Emitted(2, 14) Source(2, 14) + SourceIndex(0) +5 >Emitted(2, 15) Source(2, 15) + SourceIndex(0) +--- +>>>} +1 >^ +2 > ^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > + >} +1 >Emitted(3, 2) Source(3, 2) + SourceIndex(0) +--- +>>>export interface Unused { +1-> +2 >^^^^^^ +3 > ^^^^^^^^^^^ +4 > ^^^^^^ +1-> + > +2 >export +3 > interface +4 > Unused +1->Emitted(4, 1) Source(4, 1) + SourceIndex(0) +2 >Emitted(4, 7) Source(4, 7) + SourceIndex(0) +3 >Emitted(4, 18) Source(4, 18) + SourceIndex(0) +4 >Emitted(4, 24) Source(4, 24) + SourceIndex(0) +--- +>>> unused: true; +1 >^^^^ +2 > ^^^^^^ +3 > ^^ +4 > ^^^^ +5 > ^ +1 > { + > +2 > unused +3 > : +4 > true +5 > ; +1 >Emitted(5, 5) Source(5, 5) + SourceIndex(0) +2 >Emitted(5, 11) Source(5, 11) + SourceIndex(0) +3 >Emitted(5, 13) Source(5, 13) + SourceIndex(0) +4 >Emitted(5, 17) Source(5, 17) + SourceIndex(0) +5 >Emitted(5, 18) Source(5, 18) + SourceIndex(0) +--- +>>>} +1 >^ +2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > + >} +1 >Emitted(6, 2) Source(6, 2) + SourceIndex(0) +--- +>>>//# sourceMappingURL=types.d.ts.map=================================================================== +JsFile: foo.d.ts +mapUrl: foo.d.ts.map +sourceRoot: +sources: foo.js +=================================================================== +------------------------------------------------------------------- +emittedFile:/foo.d.ts +sourceFile:foo.js +------------------------------------------------------------------- +>>>/** +1 > +2 >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > +1 >Emitted(1, 1) Source(1, 1) + SourceIndex(0) +--- +>>> * @import { Foo } from "./types" +>>> */ +1->^^^ +2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1->/** + > * @import { Foo } from "./types" + > */ +1->Emitted(3, 4) Source(3, 4) + SourceIndex(0) +--- +>>>import type { Foo } from "./types"; +1-> +2 >^^^^^^^ +3 > ^^^^^ +4 > ^^ +5 > ^^^ +6 > ^^ +7 > ^^^^^^ +8 > ^^^^^^^^^ +9 > ^ +1-> +2 >@import +3 > +4 > { +5 > Foo +6 > } +7 > from +8 > "./types" +9 > +1->Emitted(4, 1) Source(2, 4) + SourceIndex(0) +2 >Emitted(4, 8) Source(2, 12) + SourceIndex(0) +3 >Emitted(4, 13) Source(2, 12) + SourceIndex(0) +4 >Emitted(4, 15) Source(2, 14) + SourceIndex(0) +5 >Emitted(4, 18) Source(2, 17) + SourceIndex(0) +6 >Emitted(4, 20) Source(2, 19) + SourceIndex(0) +7 >Emitted(4, 26) Source(2, 25) + SourceIndex(0) +8 >Emitted(4, 35) Source(2, 34) + SourceIndex(0) +9 >Emitted(4, 36) Source(2, 34) + SourceIndex(0) +--- +>>>/** +1 > +2 >^^^^^^^^^^^^^^^^^^^^^^-> +1 > + > */ + > + > +1 >Emitted(5, 1) Source(5, 1) + SourceIndex(0) +--- +>>> * @param { Foo } foo +>>> */ +1->^^^ +2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1->/** + > * @param { Foo } foo + > */ +1->Emitted(7, 4) Source(7, 4) + SourceIndex(0) +--- +>>>declare function f(foo: Foo): void; +1-> +2 >^^^^^^^^^^^^^^^^^ +3 > ^ +4 > ^ +5 > ^^^ +6 > ^^ +7 > ^^^ +8 > ^^^^^^^^ +1-> + > +2 >function +3 > f +4 > ( +5 > foo +6 > +7 > Foo } foo + > */ + > function f(foo +8 > ) {} +1->Emitted(8, 1) Source(8, 1) + SourceIndex(0) +2 >Emitted(8, 18) Source(8, 10) + SourceIndex(0) +3 >Emitted(8, 19) Source(8, 11) + SourceIndex(0) +4 >Emitted(8, 20) Source(8, 12) + SourceIndex(0) +5 >Emitted(8, 23) Source(8, 15) + SourceIndex(0) +6 >Emitted(8, 25) Source(6, 13) + SourceIndex(0) +7 >Emitted(8, 28) Source(8, 15) + SourceIndex(0) +8 >Emitted(8, 36) Source(8, 19) + SourceIndex(0) +--- +>>>//# sourceMappingURL=foo.d.ts.map=================================================================== +JsFile: imports.d.ts +mapUrl: imports.d.ts.map +sourceRoot: +sources: imports.js +=================================================================== +------------------------------------------------------------------- +emittedFile:/imports.d.ts +sourceFile:imports.js +------------------------------------------------------------------- +>>>import type { Foo } from "./types"; +1 > +2 >^^^^^^^ +3 > ^^^^^ +4 > ^^ +5 > ^^^ +6 > ^^ +7 > ^^^^^^ +8 > ^^^^^^^^^ +9 > ^ +1 >/** + > * +2 >@import +3 > +4 > { +5 > Foo +6 > , Unused } +7 > from +8 > "./types" +9 > +1 >Emitted(1, 1) Source(2, 4) + SourceIndex(0) +2 >Emitted(1, 8) Source(2, 12) + SourceIndex(0) +3 >Emitted(1, 13) Source(2, 12) + SourceIndex(0) +4 >Emitted(1, 15) Source(2, 14) + SourceIndex(0) +5 >Emitted(1, 18) Source(2, 17) + SourceIndex(0) +6 >Emitted(1, 20) Source(2, 27) + SourceIndex(0) +7 >Emitted(1, 26) Source(2, 33) + SourceIndex(0) +8 >Emitted(1, 35) Source(2, 42) + SourceIndex(0) +9 >Emitted(1, 36) Source(2, 42) + SourceIndex(0) +--- +>>>/** +1 > +2 >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > +1 >Emitted(2, 1) Source(1, 1) + SourceIndex(0) +--- +>>> * @import { Foo, Unused } from "./types" +>>> */ +1->^^^ +2 > ^-> +1->/** + > * @import { Foo, Unused } from "./types" + > */ +1->Emitted(4, 4) Source(3, 4) + SourceIndex(0) +--- +>>>/** +1-> +2 >^^^^^^^^^^^^^^^^^^^^-> +1-> + > +1->Emitted(5, 1) Source(4, 1) + SourceIndex(0) +--- +>>> * @param {Foo} foo +>>> */ +1->^^^ +2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1->/** + > * @param {Foo} foo + > */ +1->Emitted(7, 4) Source(6, 4) + SourceIndex(0) +--- +>>>export declare function filtered(foo: Foo): Foo; +1-> +2 >^^^^^^^^^^^^^^^^^^^^^^^^ +3 > ^^^^^^^^ +4 > ^ +5 > ^^^ +6 > ^^ +7 > ^^^ +8 > ^^^^^^^ +1-> + > +2 >export function +3 > filtered +4 > ( +5 > foo +6 > +7 > Foo} foo + > */ + > export function filtered(foo +8 > ) { + > return foo; + > } +1->Emitted(8, 1) Source(7, 1) + SourceIndex(0) +2 >Emitted(8, 25) Source(7, 17) + SourceIndex(0) +3 >Emitted(8, 33) Source(7, 25) + SourceIndex(0) +4 >Emitted(8, 34) Source(7, 26) + SourceIndex(0) +5 >Emitted(8, 37) Source(7, 29) + SourceIndex(0) +6 >Emitted(8, 39) Source(5, 12) + SourceIndex(0) +7 >Emitted(8, 42) Source(7, 29) + SourceIndex(0) +8 >Emitted(8, 49) Source(9, 2) + SourceIndex(0) +--- +>>>import type * as types from "./types"; +1 > +2 >^^^^^^^ +3 > ^^^^^ +4 > ^^^^^ +5 > ^^^^^ +6 > ^^^^^^ +7 > ^^^^^^^^^ +8 > ^ +1 > + >/** + > * +2 >@import +3 > +4 > * as +5 > types +6 > from +7 > "./types" +8 > +1 >Emitted(9, 1) Source(11, 4) + SourceIndex(0) +2 >Emitted(9, 8) Source(11, 12) + SourceIndex(0) +3 >Emitted(9, 13) Source(11, 12) + SourceIndex(0) +4 >Emitted(9, 18) Source(11, 17) + SourceIndex(0) +5 >Emitted(9, 23) Source(11, 22) + SourceIndex(0) +6 >Emitted(9, 29) Source(11, 28) + SourceIndex(0) +7 >Emitted(9, 38) Source(11, 37) + SourceIndex(0) +8 >Emitted(9, 39) Source(11, 37) + SourceIndex(0) +--- +>>>/** +1 > +2 >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > +1 >Emitted(10, 1) Source(10, 1) + SourceIndex(0) +--- +>>> * @import * as types from "./types" +>>> */ +1->^^^ +2 > ^-> +1->/** + > * @import * as types from "./types" + > */ +1->Emitted(12, 4) Source(12, 4) + SourceIndex(0) +--- +>>>/** +1-> +2 >^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1-> + > +1->Emitted(13, 1) Source(13, 1) + SourceIndex(0) +--- +>>> * @param {types.Foo} foo +>>> */ +1->^^^ +2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1->/** + > * @param {types.Foo} foo + > */ +1->Emitted(15, 4) Source(15, 4) + SourceIndex(0) +--- +>>>export declare function namespace(foo: types.Foo): Foo; +1-> +2 >^^^^^^^^^^^^^^^^^^^^^^^^ +3 > ^^^^^^^^^ +4 > ^ +5 > ^^^ +6 > ^^ +7 > ^^^^^ +8 > ^ +9 > ^^^ +10> ^^^^^^^ +1-> + > +2 >export function +3 > namespace +4 > ( +5 > foo +6 > +7 > types +8 > . +9 > Foo} foo + > */ + > export function namespace(foo +10> ) { + > return foo; + > } +1->Emitted(16, 1) Source(16, 1) + SourceIndex(0) +2 >Emitted(16, 25) Source(16, 17) + SourceIndex(0) +3 >Emitted(16, 34) Source(16, 26) + SourceIndex(0) +4 >Emitted(16, 35) Source(16, 27) + SourceIndex(0) +5 >Emitted(16, 38) Source(16, 30) + SourceIndex(0) +6 >Emitted(16, 40) Source(14, 12) + SourceIndex(0) +7 >Emitted(16, 45) Source(14, 17) + SourceIndex(0) +8 >Emitted(16, 46) Source(14, 18) + SourceIndex(0) +9 >Emitted(16, 49) Source(16, 30) + SourceIndex(0) +10>Emitted(16, 56) Source(18, 2) + SourceIndex(0) +--- +>>>//# sourceMappingURL=imports.d.ts.map \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/importTag5.symbols b/tsc/testdata/baselines/reference/conformance/importTag5.symbols index 35242e6c8988e..9775067933615 100644 --- a/tsc/testdata/baselines/reference/conformance/importTag5.symbols +++ b/tsc/testdata/baselines/reference/conformance/importTag5.symbols @@ -7,6 +7,12 @@ export interface Foo { a: number; >a : Symbol(Foo.a, Decl(types.ts, 0, 22)) } +export interface Unused { +>Unused : Symbol(Unused, Decl(types.ts, 2, 1)) + + unused: true; +>unused : Symbol(Unused.unused, Decl(types.ts, 3, 25)) +} === /foo.js === /** @@ -20,3 +26,31 @@ function f(foo) {} >f : Symbol(f, Decl(foo.js, 0, 0)) >foo : Symbol(foo, Decl(foo.js, 7, 11)) +=== /imports.js === +/** + * @import { Foo, Unused } from "./types" + */ +/** + * @param {Foo} foo + */ +export function filtered(foo) { +>filtered : Symbol(filtered, Decl(imports.js, 0, 0)) +>foo : Symbol(foo, Decl(imports.js, 6, 25)) + + return foo; +>foo : Symbol(foo, Decl(imports.js, 6, 25)) +} +/** + * @import * as types from "./types" + */ +/** + * @param {types.Foo} foo + */ +export function namespace(foo) { +>namespace : Symbol(namespace, Decl(imports.js, 8, 1)) +>foo : Symbol(foo, Decl(imports.js, 15, 26)) + + return foo; +>foo : Symbol(foo, Decl(imports.js, 15, 26)) +} + diff --git a/tsc/testdata/baselines/reference/conformance/importTag5.types b/tsc/testdata/baselines/reference/conformance/importTag5.types index 7d9641be55328..c2ff4244e0694 100644 --- a/tsc/testdata/baselines/reference/conformance/importTag5.types +++ b/tsc/testdata/baselines/reference/conformance/importTag5.types @@ -5,6 +5,11 @@ export interface Foo { a: number; >a : number } +export interface Unused { + unused: true; +>unused : true +>true : true +} === /foo.js === /** @@ -18,3 +23,31 @@ function f(foo) {} >f : (foo: Foo) => void >foo : Foo +=== /imports.js === +/** + * @import { Foo, Unused } from "./types" + */ +/** + * @param {Foo} foo + */ +export function filtered(foo) { +>filtered : (foo: Foo) => Foo +>foo : Foo + + return foo; +>foo : Foo +} +/** + * @import * as types from "./types" + */ +/** + * @param {types.Foo} foo + */ +export function namespace(foo) { +>namespace : (foo: types.Foo) => Foo +>foo : Foo + + return foo; +>foo : Foo +} + diff --git a/tsc/testdata/tests/cases/conformance/jsdoc/importTag5.ts b/tsc/testdata/tests/cases/conformance/jsdoc/importTag5.ts index eb934954c4dba..f8f7836a2eb9c 100644 --- a/tsc/testdata/tests/cases/conformance/jsdoc/importTag5.ts +++ b/tsc/testdata/tests/cases/conformance/jsdoc/importTag5.ts @@ -3,11 +3,15 @@ // @allowJs: true // @declaration: true // @emitDeclarationOnly: true +// @declarationMap: true // @filename: /types.ts export interface Foo { a: number; } +export interface Unused { + unused: true; +} // @filename: /foo.js /** @@ -18,3 +22,23 @@ export interface Foo { * @param { Foo } foo */ function f(foo) {} + +// @filename: /imports.js +/** + * @import { Foo, Unused } from "./types" + */ +/** + * @param {Foo} foo + */ +export function filtered(foo) { + return foo; +} +/** + * @import * as types from "./types" + */ +/** + * @param {types.Foo} foo + */ +export function namespace(foo) { + return foo; +}