@@ -11,6 +11,8 @@ import (
11
11
"github.com/microsoft/typescript-go/internal/compiler/module"
12
12
"github.com/microsoft/typescript-go/internal/core"
13
13
"github.com/microsoft/typescript-go/internal/parser"
14
+ "github.com/microsoft/typescript-go/internal/printer"
15
+ "github.com/microsoft/typescript-go/internal/sourcemap"
14
16
"github.com/microsoft/typescript-go/internal/tspath"
15
17
"github.com/microsoft/typescript-go/internal/vfs"
16
18
)
@@ -660,3 +662,79 @@ func getCommonSourceDirectory(options *core.CompilerOptions, files []string, cur
660
662
661
663
return commonSourceDirectory
662
664
}
665
+
666
+ type EmitOptions struct {
667
+ TargetSourceFile * ast.SourceFile // Single file to emit. If `nil`, emits all files
668
+ forceDtsEmit bool
669
+ }
670
+
671
+ type EmitResult struct {
672
+ EmitSkipped bool
673
+ Diagnostics []* ast.Diagnostic // Contains declaration emit diagnostics
674
+ EmittedFiles []string // Array of files the compiler wrote to disk
675
+ sourceMaps []* sourceMapEmitResult // Array of sourceMapData if compiler emitted sourcemaps
676
+ }
677
+
678
+ type sourceMapEmitResult struct {
679
+ inputSourceFileNames []string // Input source file (which one can use on program to get the file), 1:1 mapping with the sourceMap.sources list
680
+ sourceMap * sourcemap.RawSourceMap
681
+ }
682
+
683
+ func (p * Program ) Emit (options * EmitOptions ) * EmitResult {
684
+ // !!! performance measurement
685
+
686
+ host := & emitHost {program : p }
687
+
688
+ writerPool := & sync.Pool {
689
+ New : func () any {
690
+ return printer .NewTextWriter (host .Options ().NewLine .GetNewLineCharacter ())
691
+ },
692
+ }
693
+ wg := core .NewWorkGroup (p .programOptions .SingleThreaded )
694
+
695
+ var emitters []* emitter
696
+ sourceFiles := getSourceFilesToEmit (host , options .TargetSourceFile , options .forceDtsEmit )
697
+ for _ , sourceFile := range sourceFiles {
698
+ emitter := & emitter {
699
+ host : host ,
700
+ emittedFilesList : nil ,
701
+ sourceMapDataList : nil ,
702
+ writer : nil ,
703
+ sourceFile : sourceFile ,
704
+ }
705
+ emitters = append (emitters , emitter )
706
+ wg .Run (func () {
707
+ // take an unused writer
708
+ writer := writerPool .Get ().(printer.EmitTextWriter )
709
+ writer .Clear ()
710
+
711
+ // attach writer and perform emit
712
+ emitter .writer = writer
713
+ emitter .paths = getOutputPathsFor (sourceFile , host , options .forceDtsEmit )
714
+ emitter .emit ()
715
+ emitter .writer = nil
716
+
717
+ // put the writer back in the pool
718
+ writerPool .Put (writer )
719
+ })
720
+ }
721
+
722
+ // wait for emit to complete
723
+ wg .Wait ()
724
+
725
+ // collect results from emit, preserving input order
726
+ result := & EmitResult {}
727
+ for _ , emitter := range emitters {
728
+ if emitter .emitSkipped {
729
+ result .EmitSkipped = true
730
+ }
731
+ result .Diagnostics = append (result .Diagnostics , emitter .emitterDiagnostics .GetDiagnostics ()... )
732
+ if emitter .emittedFilesList != nil {
733
+ result .EmittedFiles = append (result .EmittedFiles , emitter .emittedFilesList ... )
734
+ }
735
+ if emitter .sourceMapDataList != nil {
736
+ result .sourceMaps = append (result .sourceMaps , emitter .sourceMapDataList ... )
737
+ }
738
+ }
739
+ return result
740
+ }
0 commit comments