Skip to content

Commit 08bc24d

Browse files
authored
Port baseline diagnostics tests (#2097)
1 parent d7d7aa4 commit 08bc24d

File tree

62 files changed

+1318
-91
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1318
-91
lines changed

internal/diagnosticwriter/diagnosticwriter.go

Lines changed: 123 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,87 @@ import (
1616
"github.com/microsoft/typescript-go/internal/tspath"
1717
)
1818

19+
type FileLike interface {
20+
FileName() string
21+
Text() string
22+
ECMALineMap() []core.TextPos
23+
}
24+
25+
// Diagnostic interface abstracts over ast.Diagnostic and LSP diagnostics
26+
type Diagnostic interface {
27+
File() FileLike
28+
Pos() int
29+
End() int
30+
Len() int
31+
Code() int32
32+
Category() diagnostics.Category
33+
Message() string
34+
MessageChain() []Diagnostic
35+
RelatedInformation() []Diagnostic
36+
}
37+
38+
// ASTDiagnostic wraps ast.Diagnostic to implement the Diagnostic interface
39+
type ASTDiagnostic struct {
40+
*ast.Diagnostic
41+
}
42+
43+
func (d *ASTDiagnostic) RelatedInformation() []Diagnostic {
44+
related := d.Diagnostic.RelatedInformation()
45+
result := make([]Diagnostic, len(related))
46+
for i, r := range related {
47+
result[i] = &ASTDiagnostic{r}
48+
}
49+
return result
50+
}
51+
52+
func (d *ASTDiagnostic) File() FileLike {
53+
if file := d.Diagnostic.File(); file != nil {
54+
return file
55+
}
56+
return nil
57+
}
58+
59+
func (d *ASTDiagnostic) MessageChain() []Diagnostic {
60+
chain := d.Diagnostic.MessageChain()
61+
result := make([]Diagnostic, len(chain))
62+
for i, c := range chain {
63+
result[i] = &ASTDiagnostic{c}
64+
}
65+
return result
66+
}
67+
68+
func WrapASTDiagnostic(d *ast.Diagnostic) *ASTDiagnostic {
69+
return &ASTDiagnostic{d}
70+
}
71+
72+
func WrapASTDiagnostics(diags []*ast.Diagnostic) []*ASTDiagnostic {
73+
result := make([]*ASTDiagnostic, len(diags))
74+
for i, d := range diags {
75+
result[i] = WrapASTDiagnostic(d)
76+
}
77+
return result
78+
}
79+
80+
func FromASTDiagnostics(diags []*ast.Diagnostic) []Diagnostic {
81+
result := make([]Diagnostic, len(diags))
82+
for i, d := range diags {
83+
result[i] = WrapASTDiagnostic(d)
84+
}
85+
return result
86+
}
87+
88+
func ToDiagnostics[T Diagnostic](diags []T) []Diagnostic {
89+
result := make([]Diagnostic, len(diags))
90+
for i, d := range diags {
91+
result[i] = d
92+
}
93+
return result
94+
}
95+
96+
func CompareASTDiagnostics(a, b *ASTDiagnostic) int {
97+
return ast.CompareDiagnostics(a.Diagnostic, b.Diagnostic)
98+
}
99+
19100
type FormattingOptions struct {
20101
tspath.ComparePathsOptions
21102
NewLine string
@@ -36,7 +117,7 @@ const (
36117
ellipsis = "..."
37118
)
38119

39-
func FormatDiagnosticsWithColorAndContext(output io.Writer, diags []*ast.Diagnostic, formatOpts *FormattingOptions) {
120+
func FormatDiagnosticsWithColorAndContext(output io.Writer, diags []Diagnostic, formatOpts *FormattingOptions) {
40121
if len(diags) == 0 {
41122
return
42123
}
@@ -48,10 +129,10 @@ func FormatDiagnosticsWithColorAndContext(output io.Writer, diags []*ast.Diagnos
48129
}
49130
}
50131

51-
func FormatDiagnosticWithColorAndContext(output io.Writer, diagnostic *ast.Diagnostic, formatOpts *FormattingOptions) {
132+
func FormatDiagnosticWithColorAndContext(output io.Writer, diagnostic Diagnostic, formatOpts *FormattingOptions) {
52133
if diagnostic.File() != nil {
53134
file := diagnostic.File()
54-
pos := diagnostic.Loc().Pos()
135+
pos := diagnostic.Pos()
55136
WriteLocation(output, file, pos, formatOpts, writeWithStyleAndReset)
56137
fmt.Fprint(output, " - ")
57138
}
@@ -83,7 +164,7 @@ func FormatDiagnosticWithColorAndContext(output io.Writer, diagnostic *ast.Diagn
83164
}
84165
}
85166

86-
func writeCodeSnippet(writer io.Writer, sourceFile *ast.SourceFile, start int, length int, squiggleColor string, indent string, formatOpts *FormattingOptions) {
167+
func writeCodeSnippet(writer io.Writer, sourceFile FileLike, start int, length int, squiggleColor string, indent string, formatOpts *FormattingOptions) {
87168
firstLine, firstLineChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, start)
88169
lastLine, lastLineChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, start+length)
89170
if length == 0 {
@@ -118,7 +199,7 @@ func writeCodeSnippet(writer io.Writer, sourceFile *ast.SourceFile, start int, l
118199
if i < lastLineOfFile {
119200
lineEnd = scanner.GetECMAPositionOfLineAndCharacter(sourceFile, i+1, 0)
120201
} else {
121-
lineEnd = sourceFile.Loc.End()
202+
lineEnd = len(sourceFile.Text())
122203
}
123204

124205
lineContent := strings.TrimRightFunc(sourceFile.Text()[lineStart:lineEnd], unicode.IsSpace) // trim from end
@@ -167,21 +248,25 @@ func writeCodeSnippet(writer io.Writer, sourceFile *ast.SourceFile, start int, l
167248
}
168249
}
169250

170-
func FlattenDiagnosticMessage(d *ast.Diagnostic, newLine string) string {
251+
func FlattenDiagnosticMessage(d Diagnostic, newLine string) string {
171252
var output strings.Builder
172253
WriteFlattenedDiagnosticMessage(&output, d, newLine)
173254
return output.String()
174255
}
175256

176-
func WriteFlattenedDiagnosticMessage(writer io.Writer, diagnostic *ast.Diagnostic, newline string) {
257+
func WriteFlattenedASTDiagnosticMessage(writer io.Writer, diagnostic *ast.Diagnostic, newline string) {
258+
WriteFlattenedDiagnosticMessage(writer, WrapASTDiagnostic(diagnostic), newline)
259+
}
260+
261+
func WriteFlattenedDiagnosticMessage(writer io.Writer, diagnostic Diagnostic, newline string) {
177262
fmt.Fprint(writer, diagnostic.Message())
178263

179264
for _, chain := range diagnostic.MessageChain() {
180265
flattenDiagnosticMessageChain(writer, chain, newline, 1 /*level*/)
181266
}
182267
}
183268

184-
func flattenDiagnosticMessageChain(writer io.Writer, chain *ast.Diagnostic, newLine string, level int) {
269+
func flattenDiagnosticMessageChain(writer io.Writer, chain Diagnostic, newLine string, level int) {
185270
fmt.Fprint(writer, newLine)
186271
for range level {
187272
fmt.Fprint(writer, " ")
@@ -215,7 +300,7 @@ func writeWithStyleAndReset(output io.Writer, text string, formatStyle string) {
215300
fmt.Fprint(output, resetEscapeSequence)
216301
}
217302

218-
func WriteLocation(output io.Writer, file *ast.SourceFile, pos int, formatOpts *FormattingOptions, writeWithStyleAndReset FormattedWriter) {
303+
func WriteLocation(output io.Writer, file FileLike, pos int, formatOpts *FormattingOptions, writeWithStyleAndReset FormattedWriter) {
219304
firstLine, firstChar := scanner.GetECMALineAndCharacterOfPosition(file, pos)
220305
var relativeFileName string
221306
if formatOpts != nil {
@@ -235,12 +320,12 @@ func WriteLocation(output io.Writer, file *ast.SourceFile, pos int, formatOpts *
235320

236321
type ErrorSummary struct {
237322
TotalErrorCount int
238-
GlobalErrors []*ast.Diagnostic
239-
ErrorsByFiles map[*ast.SourceFile][]*ast.Diagnostic
240-
SortedFileList []*ast.SourceFile
323+
GlobalErrors []Diagnostic
324+
ErrorsByFile map[FileLike][]Diagnostic
325+
SortedFiles []FileLike
241326
}
242327

243-
func WriteErrorSummaryText(output io.Writer, allDiagnostics []*ast.Diagnostic, formatOpts *FormattingOptions) {
328+
func WriteErrorSummaryText(output io.Writer, allDiagnostics []Diagnostic, formatOpts *FormattingOptions) {
244329
// Roughly corresponds to 'getErrorSummaryText' from watch.ts
245330

246331
errorSummary := getErrorSummary(allDiagnostics)
@@ -249,12 +334,12 @@ func WriteErrorSummaryText(output io.Writer, allDiagnostics []*ast.Diagnostic, f
249334
return
250335
}
251336

252-
firstFile := &ast.SourceFile{}
253-
if len(errorSummary.SortedFileList) > 0 {
254-
firstFile = errorSummary.SortedFileList[0]
337+
var firstFile FileLike
338+
if len(errorSummary.SortedFiles) > 0 {
339+
firstFile = errorSummary.SortedFiles[0]
255340
}
256-
firstFileName := prettyPathForFileError(firstFile, errorSummary.ErrorsByFiles[firstFile], formatOpts)
257-
numErroringFiles := len(errorSummary.ErrorsByFiles)
341+
firstFileName := prettyPathForFileError(firstFile, errorSummary.ErrorsByFile[firstFile], formatOpts)
342+
numErroringFiles := len(errorSummary.ErrorsByFile)
258343

259344
var message string
260345
if totalErrorCount == 1 {
@@ -287,10 +372,10 @@ func WriteErrorSummaryText(output io.Writer, allDiagnostics []*ast.Diagnostic, f
287372
}
288373
}
289374

290-
func getErrorSummary(diags []*ast.Diagnostic) *ErrorSummary {
375+
func getErrorSummary(diags []Diagnostic) *ErrorSummary {
291376
var totalErrorCount int
292-
var globalErrors []*ast.Diagnostic
293-
var errorsByFiles map[*ast.SourceFile][]*ast.Diagnostic
377+
var globalErrors []Diagnostic
378+
var errorsByFile map[FileLike][]Diagnostic
294379

295380
for _, diagnostic := range diags {
296381
if diagnostic.Category() != diagnostics.CategoryError {
@@ -301,32 +386,32 @@ func getErrorSummary(diags []*ast.Diagnostic) *ErrorSummary {
301386
if diagnostic.File() == nil {
302387
globalErrors = append(globalErrors, diagnostic)
303388
} else {
304-
if errorsByFiles == nil {
305-
errorsByFiles = make(map[*ast.SourceFile][]*ast.Diagnostic)
389+
if errorsByFile == nil {
390+
errorsByFile = make(map[FileLike][]Diagnostic)
306391
}
307-
errorsByFiles[diagnostic.File()] = append(errorsByFiles[diagnostic.File()], diagnostic)
392+
errorsByFile[diagnostic.File()] = append(errorsByFile[diagnostic.File()], diagnostic)
308393
}
309394
}
310395

311396
// !!!
312397
// Need an ordered map here, but sorting for consistency.
313-
sortedFileList := slices.SortedFunc(maps.Keys(errorsByFiles), func(a, b *ast.SourceFile) int {
398+
sortedFiles := slices.SortedFunc(maps.Keys(errorsByFile), func(a, b FileLike) int {
314399
return strings.Compare(a.FileName(), b.FileName())
315400
})
316401

317402
return &ErrorSummary{
318403
TotalErrorCount: totalErrorCount,
319404
GlobalErrors: globalErrors,
320-
ErrorsByFiles: errorsByFiles,
321-
SortedFileList: sortedFileList,
405+
ErrorsByFile: errorsByFile,
406+
SortedFiles: sortedFiles,
322407
}
323408
}
324409

325410
func writeTabularErrorsDisplay(output io.Writer, errorSummary *ErrorSummary, formatOpts *FormattingOptions) {
326-
sortedFiles := errorSummary.SortedFileList
411+
sortedFiles := errorSummary.SortedFiles
327412

328413
maxErrors := 0
329-
for _, errorsForFile := range errorSummary.ErrorsByFiles {
414+
for _, errorsForFile := range errorSummary.ErrorsByFile {
330415
maxErrors = max(maxErrors, len(errorsForFile))
331416
}
332417

@@ -344,7 +429,7 @@ func writeTabularErrorsDisplay(output io.Writer, errorSummary *ErrorSummary, for
344429
fmt.Fprint(output, formatOpts.NewLine)
345430

346431
for _, file := range sortedFiles {
347-
fileErrors := errorSummary.ErrorsByFiles[file]
432+
fileErrors := errorSummary.ErrorsByFile[file]
348433
errorCount := len(fileErrors)
349434

350435
fmt.Fprintf(output, "%*d ", leftPaddingGoal, errorCount)
@@ -353,11 +438,11 @@ func writeTabularErrorsDisplay(output io.Writer, errorSummary *ErrorSummary, for
353438
}
354439
}
355440

356-
func prettyPathForFileError(file *ast.SourceFile, fileErrors []*ast.Diagnostic, formatOpts *FormattingOptions) string {
441+
func prettyPathForFileError(file FileLike, fileErrors []Diagnostic, formatOpts *FormattingOptions) string {
357442
if file == nil || len(fileErrors) == 0 {
358443
return ""
359444
}
360-
line := scanner.GetECMALineOfPosition(file, fileErrors[0].Loc().Pos())
445+
line := scanner.GetECMALineOfPosition(file, fileErrors[0].Pos())
361446
fileName := file.FileName()
362447
if tspath.PathIsAbsolute(fileName) && tspath.PathIsAbsolute(formatOpts.CurrentDirectory) {
363448
fileName = tspath.ConvertToRelativePath(file.FileName(), formatOpts.ComparePathsOptions)
@@ -370,15 +455,15 @@ func prettyPathForFileError(file *ast.SourceFile, fileErrors []*ast.Diagnostic,
370455
)
371456
}
372457

373-
func WriteFormatDiagnostics(output io.Writer, diagnostics []*ast.Diagnostic, formatOpts *FormattingOptions) {
458+
func WriteFormatDiagnostics(output io.Writer, diagnostics []Diagnostic, formatOpts *FormattingOptions) {
374459
for _, diagnostic := range diagnostics {
375460
WriteFormatDiagnostic(output, diagnostic, formatOpts)
376461
}
377462
}
378463

379-
func WriteFormatDiagnostic(output io.Writer, diagnostic *ast.Diagnostic, formatOpts *FormattingOptions) {
464+
func WriteFormatDiagnostic(output io.Writer, diagnostic Diagnostic, formatOpts *FormattingOptions) {
380465
if diagnostic.File() != nil {
381-
line, character := scanner.GetECMALineAndCharacterOfPosition(diagnostic.File(), diagnostic.Loc().Pos())
466+
line, character := scanner.GetECMALineAndCharacterOfPosition(diagnostic.File(), diagnostic.Pos())
382467
fileName := diagnostic.File().FileName()
383468
relativeFileName := tspath.ConvertToRelativePath(fileName, formatOpts.ComparePathsOptions)
384469
fmt.Fprintf(output, "%s(%d,%d): ", relativeFileName, line+1, character+1)
@@ -389,14 +474,14 @@ func WriteFormatDiagnostic(output io.Writer, diagnostic *ast.Diagnostic, formatO
389474
fmt.Fprint(output, formatOpts.NewLine)
390475
}
391476

392-
func FormatDiagnosticsStatusWithColorAndTime(output io.Writer, time string, diag *ast.Diagnostic, formatOpts *FormattingOptions) {
477+
func FormatDiagnosticsStatusWithColorAndTime(output io.Writer, time string, diag Diagnostic, formatOpts *FormattingOptions) {
393478
fmt.Fprint(output, "[")
394479
writeWithStyleAndReset(output, time, foregroundColorEscapeGrey)
395480
fmt.Fprint(output, "] ")
396481
WriteFlattenedDiagnosticMessage(output, diag, formatOpts.NewLine)
397482
}
398483

399-
func FormatDiagnosticsStatusAndTime(output io.Writer, time string, diag *ast.Diagnostic, formatOpts *FormattingOptions) {
484+
func FormatDiagnosticsStatusAndTime(output io.Writer, time string, diag Diagnostic, formatOpts *FormattingOptions) {
400485
fmt.Fprint(output, time, " - ")
401486
WriteFlattenedDiagnosticMessage(output, diag, formatOpts.NewLine)
402487
}
@@ -406,7 +491,7 @@ var ScreenStartingCodes = []int32{
406491
diagnostics.File_change_detected_Starting_incremental_compilation.Code(),
407492
}
408493

409-
func TryClearScreen(output io.Writer, diag *ast.Diagnostic, options *core.CompilerOptions) bool {
494+
func TryClearScreen(output io.Writer, diag Diagnostic, options *core.CompilerOptions) bool {
410495
if !options.PreserveWatchOutput.IsTrue() &&
411496
!options.ExtendedDiagnostics.IsTrue() &&
412497
!options.Diagnostics.IsTrue() &&

internal/execute/tsc/diagnostics.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ func CreateDiagnosticReporter(sys System, w io.Writer, options *core.CompilerOpt
3232
formatOpts := getFormatOptsOfSys(sys)
3333
if shouldBePretty(sys, options) {
3434
return func(diagnostic *ast.Diagnostic) {
35-
diagnosticwriter.FormatDiagnosticWithColorAndContext(w, diagnostic, formatOpts)
35+
diagnosticwriter.FormatDiagnosticWithColorAndContext(w, diagnosticwriter.WrapASTDiagnostic(diagnostic), formatOpts)
3636
fmt.Fprint(w, formatOpts.NewLine)
3737
}
3838
}
3939
return func(diagnostic *ast.Diagnostic) {
40-
diagnosticwriter.WriteFormatDiagnostic(w, diagnostic, formatOpts)
40+
diagnosticwriter.WriteFormatDiagnostic(w, diagnosticwriter.WrapASTDiagnostic(diagnostic), formatOpts)
4141
}
4242
}
4343

@@ -127,7 +127,7 @@ func CreateReportErrorSummary(sys System, options *core.CompilerOptions) Diagnos
127127
if shouldBePretty(sys, options) {
128128
formatOpts := getFormatOptsOfSys(sys)
129129
return func(diagnostics []*ast.Diagnostic) {
130-
diagnosticwriter.WriteErrorSummaryText(sys.Writer(), diagnostics, formatOpts)
130+
diagnosticwriter.WriteErrorSummaryText(sys.Writer(), diagnosticwriter.FromASTDiagnostics(diagnostics), formatOpts)
131131
}
132132
}
133133
return QuietDiagnosticsReporter
@@ -141,11 +141,12 @@ func CreateBuilderStatusReporter(sys System, w io.Writer, options *core.Compiler
141141
formatOpts := getFormatOptsOfSys(sys)
142142
writeStatus := core.IfElse(shouldBePretty(sys, options), diagnosticwriter.FormatDiagnosticsStatusWithColorAndTime, diagnosticwriter.FormatDiagnosticsStatusAndTime)
143143
return func(diagnostic *ast.Diagnostic) {
144+
writerDiagnostic := diagnosticwriter.WrapASTDiagnostic(diagnostic)
144145
if testing != nil {
145146
testing.OnBuildStatusReportStart(w)
146147
defer testing.OnBuildStatusReportEnd(w)
147148
}
148-
writeStatus(w, sys.Now().Format("03:04:05 PM"), diagnostic, formatOpts)
149+
writeStatus(w, sys.Now().Format("03:04:05 PM"), writerDiagnostic, formatOpts)
149150
fmt.Fprint(w, formatOpts.NewLine, formatOpts.NewLine)
150151
}
151152
}
@@ -154,13 +155,14 @@ func CreateWatchStatusReporter(sys System, options *core.CompilerOptions, testin
154155
formatOpts := getFormatOptsOfSys(sys)
155156
writeStatus := core.IfElse(shouldBePretty(sys, options), diagnosticwriter.FormatDiagnosticsStatusWithColorAndTime, diagnosticwriter.FormatDiagnosticsStatusAndTime)
156157
return func(diagnostic *ast.Diagnostic) {
158+
writerDiagnostic := diagnosticwriter.WrapASTDiagnostic(diagnostic)
157159
writer := sys.Writer()
158160
if testing != nil {
159161
testing.OnWatchStatusReportStart()
160162
defer testing.OnWatchStatusReportEnd()
161163
}
162-
diagnosticwriter.TryClearScreen(writer, diagnostic, options)
163-
writeStatus(writer, sys.Now().Format("03:04:05 PM"), diagnostic, formatOpts)
164+
diagnosticwriter.TryClearScreen(writer, writerDiagnostic, options)
165+
writeStatus(writer, sys.Now().Format("03:04:05 PM"), writerDiagnostic, formatOpts)
164166
fmt.Fprint(writer, formatOpts.NewLine, formatOpts.NewLine)
165167
}
166168
}

0 commit comments

Comments
 (0)