2025-10-15 10:12:44 +03:00

167 lines
5.0 KiB
Go

package tsc
import (
"fmt"
"io"
"strings"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/diagnosticwriter"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
)
func getFormatOptsOfSys(sys System) *diagnosticwriter.FormattingOptions {
return &diagnosticwriter.FormattingOptions{
NewLine: "\n",
ComparePathsOptions: tspath.ComparePathsOptions{
CurrentDirectory: sys.GetCurrentDirectory(),
UseCaseSensitiveFileNames: sys.FS().UseCaseSensitiveFileNames(),
},
}
}
type DiagnosticReporter = func(*ast.Diagnostic)
func QuietDiagnosticReporter(diagnostic *ast.Diagnostic) {}
func CreateDiagnosticReporter(sys System, w io.Writer, options *core.CompilerOptions) DiagnosticReporter {
if options.Quiet.IsTrue() {
return QuietDiagnosticReporter
}
formatOpts := getFormatOptsOfSys(sys)
if shouldBePretty(sys, options) {
return func(diagnostic *ast.Diagnostic) {
diagnosticwriter.FormatDiagnosticWithColorAndContext(w, diagnostic, formatOpts)
fmt.Fprint(w, formatOpts.NewLine)
}
}
return func(diagnostic *ast.Diagnostic) {
diagnosticwriter.WriteFormatDiagnostic(w, diagnostic, formatOpts)
}
}
func defaultIsPretty(sys System) bool {
return sys.WriteOutputIsTTY() && sys.GetEnvironmentVariable("NO_COLOR") == ""
}
func shouldBePretty(sys System, options *core.CompilerOptions) bool {
if options == nil || options.Pretty.IsUnknown() {
return defaultIsPretty(sys)
}
return options.Pretty.IsTrue()
}
type colors struct {
showColors bool
isWindows bool
isWindowsTerminal bool
isVSCode bool
supportsRicherColors bool
}
func createColors(sys System) *colors {
if !defaultIsPretty(sys) {
return &colors{showColors: false}
}
os := sys.GetEnvironmentVariable("OS")
isWindows := strings.Contains(strings.ToLower(os), "windows")
isWindowsTerminal := sys.GetEnvironmentVariable("WT_SESSION") != ""
isVSCode := sys.GetEnvironmentVariable("TERM_PROGRAM") == "vscode"
supportsRicherColors := sys.GetEnvironmentVariable("COLORTERM") == "truecolor" || sys.GetEnvironmentVariable("TERM") == "xterm-256color"
return &colors{
showColors: true,
isWindows: isWindows,
isWindowsTerminal: isWindowsTerminal,
isVSCode: isVSCode,
supportsRicherColors: supportsRicherColors,
}
}
func (c *colors) bold(str string) string {
if !c.showColors {
return str
}
return "\x1b[1m" + str + "\x1b[22m"
}
func (c *colors) blue(str string) string {
if !c.showColors {
return str
}
// Effectively Powershell and Command prompt users use cyan instead
// of blue because the default theme doesn't show blue with enough contrast.
if c.isWindows && !c.isWindowsTerminal && !c.isVSCode {
return c.brightWhite(str)
}
return "\x1b[94m" + str + "\x1b[39m"
}
func (c *colors) blueBackground(str string) string {
if !c.showColors {
return str
}
if c.supportsRicherColors {
return "\x1B[48;5;68m" + str + "\x1B[39;49m"
} else {
return "\x1b[44m" + str + "\x1B[39;49m"
}
}
func (c *colors) brightWhite(str string) string {
if !c.showColors {
return str
}
return "\x1b[97m" + str + "\x1b[39m"
}
type DiagnosticsReporter = func(diagnostics []*ast.Diagnostic)
func QuietDiagnosticsReporter(diagnostics []*ast.Diagnostic) {}
func CreateReportErrorSummary(sys System, options *core.CompilerOptions) DiagnosticsReporter {
if shouldBePretty(sys, options) {
formatOpts := getFormatOptsOfSys(sys)
return func(diagnostics []*ast.Diagnostic) {
diagnosticwriter.WriteErrorSummaryText(sys.Writer(), diagnostics, formatOpts)
}
}
return QuietDiagnosticsReporter
}
func CreateBuilderStatusReporter(sys System, w io.Writer, options *core.CompilerOptions, testing CommandLineTesting) DiagnosticReporter {
if options.Quiet.IsTrue() {
return QuietDiagnosticReporter
}
formatOpts := getFormatOptsOfSys(sys)
writeStatus := core.IfElse(shouldBePretty(sys, options), diagnosticwriter.FormatDiagnosticsStatusWithColorAndTime, diagnosticwriter.FormatDiagnosticsStatusAndTime)
return func(diagnostic *ast.Diagnostic) {
if testing != nil {
testing.OnBuildStatusReportStart(w)
defer testing.OnBuildStatusReportEnd(w)
}
writeStatus(w, sys.Now().Format("03:04:05 PM"), diagnostic, formatOpts)
fmt.Fprint(w, formatOpts.NewLine, formatOpts.NewLine)
}
}
func CreateWatchStatusReporter(sys System, options *core.CompilerOptions, testing CommandLineTesting) DiagnosticReporter {
formatOpts := getFormatOptsOfSys(sys)
writeStatus := core.IfElse(shouldBePretty(sys, options), diagnosticwriter.FormatDiagnosticsStatusWithColorAndTime, diagnosticwriter.FormatDiagnosticsStatusAndTime)
return func(diagnostic *ast.Diagnostic) {
writer := sys.Writer()
if testing != nil {
testing.OnWatchStatusReportStart()
defer testing.OnWatchStatusReportEnd()
}
diagnosticwriter.TryClearScreen(writer, diagnostic, options)
writeStatus(writer, sys.Now().Format("03:04:05 PM"), diagnostic, formatOpts)
fmt.Fprint(writer, formatOpts.NewLine, formatOpts.NewLine)
}
}