vendor tsgo
This commit is contained in:
135
tools/tsgo/internal/compiler/processingDiagnostic.go
Normal file
135
tools/tsgo/internal/compiler/processingDiagnostic.go
Normal file
@@ -0,0 +1,135 @@
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"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/tsoptions"
|
||||
"github.com/microsoft/typescript-go/internal/tspath"
|
||||
)
|
||||
|
||||
type processingDiagnosticKind int
|
||||
|
||||
const (
|
||||
processingDiagnosticKindUnknownReference processingDiagnosticKind = iota
|
||||
processingDiagnosticKindExplainingFileInclude
|
||||
)
|
||||
|
||||
type processingDiagnostic struct {
|
||||
kind processingDiagnosticKind
|
||||
data any
|
||||
}
|
||||
|
||||
func (d *processingDiagnostic) asFileIncludeReason() *FileIncludeReason {
|
||||
return d.data.(*FileIncludeReason)
|
||||
}
|
||||
|
||||
type includeExplainingDiagnostic struct {
|
||||
file tspath.Path
|
||||
diagnosticReason *FileIncludeReason
|
||||
message *diagnostics.Message
|
||||
args []any
|
||||
}
|
||||
|
||||
func (d *processingDiagnostic) asIncludeExplainingDiagnostic() *includeExplainingDiagnostic {
|
||||
return d.data.(*includeExplainingDiagnostic)
|
||||
}
|
||||
|
||||
func (d *processingDiagnostic) toDiagnostic(program *Program) *ast.Diagnostic {
|
||||
switch d.kind {
|
||||
case processingDiagnosticKindUnknownReference:
|
||||
ref := d.asFileIncludeReason()
|
||||
loc := ref.getReferencedLocation(program)
|
||||
switch ref.kind {
|
||||
case fileIncludeKindTypeReferenceDirective:
|
||||
return loc.diagnosticAt(diagnostics.Cannot_find_type_definition_file_for_0, loc.ref.FileName)
|
||||
case fileIncludeKindLibReferenceDirective:
|
||||
libName := tspath.ToFileNameLowerCase(loc.ref.FileName)
|
||||
unqualifiedLibName := strings.TrimSuffix(strings.TrimPrefix(libName, "lib."), ".d.ts")
|
||||
suggestion := core.GetSpellingSuggestionForStrings(unqualifiedLibName, slices.Values(tsoptions.Libs))
|
||||
return loc.diagnosticAt(core.IfElse(
|
||||
suggestion != "",
|
||||
diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1,
|
||||
diagnostics.Cannot_find_lib_definition_for_0,
|
||||
), libName, suggestion)
|
||||
default:
|
||||
panic("unknown include kind")
|
||||
}
|
||||
case processingDiagnosticKindExplainingFileInclude:
|
||||
return d.createDiagnosticExplainingFile(program)
|
||||
default:
|
||||
panic("unknown processingDiagnosticKind")
|
||||
}
|
||||
}
|
||||
|
||||
func (d *processingDiagnostic) createDiagnosticExplainingFile(program *Program) *ast.Diagnostic {
|
||||
diag := d.asIncludeExplainingDiagnostic()
|
||||
var includeDetails []*ast.Diagnostic
|
||||
var relatedInfo []*ast.Diagnostic
|
||||
var redirectInfo []*ast.Diagnostic
|
||||
var preferredLocation *FileIncludeReason
|
||||
var seenReasons collections.Set[*FileIncludeReason]
|
||||
if diag.diagnosticReason.isReferencedFile() && !program.includeProcessor.getReferenceLocation(diag.diagnosticReason, program).isSynthetic {
|
||||
preferredLocation = diag.diagnosticReason
|
||||
}
|
||||
|
||||
processRelatedInfo := func(includeReason *FileIncludeReason) {
|
||||
if preferredLocation == nil && includeReason.isReferencedFile() && !program.includeProcessor.getReferenceLocation(includeReason, program).isSynthetic {
|
||||
preferredLocation = includeReason
|
||||
} else if preferredLocation != includeReason {
|
||||
info := program.includeProcessor.getRelatedInfo(includeReason, program)
|
||||
if info != nil {
|
||||
relatedInfo = append(relatedInfo, info)
|
||||
}
|
||||
}
|
||||
}
|
||||
processInclude := func(includeReason *FileIncludeReason) {
|
||||
if !seenReasons.AddIfAbsent(includeReason) {
|
||||
return
|
||||
}
|
||||
includeDetails = append(includeDetails, includeReason.toDiagnostic(program, false))
|
||||
processRelatedInfo(includeReason)
|
||||
}
|
||||
|
||||
// !!! todo sheetal caching
|
||||
|
||||
if diag.file != "" {
|
||||
reasons := program.includeProcessor.fileIncludeReasons[diag.file]
|
||||
includeDetails = make([]*ast.Diagnostic, 0, len(reasons))
|
||||
for _, reason := range reasons {
|
||||
processInclude(reason)
|
||||
}
|
||||
redirectInfo = program.includeProcessor.explainRedirectAndImpliedFormat(program, diag.file, func(fileName string) string { return fileName })
|
||||
}
|
||||
if diag.diagnosticReason != nil {
|
||||
processInclude(diag.diagnosticReason)
|
||||
}
|
||||
var chain []*ast.Diagnostic
|
||||
if includeDetails != nil && (preferredLocation == nil || seenReasons.Len() != 1) {
|
||||
fileReason := ast.NewCompilerDiagnostic(diagnostics.The_file_is_in_the_program_because_Colon)
|
||||
fileReason.SetMessageChain(includeDetails)
|
||||
chain = []*ast.Diagnostic{fileReason}
|
||||
}
|
||||
if redirectInfo != nil {
|
||||
chain = append(chain, redirectInfo...)
|
||||
}
|
||||
|
||||
var result *ast.Diagnostic
|
||||
if preferredLocation != nil {
|
||||
result = program.includeProcessor.getReferenceLocation(preferredLocation, program).diagnosticAt(diag.message, diag.args...)
|
||||
}
|
||||
if result == nil {
|
||||
result = ast.NewCompilerDiagnostic(diag.message, diag.args...)
|
||||
}
|
||||
if chain != nil {
|
||||
result.SetMessageChain(chain)
|
||||
}
|
||||
if relatedInfo != nil {
|
||||
result.SetRelatedInfo(relatedInfo)
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user