2025-10-15 10:12:44 +03:00

55 lines
1.7 KiB
Go

package transformers
import (
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/binder"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/printer"
)
type chainedTransformer struct {
Transformer
components []*Transformer
}
func (ch *chainedTransformer) visit(node *ast.Node) *ast.Node {
if node.Kind != ast.KindSourceFile {
panic("Chained transform passed non-sourcefile initial node")
}
result := node.AsSourceFile()
for _, t := range ch.components {
result = t.TransformSourceFile(result)
}
return result.AsNode()
}
type TransformOptions struct {
Context *printer.EmitContext
CompilerOptions *core.CompilerOptions
Resolver binder.ReferenceResolver
EmitResolver printer.EmitResolver
GetEmitModuleFormatOfFile func(file ast.HasFileName) core.ModuleKind
}
type TransformerFactory = func(opt *TransformOptions) *Transformer
// Chains transforms in left-to-right order, running them one at a time in order (as opposed to interleaved at each node)
// - the resulting combined transform only operates on SourceFile nodes
func Chain(transforms ...TransformerFactory) TransformerFactory {
if len(transforms) < 2 {
if len(transforms) == 0 {
panic("Expected some number of transforms to chain, but got none")
}
return transforms[0]
}
return func(opt *TransformOptions) *Transformer {
constructed := make([]*Transformer, 0, len(transforms))
for _, t := range transforms {
// TODO: flatten nested chains?
constructed = append(constructed, t(opt))
}
ch := &chainedTransformer{components: constructed}
return ch.NewTransformer(ch.visit, opt.Context)
}
}