123 lines
4.2 KiB
Go
123 lines
4.2 KiB
Go
package build
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/microsoft/typescript-go/internal/ast"
|
|
"github.com/microsoft/typescript-go/internal/collections"
|
|
"github.com/microsoft/typescript-go/internal/compiler"
|
|
"github.com/microsoft/typescript-go/internal/diagnostics"
|
|
"github.com/microsoft/typescript-go/internal/execute/incremental"
|
|
"github.com/microsoft/typescript-go/internal/execute/tsc"
|
|
"github.com/microsoft/typescript-go/internal/tsoptions"
|
|
"github.com/microsoft/typescript-go/internal/tspath"
|
|
"github.com/microsoft/typescript-go/internal/vfs"
|
|
)
|
|
|
|
type host struct {
|
|
orchestrator *Orchestrator
|
|
host compiler.CompilerHost
|
|
|
|
// Caches that last only for build cycle and then cleared out
|
|
extendedConfigCache tsc.ExtendedConfigCache
|
|
sourceFiles parseCache[ast.SourceFileParseOptions, *ast.SourceFile]
|
|
configTimes collections.SyncMap[tspath.Path, time.Duration]
|
|
|
|
// caches that stay as long as they are needed
|
|
resolvedReferences parseCache[tspath.Path, *tsoptions.ParsedCommandLine]
|
|
mTimes *collections.SyncMap[tspath.Path, time.Time]
|
|
}
|
|
|
|
var (
|
|
_ compiler.CompilerHost = (*host)(nil)
|
|
_ incremental.BuildInfoReader = (*host)(nil)
|
|
_ incremental.Host = (*host)(nil)
|
|
)
|
|
|
|
func (h *host) FS() vfs.FS {
|
|
return h.host.FS()
|
|
}
|
|
|
|
func (h *host) DefaultLibraryPath() string {
|
|
return h.host.DefaultLibraryPath()
|
|
}
|
|
|
|
func (h *host) GetCurrentDirectory() string {
|
|
return h.host.GetCurrentDirectory()
|
|
}
|
|
|
|
func (h *host) Trace(msg *diagnostics.Message, args ...any) {
|
|
panic("build.Orchestrator.host does not support tracing, use a different host for tracing")
|
|
}
|
|
|
|
func (h *host) GetSourceFile(opts ast.SourceFileParseOptions) *ast.SourceFile {
|
|
if tspath.IsDeclarationFileName(opts.FileName) || tspath.FileExtensionIs(opts.FileName, tspath.ExtensionJson) {
|
|
// Cache dts and json files as they will be reused
|
|
return h.sourceFiles.loadOrStore(opts, h.host.GetSourceFile, false /* allowZero */)
|
|
}
|
|
return h.host.GetSourceFile(opts)
|
|
}
|
|
|
|
func (h *host) GetResolvedProjectReference(fileName string, path tspath.Path) *tsoptions.ParsedCommandLine {
|
|
return h.resolvedReferences.loadOrStore(path, func(path tspath.Path) *tsoptions.ParsedCommandLine {
|
|
configStart := h.orchestrator.opts.Sys.Now()
|
|
// Wrap command line options in "compilerOptions" key to match tsconfig.json structure
|
|
var commandLineRaw *collections.OrderedMap[string, any]
|
|
if raw, ok := h.orchestrator.opts.Command.Raw.(*collections.OrderedMap[string, any]); ok {
|
|
wrapped := &collections.OrderedMap[string, any]{}
|
|
wrapped.Set("compilerOptions", raw)
|
|
commandLineRaw = wrapped
|
|
}
|
|
commandLine, _ := tsoptions.GetParsedCommandLineOfConfigFilePath(fileName, path, h.orchestrator.opts.Command.CompilerOptions, commandLineRaw, h, &h.extendedConfigCache)
|
|
configTime := h.orchestrator.opts.Sys.Now().Sub(configStart)
|
|
h.configTimes.Store(path, configTime)
|
|
return commandLine
|
|
}, true /* allowZero */)
|
|
}
|
|
|
|
func (h *host) ReadBuildInfo(config *tsoptions.ParsedCommandLine) *incremental.BuildInfo {
|
|
configPath := h.orchestrator.toPath(config.ConfigName())
|
|
task := h.orchestrator.getTask(configPath)
|
|
buildInfo, _ := task.loadOrStoreBuildInfo(h.orchestrator, h.orchestrator.toPath(config.ConfigName()), config.GetBuildInfoFileName())
|
|
return buildInfo
|
|
}
|
|
|
|
func (h *host) GetMTime(file string) time.Time {
|
|
return h.loadOrStoreMTime(file, nil, true)
|
|
}
|
|
|
|
func (h *host) SetMTime(file string, mTime time.Time) error {
|
|
return h.FS().Chtimes(file, time.Time{}, mTime)
|
|
}
|
|
|
|
func (h *host) loadOrStoreMTime(file string, oldCache *collections.SyncMap[tspath.Path, time.Time], store bool) time.Time {
|
|
path := h.orchestrator.toPath(file)
|
|
if existing, loaded := h.mTimes.Load(path); loaded {
|
|
return existing
|
|
}
|
|
var found bool
|
|
var mTime time.Time
|
|
if oldCache != nil {
|
|
mTime, found = oldCache.Load(path)
|
|
}
|
|
if !found {
|
|
mTime = incremental.GetMTime(h.host, file)
|
|
}
|
|
if store {
|
|
mTime, _ = h.mTimes.LoadOrStore(path, mTime)
|
|
}
|
|
return mTime
|
|
}
|
|
|
|
func (h *host) storeMTime(file string, mTime time.Time) {
|
|
path := h.orchestrator.toPath(file)
|
|
h.mTimes.Store(path, mTime)
|
|
}
|
|
|
|
func (h *host) storeMTimeFromOldCache(file string, oldCache *collections.SyncMap[tspath.Path, time.Time]) {
|
|
path := h.orchestrator.toPath(file)
|
|
if mTime, found := oldCache.Load(path); found {
|
|
h.mTimes.Store(path, mTime)
|
|
}
|
|
}
|