vendor tsgo
This commit is contained in:
630
tools/tsgo/internal/execute/incremental/buildInfo.go
Normal file
630
tools/tsgo/internal/execute/incremental/buildInfo.go
Normal file
@@ -0,0 +1,630 @@
|
||||
package incremental
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/ast"
|
||||
"github.com/microsoft/typescript-go/internal/collections"
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/diagnostics"
|
||||
"github.com/microsoft/typescript-go/internal/json"
|
||||
"github.com/microsoft/typescript-go/internal/tsoptions"
|
||||
"github.com/microsoft/typescript-go/internal/tspath"
|
||||
)
|
||||
|
||||
type (
|
||||
BuildInfoFileId int
|
||||
BuildInfoFileIdListId int
|
||||
)
|
||||
|
||||
// buildInfoRoot is
|
||||
// - for incremental program buildinfo
|
||||
// - start and end of FileId for consecutive fileIds to be included as root
|
||||
// - start - single fileId that is root
|
||||
//
|
||||
// - for non incremental program buildinfo
|
||||
// - string that is the root file name
|
||||
type BuildInfoRoot struct {
|
||||
Start BuildInfoFileId
|
||||
End BuildInfoFileId
|
||||
NonIncremental string // Root of a non incremental program
|
||||
}
|
||||
|
||||
func (b *BuildInfoRoot) MarshalJSON() ([]byte, error) {
|
||||
if b.Start != 0 {
|
||||
if b.End != 0 {
|
||||
return json.Marshal([2]BuildInfoFileId{b.Start, b.End})
|
||||
} else {
|
||||
return json.Marshal(b.Start)
|
||||
}
|
||||
} else {
|
||||
return json.Marshal(b.NonIncremental)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BuildInfoRoot) UnmarshalJSON(data []byte) error {
|
||||
var startAndEnd *[2]int
|
||||
if err := json.Unmarshal(data, &startAndEnd); err != nil {
|
||||
var start int
|
||||
if err := json.Unmarshal(data, &start); err != nil {
|
||||
var name string
|
||||
if err := json.Unmarshal(data, &name); err != nil {
|
||||
return fmt.Errorf("invalid BuildInfoRoot: %s", data)
|
||||
}
|
||||
*b = BuildInfoRoot{
|
||||
NonIncremental: name,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
*b = BuildInfoRoot{
|
||||
Start: BuildInfoFileId(start),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
*b = BuildInfoRoot{
|
||||
Start: BuildInfoFileId(startAndEnd[0]),
|
||||
End: BuildInfoFileId(startAndEnd[1]),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type buildInfoFileInfoNoSignature struct {
|
||||
Version string `json:"version,omitzero"`
|
||||
NoSignature bool `json:"noSignature,omitzero"`
|
||||
AffectsGlobalScope bool `json:"affectsGlobalScope,omitzero"`
|
||||
ImpliedNodeFormat core.ResolutionMode `json:"impliedNodeFormat,omitzero"`
|
||||
}
|
||||
|
||||
// Signature is
|
||||
// - undefined if FileInfo.version === FileInfo.signature
|
||||
// - string actual signature
|
||||
type buildInfoFileInfoWithSignature struct {
|
||||
Version string `json:"version,omitzero"`
|
||||
Signature string `json:"signature,omitzero"`
|
||||
AffectsGlobalScope bool `json:"affectsGlobalScope,omitzero"`
|
||||
ImpliedNodeFormat core.ResolutionMode `json:"impliedNodeFormat,omitzero"`
|
||||
}
|
||||
|
||||
type BuildInfoFileInfo struct {
|
||||
signature string
|
||||
noSignature *buildInfoFileInfoNoSignature
|
||||
fileInfo *buildInfoFileInfoWithSignature
|
||||
}
|
||||
|
||||
func newBuildInfoFileInfo(fileInfo *FileInfo) *BuildInfoFileInfo {
|
||||
if fileInfo.version == fileInfo.signature {
|
||||
if !fileInfo.affectsGlobalScope && fileInfo.impliedNodeFormat == core.ResolutionModeCommonJS {
|
||||
return &BuildInfoFileInfo{signature: fileInfo.signature}
|
||||
}
|
||||
} else if fileInfo.signature == "" {
|
||||
return &BuildInfoFileInfo{noSignature: &buildInfoFileInfoNoSignature{
|
||||
Version: fileInfo.version,
|
||||
NoSignature: true,
|
||||
AffectsGlobalScope: fileInfo.affectsGlobalScope,
|
||||
ImpliedNodeFormat: fileInfo.impliedNodeFormat,
|
||||
}}
|
||||
}
|
||||
return &BuildInfoFileInfo{fileInfo: &buildInfoFileInfoWithSignature{
|
||||
Version: fileInfo.version,
|
||||
Signature: core.IfElse(fileInfo.signature == fileInfo.version, "", fileInfo.signature),
|
||||
AffectsGlobalScope: fileInfo.affectsGlobalScope,
|
||||
ImpliedNodeFormat: fileInfo.impliedNodeFormat,
|
||||
}}
|
||||
}
|
||||
|
||||
func (b *BuildInfoFileInfo) GetFileInfo() *FileInfo {
|
||||
if b == nil {
|
||||
return nil
|
||||
}
|
||||
if b.signature != "" {
|
||||
return &FileInfo{
|
||||
version: b.signature,
|
||||
signature: b.signature,
|
||||
impliedNodeFormat: core.ResolutionModeCommonJS,
|
||||
}
|
||||
}
|
||||
if b.noSignature != nil {
|
||||
return &FileInfo{
|
||||
version: b.noSignature.Version,
|
||||
affectsGlobalScope: b.noSignature.AffectsGlobalScope,
|
||||
impliedNodeFormat: b.noSignature.ImpliedNodeFormat,
|
||||
}
|
||||
}
|
||||
return &FileInfo{
|
||||
version: b.fileInfo.Version,
|
||||
signature: core.IfElse(b.fileInfo.Signature == "", b.fileInfo.Version, b.fileInfo.Signature),
|
||||
affectsGlobalScope: b.fileInfo.AffectsGlobalScope,
|
||||
impliedNodeFormat: b.fileInfo.ImpliedNodeFormat,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BuildInfoFileInfo) HasSignature() bool {
|
||||
return b.signature != ""
|
||||
}
|
||||
|
||||
func (b *BuildInfoFileInfo) MarshalJSON() ([]byte, error) {
|
||||
if b.signature != "" {
|
||||
return json.Marshal(b.signature)
|
||||
}
|
||||
if b.noSignature != nil {
|
||||
return json.Marshal(b.noSignature)
|
||||
}
|
||||
return json.Marshal(b.fileInfo)
|
||||
}
|
||||
|
||||
func (b *BuildInfoFileInfo) UnmarshalJSON(data []byte) error {
|
||||
var vSignature string
|
||||
if err := json.Unmarshal(data, &vSignature); err != nil {
|
||||
var noSignature buildInfoFileInfoNoSignature
|
||||
if err := json.Unmarshal(data, &noSignature); err != nil || !noSignature.NoSignature {
|
||||
var fileInfo buildInfoFileInfoWithSignature
|
||||
if err := json.Unmarshal(data, &fileInfo); err != nil {
|
||||
return fmt.Errorf("invalid BuildInfoFileInfo: %s", data)
|
||||
}
|
||||
*b = BuildInfoFileInfo{fileInfo: &fileInfo}
|
||||
return nil
|
||||
}
|
||||
*b = BuildInfoFileInfo{noSignature: &noSignature}
|
||||
return nil
|
||||
}
|
||||
*b = BuildInfoFileInfo{signature: vSignature}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BuildInfoReferenceMapEntry struct {
|
||||
FileId BuildInfoFileId
|
||||
FileIdListId BuildInfoFileIdListId
|
||||
}
|
||||
|
||||
func (b *BuildInfoReferenceMapEntry) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal([2]int{int(b.FileId), int(b.FileIdListId)})
|
||||
}
|
||||
|
||||
func (b *BuildInfoReferenceMapEntry) UnmarshalJSON(data []byte) error {
|
||||
var v *[2]int
|
||||
if err := json.Unmarshal(data, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
*b = BuildInfoReferenceMapEntry{
|
||||
FileId: BuildInfoFileId(v[0]),
|
||||
FileIdListId: BuildInfoFileIdListId(v[1]),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BuildInfoDiagnostic struct {
|
||||
// BuildInfoFileId if it is for a File thats other than its stored for
|
||||
File BuildInfoFileId `json:"file,omitzero"`
|
||||
NoFile bool `json:"noFile,omitzero"`
|
||||
Pos int `json:"pos,omitzero"`
|
||||
End int `json:"end,omitzero"`
|
||||
Code int32 `json:"code,omitzero"`
|
||||
Category diagnostics.Category `json:"category,omitzero"`
|
||||
MessageKey diagnostics.Key `json:"messageKey,omitzero"`
|
||||
MessageArgs []string `json:"messageArgs,omitzero"`
|
||||
MessageChain []*BuildInfoDiagnostic `json:"messageChain,omitzero"`
|
||||
RelatedInformation []*BuildInfoDiagnostic `json:"relatedInformation,omitzero"`
|
||||
ReportsUnnecessary bool `json:"reportsUnnecessary,omitzero"`
|
||||
ReportsDeprecated bool `json:"reportsDeprecated,omitzero"`
|
||||
SkippedOnNoEmit bool `json:"skippedOnNoEmit,omitzero"`
|
||||
RepopulateInfo *BuildInfoRepopulateInfo `json:"repopulateInfo,omitzero"`
|
||||
}
|
||||
|
||||
type BuildInfoRepopulateInfo struct {
|
||||
Kind ast.RepopulateDiagnosticKind `json:"kind"`
|
||||
ModuleReference string `json:"moduleReference,omitzero"`
|
||||
Mode core.ResolutionMode `json:"mode,omitzero"`
|
||||
PackageName string `json:"packageName,omitzero"`
|
||||
}
|
||||
|
||||
type BuildInfoDiagnosticsOfFile struct {
|
||||
FileId BuildInfoFileId
|
||||
Diagnostics []*BuildInfoDiagnostic
|
||||
}
|
||||
|
||||
func (b *BuildInfoDiagnosticsOfFile) MarshalJSON() ([]byte, error) {
|
||||
fileIdAndDiagnostics := make([]any, 0, 2)
|
||||
fileIdAndDiagnostics = append(fileIdAndDiagnostics, b.FileId)
|
||||
fileIdAndDiagnostics = append(fileIdAndDiagnostics, b.Diagnostics)
|
||||
return json.Marshal(fileIdAndDiagnostics)
|
||||
}
|
||||
|
||||
func (b *BuildInfoDiagnosticsOfFile) UnmarshalJSON(data []byte) error {
|
||||
var fileIdAndDiagnostics []json.Value
|
||||
if err := json.Unmarshal(data, &fileIdAndDiagnostics); err != nil {
|
||||
return fmt.Errorf("invalid BuildInfoDiagnosticsOfFile: %s", data)
|
||||
}
|
||||
if len(fileIdAndDiagnostics) != 2 {
|
||||
return fmt.Errorf("invalid BuildInfoDiagnosticsOfFile: expected 2 elements, got %d", len(fileIdAndDiagnostics))
|
||||
}
|
||||
var fileId BuildInfoFileId
|
||||
if err := json.Unmarshal(fileIdAndDiagnostics[0], &fileId); err != nil {
|
||||
return fmt.Errorf("invalid fileId in BuildInfoDiagnosticsOfFile: %w", err)
|
||||
}
|
||||
|
||||
var diagnostics []*BuildInfoDiagnostic
|
||||
if err := json.Unmarshal(fileIdAndDiagnostics[1], &diagnostics); err != nil {
|
||||
return fmt.Errorf("invalid diagnostics in BuildInfoDiagnosticsOfFile: %w", err)
|
||||
}
|
||||
*b = BuildInfoDiagnosticsOfFile{
|
||||
FileId: fileId,
|
||||
Diagnostics: diagnostics,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BuildInfoSemanticDiagnostic struct {
|
||||
FileId BuildInfoFileId // File is not in changedSet and still doesnt have cached diagnostics
|
||||
Diagnostics *BuildInfoDiagnosticsOfFile // Diagnostics for file
|
||||
}
|
||||
|
||||
func (b *BuildInfoSemanticDiagnostic) MarshalJSON() ([]byte, error) {
|
||||
if b.FileId != 0 {
|
||||
return json.Marshal(b.FileId)
|
||||
}
|
||||
return json.Marshal(b.Diagnostics)
|
||||
}
|
||||
|
||||
func (b *BuildInfoSemanticDiagnostic) UnmarshalJSON(data []byte) error {
|
||||
var fileId BuildInfoFileId
|
||||
if err := json.Unmarshal(data, &fileId); err != nil {
|
||||
var diagnostics BuildInfoDiagnosticsOfFile
|
||||
if err := json.Unmarshal(data, &diagnostics); err != nil {
|
||||
return fmt.Errorf("invalid BuildInfoSemanticDiagnostic: %s", data)
|
||||
}
|
||||
*b = BuildInfoSemanticDiagnostic{
|
||||
Diagnostics: &diagnostics,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
*b = BuildInfoSemanticDiagnostic{
|
||||
FileId: fileId,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// fileId if pending emit is same as what compilerOptions suggest
|
||||
// [fileId] if pending emit is only dts file emit
|
||||
// [fileId, emitKind] if any other type emit is pending
|
||||
type BuildInfoFilePendingEmit struct {
|
||||
FileId BuildInfoFileId
|
||||
EmitKind FileEmitKind
|
||||
}
|
||||
|
||||
func (b *BuildInfoFilePendingEmit) MarshalJSON() ([]byte, error) {
|
||||
if b.EmitKind == 0 {
|
||||
return json.Marshal(b.FileId)
|
||||
}
|
||||
if b.EmitKind == FileEmitKindDts {
|
||||
fileListIds := []BuildInfoFileId{b.FileId}
|
||||
return json.Marshal(fileListIds)
|
||||
}
|
||||
fileAndEmitKind := []int{int(b.FileId), int(b.EmitKind)}
|
||||
return json.Marshal(fileAndEmitKind)
|
||||
}
|
||||
|
||||
func (b *BuildInfoFilePendingEmit) UnmarshalJSON(data []byte) error {
|
||||
var fileId BuildInfoFileId
|
||||
if err := json.Unmarshal(data, &fileId); err != nil {
|
||||
var intTuple []int
|
||||
if err := json.Unmarshal(data, &intTuple); err != nil || len(intTuple) == 0 {
|
||||
return fmt.Errorf("invalid BuildInfoFilePendingEmit: %s", data)
|
||||
}
|
||||
switch len(intTuple) {
|
||||
case 1:
|
||||
*b = BuildInfoFilePendingEmit{
|
||||
FileId: BuildInfoFileId(intTuple[0]),
|
||||
EmitKind: FileEmitKindDts,
|
||||
}
|
||||
return nil
|
||||
case 2:
|
||||
*b = BuildInfoFilePendingEmit{
|
||||
FileId: BuildInfoFileId(intTuple[0]),
|
||||
EmitKind: FileEmitKind(intTuple[1]),
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("invalid BuildInfoFilePendingEmit: expected 1 or 2 integers, got %d", len(intTuple))
|
||||
}
|
||||
}
|
||||
*b = BuildInfoFilePendingEmit{
|
||||
FileId: fileId,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// [fileId, signature] if different from file's signature
|
||||
// fileId if file wasnt emitted
|
||||
type BuildInfoEmitSignature struct {
|
||||
FileId BuildInfoFileId
|
||||
Signature string // Signature if it is different from file's Signature
|
||||
DiffersOnlyInDtsMap bool // true if signature is different only in dtsMap value
|
||||
DiffersInOptions bool // true if signature is different in options used to emit file
|
||||
}
|
||||
|
||||
func (b *BuildInfoEmitSignature) noEmitSignature() bool {
|
||||
return b.Signature == "" && !b.DiffersOnlyInDtsMap && !b.DiffersInOptions
|
||||
}
|
||||
|
||||
func (b *BuildInfoEmitSignature) toEmitSignature(path tspath.Path, emitSignatures *collections.SyncMap[tspath.Path, *emitSignature]) *emitSignature {
|
||||
var signature string
|
||||
var signatureWithDifferentOptions []string
|
||||
if b.DiffersOnlyInDtsMap {
|
||||
signatureWithDifferentOptions = make([]string, 0, 1)
|
||||
info, _ := emitSignatures.Load(path)
|
||||
signatureWithDifferentOptions = append(signatureWithDifferentOptions, info.signature)
|
||||
} else if b.DiffersInOptions {
|
||||
signatureWithDifferentOptions = make([]string, 0, 1)
|
||||
signatureWithDifferentOptions = append(signatureWithDifferentOptions, b.Signature)
|
||||
} else {
|
||||
signature = b.Signature
|
||||
}
|
||||
return &emitSignature{
|
||||
signature: signature,
|
||||
signatureWithDifferentOptions: signatureWithDifferentOptions,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BuildInfoEmitSignature) MarshalJSON() ([]byte, error) {
|
||||
if b.noEmitSignature() {
|
||||
return json.Marshal(b.FileId)
|
||||
}
|
||||
fileIdAndSignature := make([]any, 2)
|
||||
fileIdAndSignature[0] = b.FileId
|
||||
var signature any
|
||||
if b.DiffersOnlyInDtsMap {
|
||||
signature = []string{}
|
||||
} else if b.DiffersInOptions {
|
||||
signature = []string{b.Signature}
|
||||
} else {
|
||||
signature = b.Signature
|
||||
}
|
||||
fileIdAndSignature[1] = signature
|
||||
return json.Marshal(fileIdAndSignature)
|
||||
}
|
||||
|
||||
func (b *BuildInfoEmitSignature) UnmarshalJSON(data []byte) error {
|
||||
var fileId BuildInfoFileId
|
||||
if err := json.Unmarshal(data, &fileId); err != nil {
|
||||
var fileIdAndSignature []any
|
||||
if err := json.Unmarshal(data, &fileIdAndSignature); err != nil {
|
||||
return fmt.Errorf("invalid BuildInfoEmitSignature: %s", data)
|
||||
}
|
||||
if len(fileIdAndSignature) != 2 {
|
||||
return fmt.Errorf("invalid BuildInfoEmitSignature: expected 2 elements, got %d", len(fileIdAndSignature))
|
||||
}
|
||||
var fileId BuildInfoFileId
|
||||
if id, ok := fileIdAndSignature[0].(float64); !ok {
|
||||
return fmt.Errorf("invalid fileId in BuildInfoEmitSignature: expected float64, got %T", fileIdAndSignature[0])
|
||||
} else {
|
||||
fileId = BuildInfoFileId(id)
|
||||
}
|
||||
var signature string
|
||||
var differsOnlyInDtsMap, differsInOptions bool
|
||||
if signatureV, ok := fileIdAndSignature[1].(string); !ok {
|
||||
if signatureList, ok := fileIdAndSignature[1].([]any); !ok {
|
||||
return fmt.Errorf("invalid signature in BuildInfoEmitSignature: expected string or []string, got %T", fileIdAndSignature[1])
|
||||
} else {
|
||||
switch len(signatureList) {
|
||||
case 0:
|
||||
differsOnlyInDtsMap = true
|
||||
case 1:
|
||||
if sig, ok := signatureList[0].(string); !ok {
|
||||
return fmt.Errorf("invalid signature in BuildInfoEmitSignature: expected string, got %T", signatureList[0])
|
||||
} else {
|
||||
signature = sig
|
||||
differsInOptions = true
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid signature in BuildInfoEmitSignature: expected string or []string with 0 or 1 element, got %d elements", len(signatureList))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
signature = signatureV
|
||||
}
|
||||
*b = BuildInfoEmitSignature{
|
||||
FileId: fileId,
|
||||
Signature: signature,
|
||||
DiffersOnlyInDtsMap: differsOnlyInDtsMap,
|
||||
DiffersInOptions: differsInOptions,
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
*b = BuildInfoEmitSignature{
|
||||
FileId: fileId,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BuildInfoResolvedRoot struct {
|
||||
Resolved BuildInfoFileId
|
||||
Root BuildInfoFileId
|
||||
}
|
||||
|
||||
func (b *BuildInfoResolvedRoot) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal([2]BuildInfoFileId{b.Resolved, b.Root})
|
||||
}
|
||||
|
||||
func (b *BuildInfoResolvedRoot) UnmarshalJSON(data []byte) error {
|
||||
var resolvedAndRoot [2]int
|
||||
if err := json.Unmarshal(data, &resolvedAndRoot); err != nil {
|
||||
return fmt.Errorf("invalid BuildInfoResolvedRoot: %s", data)
|
||||
}
|
||||
*b = BuildInfoResolvedRoot{
|
||||
Resolved: BuildInfoFileId(resolvedAndRoot[0]),
|
||||
Root: BuildInfoFileId(resolvedAndRoot[1]),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BuildInfo struct {
|
||||
Version string `json:"version,omitzero"`
|
||||
|
||||
// Common between incremental and tsc -b buildinfo for non incremental programs
|
||||
Errors bool `json:"errors,omitzero"`
|
||||
CheckPending bool `json:"checkPending,omitzero"`
|
||||
Root []*BuildInfoRoot `json:"root,omitzero"`
|
||||
PackageJsons []string `json:"packageJsons,omitzero"`
|
||||
MissingPackageJsons []string `json:"missingPackageJsons,omitzero"`
|
||||
|
||||
// IncrementalProgram info
|
||||
FileNames []string `json:"fileNames,omitzero"`
|
||||
FileInfos []*BuildInfoFileInfo `json:"fileInfos,omitzero"`
|
||||
FileIdsList [][]BuildInfoFileId `json:"fileIdsList,omitzero"`
|
||||
Options *collections.OrderedMap[string, any] `json:"options,omitzero"`
|
||||
ReferencedMap []*BuildInfoReferenceMapEntry `json:"referencedMap,omitzero"`
|
||||
SemanticDiagnosticsPerFile []*BuildInfoSemanticDiagnostic `json:"semanticDiagnosticsPerFile,omitzero"`
|
||||
EmitDiagnosticsPerFile []*BuildInfoDiagnosticsOfFile `json:"emitDiagnosticsPerFile,omitzero"`
|
||||
ChangeFileSet []BuildInfoFileId `json:"changeFileSet,omitzero"`
|
||||
AffectedFilesPendingEmit []*BuildInfoFilePendingEmit `json:"affectedFilesPendingEmit,omitzero"`
|
||||
LatestChangedDtsFile string `json:"latestChangedDtsFile,omitzero"` // Because this is only output file in the program, we dont need fileId to deduplicate name
|
||||
EmitSignatures []*BuildInfoEmitSignature `json:"emitSignatures,omitzero"`
|
||||
ResolvedRoot []*BuildInfoResolvedRoot `json:"resolvedRoot,omitzero"`
|
||||
|
||||
// NonIncrementalProgram info
|
||||
SemanticErrors bool `json:"semanticErrors,omitzero"`
|
||||
}
|
||||
|
||||
func (b *BuildInfo) IsValidVersion() bool {
|
||||
return b.Version == core.Version()
|
||||
}
|
||||
|
||||
func (b *BuildInfo) IsIncremental() bool {
|
||||
return b != nil && len(b.FileNames) != 0
|
||||
}
|
||||
|
||||
func IsBuildInfoFileNameDefaultLibrary(fileName string) bool {
|
||||
return !tspath.PathIsRelative(fileName) && !tspath.PathIsAbsolute(fileName)
|
||||
}
|
||||
|
||||
func (b *BuildInfo) fileName(fileId BuildInfoFileId) string {
|
||||
if fileId < 1 || int(fileId) > len(b.FileNames) {
|
||||
return ""
|
||||
}
|
||||
return b.FileNames[fileId-1]
|
||||
}
|
||||
|
||||
func (b *BuildInfo) fileInfo(fileId BuildInfoFileId) *BuildInfoFileInfo {
|
||||
if fileId < 1 || int(fileId) > len(b.FileInfos) {
|
||||
return nil
|
||||
}
|
||||
return b.FileInfos[fileId-1]
|
||||
}
|
||||
|
||||
func (b *BuildInfo) GetCompilerOptions(buildInfoDirectory string) *core.CompilerOptions {
|
||||
options := &core.CompilerOptions{}
|
||||
for option, value := range b.Options.Entries() {
|
||||
if buildInfoDirectory != "" {
|
||||
result, ok := tsoptions.ConvertOptionToAbsolutePath(option, value, tsoptions.CommandLineCompilerOptionsMap, buildInfoDirectory)
|
||||
if ok {
|
||||
tsoptions.ParseCompilerOptions(option, result, options)
|
||||
continue
|
||||
}
|
||||
}
|
||||
tsoptions.ParseCompilerOptions(option, value, options)
|
||||
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
func (b *BuildInfo) IsEmitPending(resolved *tsoptions.ParsedCommandLine, buildInfoDirectory string) bool {
|
||||
// Some of the emit files like source map or dts etc are not yet done
|
||||
if !resolved.CompilerOptions().NoEmit.IsTrue() || resolved.CompilerOptions().GetEmitDeclarations() {
|
||||
pendingEmit := getPendingEmitKindWithOptions(resolved.CompilerOptions(), b.GetCompilerOptions(buildInfoDirectory))
|
||||
if resolved.CompilerOptions().NoEmit.IsTrue() {
|
||||
pendingEmit &= FileEmitKindDtsErrors
|
||||
}
|
||||
return pendingEmit != 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *BuildInfo) GetPackageJsons(buildInfoDirectory string) iter.Seq[string] {
|
||||
return getNormalizedPaths(b.PackageJsons, buildInfoDirectory)
|
||||
}
|
||||
|
||||
func (b *BuildInfo) GetMissingPackageJsons(buildInfoDirectory string) iter.Seq[string] {
|
||||
return getNormalizedPaths(b.MissingPackageJsons, buildInfoDirectory)
|
||||
}
|
||||
|
||||
func getNormalizedPaths(paths []string, buildInfoDirectory string) iter.Seq[string] {
|
||||
return func(yield func(string) bool) {
|
||||
for _, path := range paths {
|
||||
if !yield(tspath.GetNormalizedAbsolutePath(path, buildInfoDirectory)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BuildInfo) GetBuildInfoRootInfoReader(buildInfoDirectory string, comparePathOptions tspath.ComparePathsOptions) *BuildInfoRootInfoReader {
|
||||
resolvedRootFileInfos := make(map[tspath.Path]*BuildInfoFileInfo, len(b.FileNames))
|
||||
// Roots of the File
|
||||
rootToResolved := collections.NewOrderedMapWithSizeHint[tspath.Path, tspath.Path](len(b.FileNames))
|
||||
resolvedToRoot := make(map[tspath.Path]tspath.Path, len(b.ResolvedRoot))
|
||||
toPath := func(fileName string) tspath.Path {
|
||||
return tspath.ToPath(fileName, buildInfoDirectory, comparePathOptions.UseCaseSensitiveFileNames)
|
||||
}
|
||||
|
||||
// Create map from resolvedRoot to Root
|
||||
for _, resolved := range b.ResolvedRoot {
|
||||
resolvedRoot := b.fileName(resolved.Resolved)
|
||||
root := b.fileName(resolved.Root)
|
||||
if resolvedRoot != "" && root != "" {
|
||||
resolvedToRoot[toPath(resolvedRoot)] = toPath(root)
|
||||
}
|
||||
}
|
||||
|
||||
addRoot := func(resolvedRoot string, fileInfo *BuildInfoFileInfo) {
|
||||
if resolvedRoot == "" {
|
||||
return
|
||||
}
|
||||
resolvedRootPath := toPath(resolvedRoot)
|
||||
if rootPath, ok := resolvedToRoot[resolvedRootPath]; ok {
|
||||
rootToResolved.Set(rootPath, resolvedRootPath)
|
||||
} else {
|
||||
rootToResolved.Set(resolvedRootPath, resolvedRootPath)
|
||||
}
|
||||
if fileInfo != nil {
|
||||
resolvedRootFileInfos[resolvedRootPath] = fileInfo
|
||||
}
|
||||
}
|
||||
|
||||
for _, root := range b.Root {
|
||||
if root.NonIncremental != "" {
|
||||
addRoot(root.NonIncremental, nil)
|
||||
} else if root.End == 0 {
|
||||
addRoot(b.fileName(root.Start), b.fileInfo(root.Start))
|
||||
} else {
|
||||
for i := root.Start; i <= root.End; i++ {
|
||||
addRoot(b.fileName(i), b.fileInfo(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &BuildInfoRootInfoReader{
|
||||
resolvedRootFileInfos: resolvedRootFileInfos,
|
||||
rootToResolved: rootToResolved,
|
||||
}
|
||||
}
|
||||
|
||||
type BuildInfoRootInfoReader struct {
|
||||
resolvedRootFileInfos map[tspath.Path]*BuildInfoFileInfo
|
||||
rootToResolved *collections.OrderedMap[tspath.Path, tspath.Path]
|
||||
}
|
||||
|
||||
func (b *BuildInfoRootInfoReader) GetBuildInfoFileInfo(inputFilePath tspath.Path) (*BuildInfoFileInfo, tspath.Path) {
|
||||
if info, ok := b.resolvedRootFileInfos[inputFilePath]; ok {
|
||||
return info, inputFilePath
|
||||
}
|
||||
if resolved, ok := b.rootToResolved.Get(inputFilePath); ok {
|
||||
return b.resolvedRootFileInfos[resolved], resolved
|
||||
}
|
||||
return nil, ""
|
||||
}
|
||||
|
||||
func (b *BuildInfoRootInfoReader) Roots() iter.Seq[tspath.Path] {
|
||||
return b.rootToResolved.Keys()
|
||||
}
|
||||
Reference in New Issue
Block a user