| 1631 | } |
| 1632 | |
| 1633 | func (p *Program) Emit(ctx context.Context, options EmitOptions) *EmitResult { |
| 1634 | if tr := p.opts.Tracing; tr != nil { |
| 1635 | defer tr.Push(tracing.PhaseEmit, "emit", nil, true)() |
| 1636 | } |
| 1637 | |
| 1638 | if options.EmitOnly != EmitOnlyForcedDts { |
| 1639 | result := HandleNoEmitOnError( |
| 1640 | ctx, |
| 1641 | p, |
| 1642 | options.TargetSourceFile, |
| 1643 | ) |
| 1644 | if result != nil || ctx.Err() != nil { |
| 1645 | return result |
| 1646 | } |
| 1647 | } |
| 1648 | |
| 1649 | newLine := p.Options().NewLine.GetNewLineCharacter() |
| 1650 | writerPool := &sync.Pool{ |
| 1651 | New: func() any { |
| 1652 | return printer.NewTextWriter(newLine, 0) |
| 1653 | }, |
| 1654 | } |
| 1655 | wg := core.NewWorkGroup(p.SingleThreaded()) |
| 1656 | var emitters []*emitter |
| 1657 | sourceFiles := p.getSourceFilesToEmit(options.TargetSourceFile, options.EmitOnly == EmitOnlyForcedDts) |
| 1658 | |
| 1659 | for _, sourceFile := range sourceFiles { |
| 1660 | emitter := &emitter{ |
| 1661 | writer: nil, |
| 1662 | sourceFile: sourceFile, |
| 1663 | emitOnly: options.EmitOnly, |
| 1664 | writeFile: options.WriteFile, |
| 1665 | tr: p.opts.Tracing, |
| 1666 | } |
| 1667 | emitters = append(emitters, emitter) |
| 1668 | wg.Queue(func() { |
| 1669 | host, done := newEmitHost(ctx, p, sourceFile) |
| 1670 | defer done() |
| 1671 | emitter.host = host |
| 1672 | |
| 1673 | // take an unused writer |
| 1674 | writer := writerPool.Get().(printer.EmitTextWriter) |
| 1675 | writer.Clear() |
| 1676 | |
| 1677 | // attach writer and perform emit |
| 1678 | emitter.writer = writer |
| 1679 | emitter.paths = outputpaths.GetOutputPathsFor(sourceFile, host.Options(), host, options.EmitOnly == EmitOnlyForcedDts) |
| 1680 | emitter.emit() |
| 1681 | emitter.writer = nil |
| 1682 | |
| 1683 | // put the writer back in the pool |
| 1684 | writerPool.Put(writer) |
| 1685 | }) |
| 1686 | } |
| 1687 | |
| 1688 | // wait for emit to complete |
| 1689 | wg.RunAndWait() |
| 1690 | |