diff --git a/internal/diagnosticwriter/diagnosticwriter.go b/internal/diagnosticwriter/diagnosticwriter.go index df29debe0a..9609aa3789 100644 --- a/internal/diagnosticwriter/diagnosticwriter.go +++ b/internal/diagnosticwriter/diagnosticwriter.go @@ -16,6 +16,87 @@ import ( "github.com/microsoft/typescript-go/internal/tspath" ) +type FileLike interface { + FileName() string + Text() string + ECMALineMap() []core.TextPos +} + +// Diagnostic interface abstracts over ast.Diagnostic and LSP diagnostics +type Diagnostic interface { + File() FileLike + Pos() int + End() int + Len() int + Code() int32 + Category() diagnostics.Category + Message() string + MessageChain() []Diagnostic + RelatedInformation() []Diagnostic +} + +// ASTDiagnostic wraps ast.Diagnostic to implement the Diagnostic interface +type ASTDiagnostic struct { + *ast.Diagnostic +} + +func (d *ASTDiagnostic) RelatedInformation() []Diagnostic { + related := d.Diagnostic.RelatedInformation() + result := make([]Diagnostic, len(related)) + for i, r := range related { + result[i] = &ASTDiagnostic{r} + } + return result +} + +func (d *ASTDiagnostic) File() FileLike { + if file := d.Diagnostic.File(); file != nil { + return file + } + return nil +} + +func (d *ASTDiagnostic) MessageChain() []Diagnostic { + chain := d.Diagnostic.MessageChain() + result := make([]Diagnostic, len(chain)) + for i, c := range chain { + result[i] = &ASTDiagnostic{c} + } + return result +} + +func WrapASTDiagnostic(d *ast.Diagnostic) *ASTDiagnostic { + return &ASTDiagnostic{d} +} + +func WrapASTDiagnostics(diags []*ast.Diagnostic) []*ASTDiagnostic { + result := make([]*ASTDiagnostic, len(diags)) + for i, d := range diags { + result[i] = WrapASTDiagnostic(d) + } + return result +} + +func FromASTDiagnostics(diags []*ast.Diagnostic) []Diagnostic { + result := make([]Diagnostic, len(diags)) + for i, d := range diags { + result[i] = WrapASTDiagnostic(d) + } + return result +} + +func ToDiagnostics[T Diagnostic](diags []T) []Diagnostic { + result := make([]Diagnostic, len(diags)) + for i, d := range diags { + result[i] = d + } + return result +} + +func CompareASTDiagnostics(a, b *ASTDiagnostic) int { + return ast.CompareDiagnostics(a.Diagnostic, b.Diagnostic) +} + type FormattingOptions struct { tspath.ComparePathsOptions NewLine string @@ -36,7 +117,7 @@ const ( ellipsis = "..." ) -func FormatDiagnosticsWithColorAndContext(output io.Writer, diags []*ast.Diagnostic, formatOpts *FormattingOptions) { +func FormatDiagnosticsWithColorAndContext(output io.Writer, diags []Diagnostic, formatOpts *FormattingOptions) { if len(diags) == 0 { return } @@ -48,10 +129,10 @@ func FormatDiagnosticsWithColorAndContext(output io.Writer, diags []*ast.Diagnos } } -func FormatDiagnosticWithColorAndContext(output io.Writer, diagnostic *ast.Diagnostic, formatOpts *FormattingOptions) { +func FormatDiagnosticWithColorAndContext(output io.Writer, diagnostic Diagnostic, formatOpts *FormattingOptions) { if diagnostic.File() != nil { file := diagnostic.File() - pos := diagnostic.Loc().Pos() + pos := diagnostic.Pos() WriteLocation(output, file, pos, formatOpts, writeWithStyleAndReset) fmt.Fprint(output, " - ") } @@ -83,7 +164,7 @@ func FormatDiagnosticWithColorAndContext(output io.Writer, diagnostic *ast.Diagn } } -func writeCodeSnippet(writer io.Writer, sourceFile *ast.SourceFile, start int, length int, squiggleColor string, indent string, formatOpts *FormattingOptions) { +func writeCodeSnippet(writer io.Writer, sourceFile FileLike, start int, length int, squiggleColor string, indent string, formatOpts *FormattingOptions) { firstLine, firstLineChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, start) lastLine, lastLineChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, start+length) if length == 0 { @@ -118,7 +199,7 @@ func writeCodeSnippet(writer io.Writer, sourceFile *ast.SourceFile, start int, l if i < lastLineOfFile { lineEnd = scanner.GetECMAPositionOfLineAndCharacter(sourceFile, i+1, 0) } else { - lineEnd = sourceFile.Loc.End() + lineEnd = len(sourceFile.Text()) } lineContent := strings.TrimRightFunc(sourceFile.Text()[lineStart:lineEnd], unicode.IsSpace) // trim from end @@ -167,13 +248,17 @@ func writeCodeSnippet(writer io.Writer, sourceFile *ast.SourceFile, start int, l } } -func FlattenDiagnosticMessage(d *ast.Diagnostic, newLine string) string { +func FlattenDiagnosticMessage(d Diagnostic, newLine string) string { var output strings.Builder WriteFlattenedDiagnosticMessage(&output, d, newLine) return output.String() } -func WriteFlattenedDiagnosticMessage(writer io.Writer, diagnostic *ast.Diagnostic, newline string) { +func WriteFlattenedASTDiagnosticMessage(writer io.Writer, diagnostic *ast.Diagnostic, newline string) { + WriteFlattenedDiagnosticMessage(writer, WrapASTDiagnostic(diagnostic), newline) +} + +func WriteFlattenedDiagnosticMessage(writer io.Writer, diagnostic Diagnostic, newline string) { fmt.Fprint(writer, diagnostic.Message()) for _, chain := range diagnostic.MessageChain() { @@ -181,7 +266,7 @@ func WriteFlattenedDiagnosticMessage(writer io.Writer, diagnostic *ast.Diagnosti } } -func flattenDiagnosticMessageChain(writer io.Writer, chain *ast.Diagnostic, newLine string, level int) { +func flattenDiagnosticMessageChain(writer io.Writer, chain Diagnostic, newLine string, level int) { fmt.Fprint(writer, newLine) for range level { fmt.Fprint(writer, " ") @@ -215,7 +300,7 @@ func writeWithStyleAndReset(output io.Writer, text string, formatStyle string) { fmt.Fprint(output, resetEscapeSequence) } -func WriteLocation(output io.Writer, file *ast.SourceFile, pos int, formatOpts *FormattingOptions, writeWithStyleAndReset FormattedWriter) { +func WriteLocation(output io.Writer, file FileLike, pos int, formatOpts *FormattingOptions, writeWithStyleAndReset FormattedWriter) { firstLine, firstChar := scanner.GetECMALineAndCharacterOfPosition(file, pos) var relativeFileName string if formatOpts != nil { @@ -235,12 +320,12 @@ func WriteLocation(output io.Writer, file *ast.SourceFile, pos int, formatOpts * type ErrorSummary struct { TotalErrorCount int - GlobalErrors []*ast.Diagnostic - ErrorsByFiles map[*ast.SourceFile][]*ast.Diagnostic - SortedFileList []*ast.SourceFile + GlobalErrors []Diagnostic + ErrorsByFile map[FileLike][]Diagnostic + SortedFiles []FileLike } -func WriteErrorSummaryText(output io.Writer, allDiagnostics []*ast.Diagnostic, formatOpts *FormattingOptions) { +func WriteErrorSummaryText(output io.Writer, allDiagnostics []Diagnostic, formatOpts *FormattingOptions) { // Roughly corresponds to 'getErrorSummaryText' from watch.ts errorSummary := getErrorSummary(allDiagnostics) @@ -249,12 +334,12 @@ func WriteErrorSummaryText(output io.Writer, allDiagnostics []*ast.Diagnostic, f return } - firstFile := &ast.SourceFile{} - if len(errorSummary.SortedFileList) > 0 { - firstFile = errorSummary.SortedFileList[0] + var firstFile FileLike + if len(errorSummary.SortedFiles) > 0 { + firstFile = errorSummary.SortedFiles[0] } - firstFileName := prettyPathForFileError(firstFile, errorSummary.ErrorsByFiles[firstFile], formatOpts) - numErroringFiles := len(errorSummary.ErrorsByFiles) + firstFileName := prettyPathForFileError(firstFile, errorSummary.ErrorsByFile[firstFile], formatOpts) + numErroringFiles := len(errorSummary.ErrorsByFile) var message string if totalErrorCount == 1 { @@ -287,10 +372,10 @@ func WriteErrorSummaryText(output io.Writer, allDiagnostics []*ast.Diagnostic, f } } -func getErrorSummary(diags []*ast.Diagnostic) *ErrorSummary { +func getErrorSummary(diags []Diagnostic) *ErrorSummary { var totalErrorCount int - var globalErrors []*ast.Diagnostic - var errorsByFiles map[*ast.SourceFile][]*ast.Diagnostic + var globalErrors []Diagnostic + var errorsByFile map[FileLike][]Diagnostic for _, diagnostic := range diags { if diagnostic.Category() != diagnostics.CategoryError { @@ -301,32 +386,32 @@ func getErrorSummary(diags []*ast.Diagnostic) *ErrorSummary { if diagnostic.File() == nil { globalErrors = append(globalErrors, diagnostic) } else { - if errorsByFiles == nil { - errorsByFiles = make(map[*ast.SourceFile][]*ast.Diagnostic) + if errorsByFile == nil { + errorsByFile = make(map[FileLike][]Diagnostic) } - errorsByFiles[diagnostic.File()] = append(errorsByFiles[diagnostic.File()], diagnostic) + errorsByFile[diagnostic.File()] = append(errorsByFile[diagnostic.File()], diagnostic) } } // !!! // Need an ordered map here, but sorting for consistency. - sortedFileList := slices.SortedFunc(maps.Keys(errorsByFiles), func(a, b *ast.SourceFile) int { + sortedFiles := slices.SortedFunc(maps.Keys(errorsByFile), func(a, b FileLike) int { return strings.Compare(a.FileName(), b.FileName()) }) return &ErrorSummary{ TotalErrorCount: totalErrorCount, GlobalErrors: globalErrors, - ErrorsByFiles: errorsByFiles, - SortedFileList: sortedFileList, + ErrorsByFile: errorsByFile, + SortedFiles: sortedFiles, } } func writeTabularErrorsDisplay(output io.Writer, errorSummary *ErrorSummary, formatOpts *FormattingOptions) { - sortedFiles := errorSummary.SortedFileList + sortedFiles := errorSummary.SortedFiles maxErrors := 0 - for _, errorsForFile := range errorSummary.ErrorsByFiles { + for _, errorsForFile := range errorSummary.ErrorsByFile { maxErrors = max(maxErrors, len(errorsForFile)) } @@ -344,7 +429,7 @@ func writeTabularErrorsDisplay(output io.Writer, errorSummary *ErrorSummary, for fmt.Fprint(output, formatOpts.NewLine) for _, file := range sortedFiles { - fileErrors := errorSummary.ErrorsByFiles[file] + fileErrors := errorSummary.ErrorsByFile[file] errorCount := len(fileErrors) fmt.Fprintf(output, "%*d ", leftPaddingGoal, errorCount) @@ -353,11 +438,11 @@ func writeTabularErrorsDisplay(output io.Writer, errorSummary *ErrorSummary, for } } -func prettyPathForFileError(file *ast.SourceFile, fileErrors []*ast.Diagnostic, formatOpts *FormattingOptions) string { +func prettyPathForFileError(file FileLike, fileErrors []Diagnostic, formatOpts *FormattingOptions) string { if file == nil || len(fileErrors) == 0 { return "" } - line := scanner.GetECMALineOfPosition(file, fileErrors[0].Loc().Pos()) + line := scanner.GetECMALineOfPosition(file, fileErrors[0].Pos()) fileName := file.FileName() if tspath.PathIsAbsolute(fileName) && tspath.PathIsAbsolute(formatOpts.CurrentDirectory) { fileName = tspath.ConvertToRelativePath(file.FileName(), formatOpts.ComparePathsOptions) @@ -370,15 +455,15 @@ func prettyPathForFileError(file *ast.SourceFile, fileErrors []*ast.Diagnostic, ) } -func WriteFormatDiagnostics(output io.Writer, diagnostics []*ast.Diagnostic, formatOpts *FormattingOptions) { +func WriteFormatDiagnostics(output io.Writer, diagnostics []Diagnostic, formatOpts *FormattingOptions) { for _, diagnostic := range diagnostics { WriteFormatDiagnostic(output, diagnostic, formatOpts) } } -func WriteFormatDiagnostic(output io.Writer, diagnostic *ast.Diagnostic, formatOpts *FormattingOptions) { +func WriteFormatDiagnostic(output io.Writer, diagnostic Diagnostic, formatOpts *FormattingOptions) { if diagnostic.File() != nil { - line, character := scanner.GetECMALineAndCharacterOfPosition(diagnostic.File(), diagnostic.Loc().Pos()) + line, character := scanner.GetECMALineAndCharacterOfPosition(diagnostic.File(), diagnostic.Pos()) fileName := diagnostic.File().FileName() relativeFileName := tspath.ConvertToRelativePath(fileName, formatOpts.ComparePathsOptions) fmt.Fprintf(output, "%s(%d,%d): ", relativeFileName, line+1, character+1) @@ -389,14 +474,14 @@ func WriteFormatDiagnostic(output io.Writer, diagnostic *ast.Diagnostic, formatO fmt.Fprint(output, formatOpts.NewLine) } -func FormatDiagnosticsStatusWithColorAndTime(output io.Writer, time string, diag *ast.Diagnostic, formatOpts *FormattingOptions) { +func FormatDiagnosticsStatusWithColorAndTime(output io.Writer, time string, diag Diagnostic, formatOpts *FormattingOptions) { fmt.Fprint(output, "[") writeWithStyleAndReset(output, time, foregroundColorEscapeGrey) fmt.Fprint(output, "] ") WriteFlattenedDiagnosticMessage(output, diag, formatOpts.NewLine) } -func FormatDiagnosticsStatusAndTime(output io.Writer, time string, diag *ast.Diagnostic, formatOpts *FormattingOptions) { +func FormatDiagnosticsStatusAndTime(output io.Writer, time string, diag Diagnostic, formatOpts *FormattingOptions) { fmt.Fprint(output, time, " - ") WriteFlattenedDiagnosticMessage(output, diag, formatOpts.NewLine) } @@ -406,7 +491,7 @@ var ScreenStartingCodes = []int32{ diagnostics.File_change_detected_Starting_incremental_compilation.Code(), } -func TryClearScreen(output io.Writer, diag *ast.Diagnostic, options *core.CompilerOptions) bool { +func TryClearScreen(output io.Writer, diag Diagnostic, options *core.CompilerOptions) bool { if !options.PreserveWatchOutput.IsTrue() && !options.ExtendedDiagnostics.IsTrue() && !options.Diagnostics.IsTrue() && diff --git a/internal/execute/tsc/diagnostics.go b/internal/execute/tsc/diagnostics.go index a477867417..76992e2417 100644 --- a/internal/execute/tsc/diagnostics.go +++ b/internal/execute/tsc/diagnostics.go @@ -32,12 +32,12 @@ func CreateDiagnosticReporter(sys System, w io.Writer, options *core.CompilerOpt formatOpts := getFormatOptsOfSys(sys) if shouldBePretty(sys, options) { return func(diagnostic *ast.Diagnostic) { - diagnosticwriter.FormatDiagnosticWithColorAndContext(w, diagnostic, formatOpts) + diagnosticwriter.FormatDiagnosticWithColorAndContext(w, diagnosticwriter.WrapASTDiagnostic(diagnostic), formatOpts) fmt.Fprint(w, formatOpts.NewLine) } } return func(diagnostic *ast.Diagnostic) { - diagnosticwriter.WriteFormatDiagnostic(w, diagnostic, formatOpts) + diagnosticwriter.WriteFormatDiagnostic(w, diagnosticwriter.WrapASTDiagnostic(diagnostic), formatOpts) } } @@ -127,7 +127,7 @@ func CreateReportErrorSummary(sys System, options *core.CompilerOptions) Diagnos if shouldBePretty(sys, options) { formatOpts := getFormatOptsOfSys(sys) return func(diagnostics []*ast.Diagnostic) { - diagnosticwriter.WriteErrorSummaryText(sys.Writer(), diagnostics, formatOpts) + diagnosticwriter.WriteErrorSummaryText(sys.Writer(), diagnosticwriter.FromASTDiagnostics(diagnostics), formatOpts) } } return QuietDiagnosticsReporter @@ -141,11 +141,12 @@ func CreateBuilderStatusReporter(sys System, w io.Writer, options *core.Compiler formatOpts := getFormatOptsOfSys(sys) writeStatus := core.IfElse(shouldBePretty(sys, options), diagnosticwriter.FormatDiagnosticsStatusWithColorAndTime, diagnosticwriter.FormatDiagnosticsStatusAndTime) return func(diagnostic *ast.Diagnostic) { + writerDiagnostic := diagnosticwriter.WrapASTDiagnostic(diagnostic) if testing != nil { testing.OnBuildStatusReportStart(w) defer testing.OnBuildStatusReportEnd(w) } - writeStatus(w, sys.Now().Format("03:04:05 PM"), diagnostic, formatOpts) + writeStatus(w, sys.Now().Format("03:04:05 PM"), writerDiagnostic, formatOpts) fmt.Fprint(w, formatOpts.NewLine, formatOpts.NewLine) } } @@ -154,13 +155,14 @@ func CreateWatchStatusReporter(sys System, options *core.CompilerOptions, testin formatOpts := getFormatOptsOfSys(sys) writeStatus := core.IfElse(shouldBePretty(sys, options), diagnosticwriter.FormatDiagnosticsStatusWithColorAndTime, diagnosticwriter.FormatDiagnosticsStatusAndTime) return func(diagnostic *ast.Diagnostic) { + writerDiagnostic := diagnosticwriter.WrapASTDiagnostic(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) + diagnosticwriter.TryClearScreen(writer, writerDiagnostic, options) + writeStatus(writer, sys.Now().Format("03:04:05 PM"), writerDiagnostic, formatOpts) fmt.Fprint(writer, formatOpts.NewLine, formatOpts.NewLine) } } diff --git a/internal/fourslash/_scripts/convertFourslash.mts b/internal/fourslash/_scripts/convertFourslash.mts index d2d3a504ad..169151c118 100644 --- a/internal/fourslash/_scripts/convertFourslash.mts +++ b/internal/fourslash/_scripts/convertFourslash.mts @@ -217,6 +217,9 @@ function parseFourslashStatement(statement: ts.Statement): Cmd[] | undefined { case "getSuggestionDiagnostics": case "getSyntacticDiagnostics": return parseVerifyDiagnostics(func.text, callExpression.arguments); + case "baselineSyntacticDiagnostics": + case "baselineSyntacticAndSemanticDiagnostics": + return [{ kind: "verifyBaselineDiagnostics" }]; } } // `goTo....` @@ -327,10 +330,11 @@ function parseGoToArgs(args: readonly ts.Expression[], funcName: string): GoToCm } let arg0; if (arg0 = getStringLiteralLike(args[0])) { + const text = arg0.text.replace("tests/cases/fourslash/server/", "").replace("tests/cases/fourslash/", ""); return [{ kind: "goTo", funcName: "file", - args: [getGoStringLiteral(arg0.text)], + args: [getGoStringLiteral(text)], }]; } else if (arg0 = getNumericLiteral(args[0])) { @@ -1892,6 +1896,10 @@ interface VerifyDiagnosticsCmd { isSuggestion: boolean; } +interface VerifyBaselineDiagnosticsCmd { + kind: "verifyBaselineDiagnostics"; +} + type Cmd = | VerifyCompletionsCmd | VerifyApplyCodeActionFromCompletionCmd @@ -1908,7 +1916,8 @@ type Cmd = | VerifyRenameInfoCmd | VerifyBaselineInlayHintsCmd | VerifyImportFixAtPositionCmd - | VerifyDiagnosticsCmd; + | VerifyDiagnosticsCmd + | VerifyBaselineDiagnosticsCmd; function generateVerifyCompletions({ marker, args, isNewIdentifierLocation, andApplyCodeActionArgs }: VerifyCompletionsCmd): string { let expectedList: string; @@ -2060,6 +2069,8 @@ function generateCmd(cmd: Cmd): string { case "verifyDiagnostics": const funcName = cmd.isSuggestion ? "VerifySuggestionDiagnostics" : "VerifyNonSuggestionDiagnostics"; return `f.${funcName}(t, ${cmd.arg})`; + case "verifyBaselineDiagnostics": + return `f.VerifyBaselineNonSuggestionDiagnostics(t)`; default: let neverCommand: never = cmd; throw new Error(`Unknown command kind: ${neverCommand as Cmd["kind"]}`); diff --git a/internal/fourslash/baselineutil.go b/internal/fourslash/baselineutil.go index 03eb2210ff..cc61da098a 100644 --- a/internal/fourslash/baselineutil.go +++ b/internal/fourslash/baselineutil.go @@ -47,7 +47,7 @@ func getBaselineFileName(t *testing.T, command string) string { func getBaselineExtension(command string) string { switch command { - case "QuickInfo", "SignatureHelp", "Smart Selection", "Inlay Hints": + case "QuickInfo", "SignatureHelp", "Smart Selection", "Inlay Hints", "Syntax and Semantic Diagnostics": return "baseline" case "Auto Imports": return "baseline.md" diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index b60bca8ae9..2205dbdfb5 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -16,6 +16,8 @@ import ( "github.com/microsoft/typescript-go/internal/bundled" "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/diagnosticwriter" "github.com/microsoft/typescript-go/internal/ls" "github.com/microsoft/typescript-go/internal/ls/lsconv" "github.com/microsoft/typescript-go/internal/ls/lsutil" @@ -26,6 +28,7 @@ import ( "github.com/microsoft/typescript-go/internal/stringutil" "github.com/microsoft/typescript-go/internal/testutil/baseline" "github.com/microsoft/typescript-go/internal/testutil/harnessutil" + "github.com/microsoft/typescript-go/internal/testutil/tsbaseline" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" "github.com/microsoft/typescript-go/internal/vfs/vfstest" @@ -2517,23 +2520,7 @@ func (f *FourslashTest) VerifySuggestionDiagnostics(t *testing.T, expected []*ls } func (f *FourslashTest) verifyDiagnostics(t *testing.T, expected []*lsproto.Diagnostic, filterDiagnostics func(*lsproto.Diagnostic) bool) { - params := &lsproto.DocumentDiagnosticParams{ - TextDocument: lsproto.TextDocumentIdentifier{ - Uri: lsconv.FileNameToDocumentURI(f.activeFilename), - }, - } - resMsg, result, resultOk := sendRequest(t, f, lsproto.TextDocumentDiagnosticInfo, params) - if resMsg == nil { - t.Fatal("Nil response received for diagnostics request") - } - if !resultOk { - t.Fatalf("Unexpected response type for diagnostics request: %T", resMsg.AsResponse().Result) - } - - var actualDiagnostics []*lsproto.Diagnostic - if result.FullDocumentDiagnosticReport != nil { - actualDiagnostics = append(actualDiagnostics, result.FullDocumentDiagnosticReport.Items...) - } + actualDiagnostics := f.getDiagnostics(t, f.activeFilename) actualDiagnostics = core.Filter(actualDiagnostics, filterDiagnostics) emptyRange := lsproto.Range{} expectedWithRanges := make([]*lsproto.Diagnostic, len(expected)) @@ -2556,11 +2543,217 @@ func (f *FourslashTest) verifyDiagnostics(t *testing.T, expected []*lsproto.Diag assertDeepEqual(t, actualDiagnostics, expectedWithRanges, "Diagnostics do not match expected", diagnosticsIgnoreOpts) } +func (f *FourslashTest) getDiagnostics(t *testing.T, fileName string) []*lsproto.Diagnostic { + params := &lsproto.DocumentDiagnosticParams{ + TextDocument: lsproto.TextDocumentIdentifier{ + Uri: lsconv.FileNameToDocumentURI(fileName), + }, + } + resMsg, result, resultOk := sendRequest(t, f, lsproto.TextDocumentDiagnosticInfo, params) + if resMsg == nil { + t.Fatal("Nil response received for diagnostics request") + } + if !resultOk { + t.Fatalf("Unexpected response type for diagnostics request: %T", resMsg.AsResponse().Result) + } + + if result.FullDocumentDiagnosticReport != nil { + return result.FullDocumentDiagnosticReport.Items + } + return nil +} + func isSuggestionDiagnostic(diag *lsproto.Diagnostic) bool { return diag.Tags != nil && len(*diag.Tags) > 0 || (diag.Severity != nil && *diag.Severity == lsproto.DiagnosticSeverityHint) } +func (f *FourslashTest) VerifyBaselineNonSuggestionDiagnostics(t *testing.T) { + var diagnostics []*fourslashDiagnostic + var files []*harnessutil.TestFile + for fileName, scriptInfo := range f.scriptInfos { + if tspath.HasJSONFileExtension(fileName) { + continue + } + files = append(files, &harnessutil.TestFile{UnitName: fileName, Content: scriptInfo.content}) + lspDiagnostics := core.Filter( + f.getDiagnostics(t, fileName), + func(d *lsproto.Diagnostic) bool { return !isSuggestionDiagnostic(d) }, + ) + diagnostics = append(diagnostics, core.Map(lspDiagnostics, func(d *lsproto.Diagnostic) *fourslashDiagnostic { + return f.toDiagnostic(scriptInfo, d) + })...) + } + slices.SortFunc(files, func(a, b *harnessutil.TestFile) int { + return strings.Compare(a.UnitName, b.UnitName) + }) + result := tsbaseline.GetErrorBaseline(t, files, diagnostics, compareDiagnostics, false /*pretty*/) + f.addResultToBaseline(t, "Syntax and Semantic Diagnostics", result) +} + +type fourslashDiagnostic struct { + file *fourslashDiagnosticFile + loc core.TextRange + code int32 + category diagnostics.Category + message string + relatedDiagnostics []*fourslashDiagnostic + reportsUnnecessary bool + reportsDeprecated bool +} + +type fourslashDiagnosticFile struct { + file *harnessutil.TestFile + ecmaLineMap []core.TextPos +} + +var _ diagnosticwriter.FileLike = (*fourslashDiagnosticFile)(nil) + +func (f *fourslashDiagnosticFile) FileName() string { + return f.file.UnitName +} + +func (f *fourslashDiagnosticFile) Text() string { + return f.file.Content +} + +func (f *fourslashDiagnosticFile) ECMALineMap() []core.TextPos { + if f.ecmaLineMap == nil { + f.ecmaLineMap = core.ComputeECMALineStarts(f.file.Content) + } + return f.ecmaLineMap +} + +var _ diagnosticwriter.Diagnostic = (*fourslashDiagnostic)(nil) + +func (d *fourslashDiagnostic) File() diagnosticwriter.FileLike { + return d.file +} + +func (d *fourslashDiagnostic) Pos() int { + return d.loc.Pos() +} + +func (d *fourslashDiagnostic) End() int { + return d.loc.End() +} + +func (d *fourslashDiagnostic) Len() int { + return d.loc.Len() +} + +func (d *fourslashDiagnostic) Code() int32 { + return d.code +} + +func (d *fourslashDiagnostic) Category() diagnostics.Category { + return d.category +} + +func (d *fourslashDiagnostic) Message() string { + return d.message +} + +func (d *fourslashDiagnostic) MessageChain() []diagnosticwriter.Diagnostic { + return nil +} + +func (d *fourslashDiagnostic) RelatedInformation() []diagnosticwriter.Diagnostic { + relatedInfo := make([]diagnosticwriter.Diagnostic, 0, len(d.relatedDiagnostics)) + for _, relDiag := range d.relatedDiagnostics { + relatedInfo = append(relatedInfo, relDiag) + } + return relatedInfo +} + +func (f *FourslashTest) toDiagnostic(scriptInfo *scriptInfo, lspDiagnostic *lsproto.Diagnostic) *fourslashDiagnostic { + var category diagnostics.Category + switch *lspDiagnostic.Severity { + case lsproto.DiagnosticSeverityError: + category = diagnostics.CategoryError + case lsproto.DiagnosticSeverityWarning: + category = diagnostics.CategoryWarning + case lsproto.DiagnosticSeverityInformation: + category = diagnostics.CategoryMessage + case lsproto.DiagnosticSeverityHint: + category = diagnostics.CategorySuggestion + default: + category = diagnostics.CategoryError + } + code := *lspDiagnostic.Code.Integer + + var relatedDiagnostics []*fourslashDiagnostic + if lspDiagnostic.RelatedInformation != nil { + for _, info := range *lspDiagnostic.RelatedInformation { + relatedScriptInfo := f.getScriptInfo(info.Location.Uri.FileName()) + if relatedScriptInfo == nil { + continue + } + relatedDiagnostic := &fourslashDiagnostic{ + file: &fourslashDiagnosticFile{file: &harnessutil.TestFile{UnitName: relatedScriptInfo.fileName, Content: relatedScriptInfo.content}}, + loc: f.converters.FromLSPRange(relatedScriptInfo, info.Location.Range), + code: code, + category: category, + message: info.Message, + } + relatedDiagnostics = append(relatedDiagnostics, relatedDiagnostic) + } + } + + diagnostic := &fourslashDiagnostic{ + file: &fourslashDiagnosticFile{ + file: &harnessutil.TestFile{ + UnitName: scriptInfo.fileName, + Content: scriptInfo.content, + }, + }, + loc: f.converters.FromLSPRange(scriptInfo, lspDiagnostic.Range), + code: code, + category: category, + message: lspDiagnostic.Message, + relatedDiagnostics: relatedDiagnostics, + } + return diagnostic +} + +func compareDiagnostics(d1, d2 *fourslashDiagnostic) int { + c := strings.Compare(d1.file.FileName(), d2.file.FileName()) + if c != 0 { + return c + } + c = d1.Pos() - d2.Pos() + if c != 0 { + return c + } + c = d1.End() - d2.End() + if c != 0 { + return c + } + c = int(d1.code) - int(d2.code) + if c != 0 { + return c + } + c = strings.Compare(d1.message, d2.message) + if c != 0 { + return c + } + return compareRelatedDiagnostics(d1.relatedDiagnostics, d2.relatedDiagnostics) +} + +func compareRelatedDiagnostics(d1, d2 []*fourslashDiagnostic) int { + c := len(d2) - len(d1) + if c != 0 { + return c + } + for i := range d1 { + c = compareDiagnostics(d1[i], d2[i]) + if c != 0 { + return c + } + } + return 0 +} + func isLibFile(fileName string) bool { baseName := tspath.GetBaseFileName(fileName) if strings.HasPrefix(baseName, "lib.") && strings.HasSuffix(baseName, ".d.ts") { diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics01_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics01_test.go new file mode 100644 index 0000000000..397b6a2173 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics01_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics01(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +var ===;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics02_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics02_test.go new file mode 100644 index 0000000000..149ad70f75 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics02_test.go @@ -0,0 +1,22 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics02(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: b.js +var a = "a"; +var b: boolean = true; +function foo(): string { } +var var = "c";` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics10_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics10_test.go new file mode 100644 index 0000000000..c1ac23aa81 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics10_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics10(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +function F() { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics11_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics11_test.go new file mode 100644 index 0000000000..875e0aac31 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics11_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics11(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +function F(): number { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics12_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics12_test.go new file mode 100644 index 0000000000..cba5db238b --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics12_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics12(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +declare var v;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics13_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics13_test.go new file mode 100644 index 0000000000..bd51a808fc --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics13_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics13(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +var v: () => number;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics14_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics14_test.go new file mode 100644 index 0000000000..932818ae6e --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics14_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics14(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +Foo();` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics15_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics15_test.go new file mode 100644 index 0000000000..c9c1f4f91d --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics15_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics15(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +function F(public p) { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics16_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics16_test.go new file mode 100644 index 0000000000..826fac6510 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics16_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics16(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +function F(p?) { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics17_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics17_test.go new file mode 100644 index 0000000000..b5ec3bcea3 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics17_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics17(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +function F(a: number) { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics18_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics18_test.go new file mode 100644 index 0000000000..f8c1dbd261 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics18_test.go @@ -0,0 +1,27 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics18(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +class C { + x; // Regular property declaration allowed + static y; // static allowed + public z; // public not allowed +} +// @Filename: b.js +class C { + x: number; // Types not allowed +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics19_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics19_test.go new file mode 100644 index 0000000000..5df7a2c35e --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics19_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics19(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +enum E { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics1_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics1_test.go new file mode 100644 index 0000000000..e0ea67f04b --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics1_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +import a = b;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics2_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics2_test.go new file mode 100644 index 0000000000..9597a92036 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics2_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +export = b;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics3_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics3_test.go new file mode 100644 index 0000000000..8551aec682 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics3_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +class C { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics4_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics4_test.go new file mode 100644 index 0000000000..b1179f5639 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics4_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +public class C { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics5_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics5_test.go new file mode 100644 index 0000000000..b19508d1fe --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics5_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics5(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +class C implements D { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics6_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics6_test.go new file mode 100644 index 0000000000..57aeba6777 --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics6_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics6(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +interface I { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics7_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics7_test.go new file mode 100644 index 0000000000..6b1228203d --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics7_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics7(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +module M { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics8_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics8_test.go new file mode 100644 index 0000000000..103fd7542e --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics8_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics8(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +type a = b;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics9_test.go b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics9_test.go new file mode 100644 index 0000000000..4ac13df47f --- /dev/null +++ b/internal/fourslash/tests/gen/getJavaScriptSyntacticDiagnostics9_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetJavaScriptSyntacticDiagnostics9(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @Filename: a.js +public function F() { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/rewriteRelativeImportExtensionsProjectReferences1_test.go b/internal/fourslash/tests/gen/rewriteRelativeImportExtensionsProjectReferences1_test.go new file mode 100644 index 0000000000..c1cad904d1 --- /dev/null +++ b/internal/fourslash/tests/gen/rewriteRelativeImportExtensionsProjectReferences1_test.go @@ -0,0 +1,58 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestRewriteRelativeImportExtensionsProjectReferences1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: packages/common/tsconfig.json +{ + "compilerOptions": { + "composite": true, + "rootDir": "src", + "outDir": "dist", + "module": "nodenext", + "resolveJsonModule": false, + } +} +// @Filename: packages/common/package.json +{ + "name": "common", + "version": "1.0.0", + "type": "module", + "exports": { + ".": { + "source": "./src/index.ts", + "default": "./dist/index.js" + } + } +} +// @Filename: packages/common/src/index.ts +export {}; +// @Filename: packages/main/tsconfig.json +{ + "compilerOptions": { + "module": "nodenext", + "rewriteRelativeImportExtensions": true, + "rootDir": "src", + "outDir": "dist", + "resolveJsonModule": false, + }, + "references": [ + { "path": "../common" } + ] +} +// @Filename: packages/main/package.json +{ "type": "module" } +// @Filename: packages/main/src/index.ts +import {} from "../../common/src/index.ts";` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/packages/main/src/index.ts") + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/rewriteRelativeImportExtensionsProjectReferences2_test.go b/internal/fourslash/tests/gen/rewriteRelativeImportExtensionsProjectReferences2_test.go new file mode 100644 index 0000000000..c84c61ffb2 --- /dev/null +++ b/internal/fourslash/tests/gen/rewriteRelativeImportExtensionsProjectReferences2_test.go @@ -0,0 +1,44 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestRewriteRelativeImportExtensionsProjectReferences2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: src/tsconfig-base.json +{ + "compilerOptions": { + "module": "nodenext", + "composite": true, + "rootDir": ".", + "outDir": "../dist", + "rewriteRelativeImportExtensions": true, + } +} +// @Filename: src/compiler/tsconfig.json +{ + "extends": "../tsconfig-base.json", + "compilerOptions": {} +} +// @Filename: src/compiler/parser.ts +export {}; +// @Filename: src/services/tsconfig.json +{ + "extends": "../tsconfig-base.json", + "compilerOptions": {}, + "references": [ + { "path": "../compiler" } + ] +} +// @Filename: src/services/services.ts +import {} from "../compiler/parser.ts";` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/src/services/services.ts") + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/rewriteRelativeImportExtensionsProjectReferences3_test.go b/internal/fourslash/tests/gen/rewriteRelativeImportExtensionsProjectReferences3_test.go new file mode 100644 index 0000000000..4a9e14097c --- /dev/null +++ b/internal/fourslash/tests/gen/rewriteRelativeImportExtensionsProjectReferences3_test.go @@ -0,0 +1,47 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestRewriteRelativeImportExtensionsProjectReferences3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: src/tsconfig-base.json +{ + "compilerOptions": { + "module": "nodenext", + "composite": true, + "rewriteRelativeImportExtensions": true, + } +} +// @Filename: src/compiler/tsconfig.json +{ + "extends": "../tsconfig-base.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "../../dist/compiler", +} +// @Filename: src/compiler/parser.ts +export {}; +// @Filename: src/services/tsconfig.json +{ + "extends": "../tsconfig-base.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "../../dist/services", + }, + "references": [ + { "path": "../compiler" } + ] +} +// @Filename: src/services/services.ts +import {} from "../compiler/parser.ts";` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/src/services/services.ts") + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/fourslash/tests/gen/typeErrorAfterStringCompletionsInNestedCall2_test.go b/internal/fourslash/tests/gen/typeErrorAfterStringCompletionsInNestedCall2_test.go new file mode 100644 index 0000000000..0ff56db36a --- /dev/null +++ b/internal/fourslash/tests/gen/typeErrorAfterStringCompletionsInNestedCall2_test.go @@ -0,0 +1,80 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + . "github.com/microsoft/typescript-go/internal/fourslash/tests/util" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestTypeErrorAfterStringCompletionsInNestedCall2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @strict: true + +type ActionFunction< + TExpressionEvent extends { type: string }, + out TEvent extends { type: string } +> = { + ({ event }: { event: TExpressionEvent }): void; + _out_TEvent?: TEvent; +}; + +interface MachineConfig { + types: { + events: TEvent; + }; + on: { + [K in TEvent["type"]]?: ActionFunction< + Extract, + TEvent + >; + }; +} + +declare function raise< + TExpressionEvent extends { type: string }, + TEvent extends { type: string } +>( + resolve: ({ event }: { event: TExpressionEvent }) => TEvent +): { + ({ event }: { event: TExpressionEvent }): void; + _out_TEvent?: TEvent; +}; + +declare function createMachine( + config: MachineConfig +): void; + +createMachine({ + types: { + events: {} as { type: "FOO" } | { type: "BAR" }, + }, + on: { + [|/*error*/FOO|]: raise(({ event }) => { + return { + type: "BAR/*1*/" as const, + }; + }), + }, +});` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "1") + f.Insert(t, "x") + f.VerifyCompletions(t, nil, &fourslash.CompletionsExpectedList{ + IsIncomplete: false, + ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{ + CommitCharacters: &DefaultCommitCharacters, + EditRange: Ignored, + }, + Items: &fourslash.CompletionsExpectedItems{ + Exact: []fourslash.CompletionsExpectedItem{ + "BAR", + "FOO", + }, + }, + }) + f.VerifyBaselineNonSuggestionDiagnostics(t) +} diff --git a/internal/ls/diagnostics.go b/internal/ls/diagnostics.go index 59d34bb213..f223bf5dbe 100644 --- a/internal/ls/diagnostics.go +++ b/internal/ls/diagnostics.go @@ -104,7 +104,7 @@ func messageChainToString(diagnostic *ast.Diagnostic) string { return diagnostic.Message() } var b strings.Builder - diagnosticwriter.WriteFlattenedDiagnosticMessage(&b, diagnostic, "\n") + diagnosticwriter.WriteFlattenedASTDiagnosticMessage(&b, diagnostic, "\n") return b.String() } diff --git a/internal/scanner/scanner.go b/internal/scanner/scanner.go index 3dd6eff04a..0367bd0214 100644 --- a/internal/scanner/scanner.go +++ b/internal/scanner/scanner.go @@ -2465,7 +2465,7 @@ func GetECMAEndLinePosition(sourceFile *ast.SourceFile, line int) int { } } -func GetECMAPositionOfLineAndCharacter(sourceFile *ast.SourceFile, line int, character int) int { +func GetECMAPositionOfLineAndCharacter(sourceFile ast.SourceFileLike, line int, character int) int { return ComputePositionOfLineAndCharacter(GetECMALineStarts(sourceFile), line, character) } diff --git a/internal/testutil/parsetestutil/parsetestutil.go b/internal/testutil/parsetestutil/parsetestutil.go index 589077b56c..4d0a4d20d5 100644 --- a/internal/testutil/parsetestutil/parsetestutil.go +++ b/internal/testutil/parsetestutil/parsetestutil.go @@ -27,7 +27,7 @@ func CheckDiagnostics(t *testing.T, file *ast.SourceFile) { t.Helper() if len(file.Diagnostics()) > 0 { var b strings.Builder - diagnosticwriter.WriteFormatDiagnostics(&b, file.Diagnostics(), &diagnosticwriter.FormattingOptions{ + diagnosticwriter.WriteFormatDiagnostics(&b, diagnosticwriter.FromASTDiagnostics(file.Diagnostics()), &diagnosticwriter.FormattingOptions{ NewLine: "\n", }) t.Error(b.String()) @@ -39,7 +39,7 @@ func CheckDiagnosticsMessage(t *testing.T, file *ast.SourceFile, message string) t.Helper() if len(file.Diagnostics()) > 0 { var b strings.Builder - diagnosticwriter.WriteFormatDiagnostics(&b, file.Diagnostics(), &diagnosticwriter.FormattingOptions{ + diagnosticwriter.WriteFormatDiagnostics(&b, diagnosticwriter.FromASTDiagnostics(file.Diagnostics()), &diagnosticwriter.FormattingOptions{ NewLine: "\n", }) t.Error(message + b.String()) diff --git a/internal/testutil/tsbaseline/error_baseline.go b/internal/testutil/tsbaseline/error_baseline.go index d9ea2a8cd1..b3e20f5093 100644 --- a/internal/testutil/tsbaseline/error_baseline.go +++ b/internal/testutil/tsbaseline/error_baseline.go @@ -35,14 +35,14 @@ func DoErrorBaseline(t *testing.T, baselinePath string, inputFiles []*harnessuti baselinePath = tsExtension.ReplaceAllString(baselinePath, ".errors.txt") var errorBaseline string if len(errors) > 0 { - errorBaseline = getErrorBaseline(t, inputFiles, errors, pretty) + errorBaseline = GetErrorBaseline(t, inputFiles, diagnosticwriter.WrapASTDiagnostics(errors), diagnosticwriter.CompareASTDiagnostics, pretty) } else { errorBaseline = baseline.NoContent } baseline.Run(t, baselinePath, errorBaseline, opts) } -func minimalDiagnosticsToString(diagnostics []*ast.Diagnostic, pretty bool) string { +func minimalDiagnosticsToString(diagnostics []diagnosticwriter.Diagnostic, pretty bool) string { var output strings.Builder if pretty { diagnosticwriter.FormatDiagnosticsWithColorAndContext(&output, diagnostics, formatOpts) @@ -52,15 +52,15 @@ func minimalDiagnosticsToString(diagnostics []*ast.Diagnostic, pretty bool) stri return output.String() } -func getErrorBaseline(t *testing.T, inputFiles []*harnessutil.TestFile, diagnostics []*ast.Diagnostic, pretty bool) string { +func GetErrorBaseline[T diagnosticwriter.Diagnostic](t *testing.T, inputFiles []*harnessutil.TestFile, diagnostics []T, compareDiagnostics func(a, b T) int, pretty bool) string { t.Helper() - outputLines := iterateErrorBaseline(t, inputFiles, diagnostics, pretty) + outputLines := iterateErrorBaseline(t, inputFiles, diagnostics, compareDiagnostics, pretty) if pretty { var summaryBuilder strings.Builder diagnosticwriter.WriteErrorSummaryText( &summaryBuilder, - diagnostics, + diagnosticwriter.ToDiagnostics(diagnostics), formatOpts) summary := removeTestPathPrefixes(summaryBuilder.String(), false) outputLines = append(outputLines, summary) @@ -68,10 +68,10 @@ func getErrorBaseline(t *testing.T, inputFiles []*harnessutil.TestFile, diagnost return strings.Join(outputLines, "") } -func iterateErrorBaseline(t *testing.T, inputFiles []*harnessutil.TestFile, inputDiagnostics []*ast.Diagnostic, pretty bool) []string { +func iterateErrorBaseline[T diagnosticwriter.Diagnostic](t *testing.T, inputFiles []*harnessutil.TestFile, inputDiagnostics []T, compareDiagnostics func(a, b T) int, pretty bool) []string { t.Helper() diagnostics := slices.Clone(inputDiagnostics) - slices.SortFunc(diagnostics, ast.CompareDiagnostics) + slices.SortFunc(diagnostics, compareDiagnostics) var outputLines strings.Builder // Count up all errors that were found in files other than lib.d.ts so we don't miss any @@ -90,7 +90,7 @@ func iterateErrorBaseline(t *testing.T, inputFiles []*harnessutil.TestFile, inpu var result []string - outputErrorText := func(diag *ast.Diagnostic) { + outputErrorText := func(diag diagnosticwriter.Diagnostic) { message := diagnosticwriter.FlattenDiagnosticMessage(diag, harnessNewLine) var errLines []string @@ -106,7 +106,7 @@ func iterateErrorBaseline(t *testing.T, inputFiles []*harnessutil.TestFile, inpu for _, info := range diag.RelatedInformation() { var location string if info.File() != nil { - location = " " + formatLocation(info.File(), info.Loc().Pos(), formatOpts, func(output io.Writer, text string, formatStyle string) { fmt.Fprint(output, text) }) + location = " " + formatLocation(info.File(), info.Pos(), formatOpts, func(output io.Writer, text string, formatStyle string) { fmt.Fprint(output, text) }) } location = removeTestPathPrefixes(location, false) if len(location) > 0 && isDefaultLibraryFile(info.File().FileName()) { @@ -133,7 +133,7 @@ func iterateErrorBaseline(t *testing.T, inputFiles []*harnessutil.TestFile, inpu } } - topDiagnostics := minimalDiagnosticsToString(diagnostics, pretty) + topDiagnostics := minimalDiagnosticsToString(diagnosticwriter.ToDiagnostics(diagnostics), pretty) topDiagnostics = removeTestPathPrefixes(topDiagnostics, false) topDiagnostics = diagnosticsLocationPrefix.ReplaceAllString(topDiagnostics, "$1(--,--)") @@ -154,7 +154,7 @@ func iterateErrorBaseline(t *testing.T, inputFiles []*harnessutil.TestFile, inpu dupeCase := map[string]int{} for _, inputFile := range inputFiles { // Filter down to the errors in the file - fileErrors := core.Filter(diagnostics, func(e *ast.Diagnostic) bool { + fileErrors := core.Filter(diagnostics, func(e T) bool { return e.File() != nil && tspath.ComparePaths(removeTestPathPrefixes(e.File().FileName(), false), removeTestPathPrefixes(inputFile.UnitName, false), tspath.ComparePathsOptions{}) == 0 }) @@ -193,8 +193,8 @@ func iterateErrorBaseline(t *testing.T, inputFiles []*harnessutil.TestFile, inpu outputLines.WriteString(line) for _, errDiagnostic := range fileErrors { // Does any error start or continue on to this line? Emit squiggles - errStart := errDiagnostic.Loc().Pos() - end := errDiagnostic.Loc().End() + errStart := errDiagnostic.Pos() + end := errStart + errDiagnostic.Len() if end >= thisLineStart && (errStart < nextLineStart || lineIndex == len(lines)-1) { // How many characters from the start of this line the error starts at (could be positive or negative) relativeOffset := errStart - thisLineStart @@ -234,12 +234,12 @@ func iterateErrorBaseline(t *testing.T, inputFiles []*harnessutil.TestFile, inpu numLibraryDiagnostics := core.CountWhere( diagnostics, - func(d *ast.Diagnostic) bool { + func(d T) bool { return d.File() != nil && (isDefaultLibraryFile(d.File().FileName()) || isBuiltFile(d.File().FileName())) }) numTsconfigDiagnostics := core.CountWhere( diagnostics, - func(d *ast.Diagnostic) bool { + func(d T) bool { return d.File() != nil && isTsConfigFile(d.File().FileName()) }) // Verify we didn't miss any errors in total @@ -248,7 +248,7 @@ func iterateErrorBaseline(t *testing.T, inputFiles []*harnessutil.TestFile, inpu return result } -func formatLocation(file *ast.SourceFile, pos int, formatOpts *diagnosticwriter.FormattingOptions, writeWithStyleAndReset diagnosticwriter.FormattedWriter) string { +func formatLocation(file diagnosticwriter.FileLike, pos int, formatOpts *diagnosticwriter.FormattingOptions, writeWithStyleAndReset diagnosticwriter.FormattedWriter) string { var output strings.Builder diagnosticwriter.WriteLocation(&output, file, pos, formatOpts, writeWithStyleAndReset) return output.String() diff --git a/internal/testutil/tsbaseline/js_emit_baseline.go b/internal/testutil/tsbaseline/js_emit_baseline.go index fc4bced86a..9a16165a03 100644 --- a/internal/testutil/tsbaseline/js_emit_baseline.go +++ b/internal/testutil/tsbaseline/js_emit_baseline.go @@ -8,6 +8,7 @@ import ( "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/diagnosticwriter" "github.com/microsoft/typescript-go/internal/parser" "github.com/microsoft/typescript-go/internal/testutil/baseline" "github.com/microsoft/typescript-go/internal/testutil/harnessutil" @@ -59,7 +60,7 @@ func DoJSEmitBaseline( CompilerOptions: options.SourceFileAffecting(), }, file.Content, core.ScriptKindJSON) if len(fileParseResult.Diagnostics()) > 0 { - jsCode.WriteString(getErrorBaseline(t, []*harnessutil.TestFile{file}, fileParseResult.Diagnostics(), false /*pretty*/)) + jsCode.WriteString(GetErrorBaseline(t, []*harnessutil.TestFile{file}, diagnosticwriter.WrapASTDiagnostics(fileParseResult.Diagnostics()), diagnosticwriter.CompareASTDiagnostics, false /*pretty*/)) continue } } @@ -86,10 +87,11 @@ func DoJSEmitBaseline( if declFileCompilationResult != nil && len(declFileCompilationResult.declResult.Diagnostics) > 0 { jsCode.WriteString("\r\n\r\n//// [DtsFileErrors]\r\n") jsCode.WriteString("\r\n\r\n") - jsCode.WriteString(getErrorBaseline( + jsCode.WriteString(GetErrorBaseline( t, slices.Concat(tsConfigFiles, declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), - declFileCompilationResult.declResult.Diagnostics, + diagnosticwriter.WrapASTDiagnostics(declFileCompilationResult.declResult.Diagnostics), + diagnosticwriter.CompareASTDiagnostics, false, /*pretty*/ )) } diff --git a/internal/tsoptions/commandlineparser_test.go b/internal/tsoptions/commandlineparser_test.go index 9caf562d17..9cfd3be97b 100644 --- a/internal/tsoptions/commandlineparser_test.go +++ b/internal/tsoptions/commandlineparser_test.go @@ -190,7 +190,7 @@ func (f commandLineSubScenario) assertParseResult(t *testing.T) { // assert.DeepEqual(t, tsBaseline.watchoptions, newParsedWatchOptions) var formattedErrors strings.Builder - diagnosticwriter.WriteFormatDiagnostics(&formattedErrors, parsed.Errors, &diagnosticwriter.FormattingOptions{NewLine: "\n"}) + diagnosticwriter.WriteFormatDiagnostics(&formattedErrors, diagnosticwriter.FromASTDiagnostics(parsed.Errors), &diagnosticwriter.FormattingOptions{NewLine: "\n"}) newBaselineErrors := formattedErrors.String() // !!! @@ -281,7 +281,7 @@ func (f commandLineSubScenario) assertBuildParseResult(t *testing.T) { // assert.DeepEqual(t, tsBaseline.watchoptions, newParsedWatchOptions) var formattedErrors strings.Builder - diagnosticwriter.WriteFormatDiagnostics(&formattedErrors, parsed.Errors, &diagnosticwriter.FormattingOptions{NewLine: "\n"}) + diagnosticwriter.WriteFormatDiagnostics(&formattedErrors, diagnosticwriter.FromASTDiagnostics(parsed.Errors), &diagnosticwriter.FormattingOptions{NewLine: "\n"}) newBaselineErrors := formattedErrors.String() // !!! diff --git a/internal/tsoptions/tsconfigparsing_test.go b/internal/tsoptions/tsconfigparsing_test.go index 42f121b7ad..3e6fd35976 100644 --- a/internal/tsoptions/tsconfigparsing_test.go +++ b/internal/tsoptions/tsconfigparsing_test.go @@ -137,7 +137,7 @@ func TestParseConfigFileTextToJson(t *testing.T) { assert.NilError(t, writeJsonReadableText(&baselineContent, parsed), "Failed to write JSON text") baselineContent.WriteString("\n") baselineContent.WriteString("Errors::\n") - diagnosticwriter.FormatDiagnosticsWithColorAndContext(&baselineContent, errors, &diagnosticwriter.FormattingOptions{ + diagnosticwriter.FormatDiagnosticsWithColorAndContext(&baselineContent, diagnosticwriter.FromASTDiagnostics(errors), &diagnosticwriter.FormattingOptions{ NewLine: "\n", ComparePathsOptions: tspath.ComparePathsOptions{ CurrentDirectory: "/", @@ -863,7 +863,7 @@ func baselineParseConfigWith(t *testing.T, baselineFileName string, noSubmoduleB baselineContent.WriteString("FileNames::\n") baselineContent.WriteString(strings.Join(parsedConfigFileContent.ParsedConfig.FileNames, ",") + "\n") baselineContent.WriteString("Errors::\n") - diagnosticwriter.FormatDiagnosticsWithColorAndContext(&baselineContent, parsedConfigFileContent.Errors, &diagnosticwriter.FormattingOptions{ + diagnosticwriter.FormatDiagnosticsWithColorAndContext(&baselineContent, diagnosticwriter.FromASTDiagnostics(parsedConfigFileContent.Errors), &diagnosticwriter.FormattingOptions{ NewLine: "\r\n", ComparePathsOptions: tspath.ComparePathsOptions{ CurrentDirectory: basePath, diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics01.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics01.baseline new file mode 100644 index 0000000000..8f1d3f66b1 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics01.baseline @@ -0,0 +1,11 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,5): error TS1134: Variable declaration expected. +/a.js(1,8): error TS1109: Expression expected. + + +==== /a.js (2 errors) ==== + var ===; + ~~~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics02.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics02.baseline new file mode 100644 index 0000000000..212add171e --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics02.baseline @@ -0,0 +1,23 @@ +// === Syntax and Semantic Diagnostics === +/b.js(2,8): error TS8010: Type annotations can only be used in TypeScript files. +/b.js(3,17): error TS8010: Type annotations can only be used in TypeScript files. +/b.js(4,5): error TS1389: 'var' is not allowed as a variable declaration name. +/b.js(4,9): error TS1134: Variable declaration expected. +/b.js(4,11): error TS1134: Variable declaration expected. + + +==== /b.js (5 errors) ==== + var a = "a"; + var b: boolean = true; + ~~~~~~~ +!!! error TS8010: Type annotations can only be used in TypeScript files. + function foo(): string { } + ~~~~~~ +!!! error TS8010: Type annotations can only be used in TypeScript files. + var var = "c"; + ~~~ +!!! error TS1389: 'var' is not allowed as a variable declaration name. + ~ +!!! error TS1134: Variable declaration expected. + ~~~ +!!! error TS1134: Variable declaration expected. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics1.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics1.baseline new file mode 100644 index 0000000000..5a7ba4c6cd --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics1.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,1): error TS8002: 'import ... =' can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + import a = b; + ~~~~~~~~~~~~~ +!!! error TS8002: 'import ... =' can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics10.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics10.baseline new file mode 100644 index 0000000000..d60ddbbfbc --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics10.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,12): error TS8004: Type parameter declarations can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + function F() { } + ~ +!!! error TS8004: Type parameter declarations can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics11.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics11.baseline new file mode 100644 index 0000000000..3cf4c936c8 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics11.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,15): error TS8010: Type annotations can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + function F(): number { } + ~~~~~~ +!!! error TS8010: Type annotations can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics12.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics12.baseline new file mode 100644 index 0000000000..36bfd049fe --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics12.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,1): error TS8009: The 'declare' modifier can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + declare var v; + ~~~~~~~ +!!! error TS8009: The 'declare' modifier can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics13.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics13.baseline new file mode 100644 index 0000000000..1a8c0bb710 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics13.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,8): error TS8010: Type annotations can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + var v: () => number; + ~~~~~~~~~~~~ +!!! error TS8010: Type annotations can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics14.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics14.baseline new file mode 100644 index 0000000000..508f54f165 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics14.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,13): error TS1109: Expression expected. + + +==== /a.js (1 errors) ==== + Foo(); + ~ +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics15.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics15.baseline new file mode 100644 index 0000000000..24708d02fe --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics15.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,12): error TS8012: Parameter modifiers can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + function F(public p) { } + ~~~~~~ +!!! error TS8012: Parameter modifiers can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics16.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics16.baseline new file mode 100644 index 0000000000..0b9ef1cf2a --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics16.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,13): error TS8009: The '?' modifier can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + function F(p?) { } + ~ +!!! error TS8009: The '?' modifier can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics17.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics17.baseline new file mode 100644 index 0000000000..cce3890ced --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics17.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,15): error TS8010: Type annotations can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + function F(a: number) { } + ~~~~~~ +!!! error TS8010: Type annotations can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics18.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics18.baseline new file mode 100644 index 0000000000..d92d796144 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics18.baseline @@ -0,0 +1,19 @@ +// === Syntax and Semantic Diagnostics === +/a.js(4,5): error TS8009: The 'public' modifier can only be used in TypeScript files. +/b.js(2,8): error TS8010: Type annotations can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + class C { + x; // Regular property declaration allowed + static y; // static allowed + public z; // public not allowed + ~~~~~~ +!!! error TS8009: The 'public' modifier can only be used in TypeScript files. + } +==== /b.js (1 errors) ==== + class C { + x: number; // Types not allowed + ~~~~~~ +!!! error TS8010: Type annotations can only be used in TypeScript files. + } \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics19.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics19.baseline new file mode 100644 index 0000000000..ca4729a3dc --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics19.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,6): error TS8006: 'enum' declarations can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + enum E { } + ~ +!!! error TS8006: 'enum' declarations can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics2.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics2.baseline new file mode 100644 index 0000000000..3836f76141 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics2.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,1): error TS8003: 'export =' can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + export = b; + ~~~~~~~~~~~ +!!! error TS8003: 'export =' can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics3.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics3.baseline new file mode 100644 index 0000000000..948e4c0a3a --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics3.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,9): error TS8004: Type parameter declarations can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + class C { } + ~ +!!! error TS8004: Type parameter declarations can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics4.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics4.baseline new file mode 100644 index 0000000000..682bbd5d1c --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics4.baseline @@ -0,0 +1,11 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,1): error TS1044: 'public' modifier cannot appear on a module or namespace element. +/a.js(1,1): error TS8009: The 'public' modifier can only be used in TypeScript files. + + +==== /a.js (2 errors) ==== + public class C { } + ~~~~~~ +!!! error TS1044: 'public' modifier cannot appear on a module or namespace element. + ~~~~~~ +!!! error TS8009: The 'public' modifier can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics5.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics5.baseline new file mode 100644 index 0000000000..db5acfdd30 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics5.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,9): error TS8005: 'implements' clauses can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + class C implements D { } + ~~~~~~~~~~~~ +!!! error TS8005: 'implements' clauses can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics6.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics6.baseline new file mode 100644 index 0000000000..2f9b79d092 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics6.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,11): error TS8006: 'interface' declarations can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + interface I { } + ~ +!!! error TS8006: 'interface' declarations can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics7.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics7.baseline new file mode 100644 index 0000000000..eeddc9d453 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics7.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,8): error TS8006: 'module' declarations can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + module M { } + ~ +!!! error TS8006: 'module' declarations can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics8.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics8.baseline new file mode 100644 index 0000000000..0e3ac10c51 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics8.baseline @@ -0,0 +1,8 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,6): error TS8008: Type aliases can only be used in TypeScript files. + + +==== /a.js (1 errors) ==== + type a = b; + ~ +!!! error TS8008: Type aliases can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics9.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics9.baseline new file mode 100644 index 0000000000..83177f4967 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/getJavaScriptSyntacticDiagnostics9.baseline @@ -0,0 +1,11 @@ +// === Syntax and Semantic Diagnostics === +/a.js(1,1): error TS1044: 'public' modifier cannot appear on a module or namespace element. +/a.js(1,1): error TS8009: The 'public' modifier can only be used in TypeScript files. + + +==== /a.js (2 errors) ==== + public function F() { } + ~~~~~~ +!!! error TS1044: 'public' modifier cannot appear on a module or namespace element. + ~~~~~~ +!!! error TS8009: The 'public' modifier can only be used in TypeScript files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/rewriteRelativeImportExtensionsProjectReferences1.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/rewriteRelativeImportExtensionsProjectReferences1.baseline new file mode 100644 index 0000000000..d1c8c10329 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/rewriteRelativeImportExtensionsProjectReferences1.baseline @@ -0,0 +1,10 @@ +// === Syntax and Semantic Diagnostics === +/packages/main/src/index.ts(1,16): error TS2878: This import path is unsafe to rewrite because it resolves to another project, and the relative path between the projects' output files is not the same as the relative path between its input files. + + +==== /packages/common/src/index.ts (0 errors) ==== + export {}; +==== /packages/main/src/index.ts (1 errors) ==== + import {} from "../../common/src/index.ts"; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2878: This import path is unsafe to rewrite because it resolves to another project, and the relative path between the projects' output files is not the same as the relative path between its input files. \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/rewriteRelativeImportExtensionsProjectReferences2.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/rewriteRelativeImportExtensionsProjectReferences2.baseline new file mode 100644 index 0000000000..786b9b4a67 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/rewriteRelativeImportExtensionsProjectReferences2.baseline @@ -0,0 +1,7 @@ +// === Syntax and Semantic Diagnostics === + + +==== /src/compiler/parser.ts (0 errors) ==== + export {}; +==== /src/services/services.ts (0 errors) ==== + import {} from "../compiler/parser.ts"; \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/rewriteRelativeImportExtensionsProjectReferences3.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/rewriteRelativeImportExtensionsProjectReferences3.baseline new file mode 100644 index 0000000000..786b9b4a67 --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/rewriteRelativeImportExtensionsProjectReferences3.baseline @@ -0,0 +1,7 @@ +// === Syntax and Semantic Diagnostics === + + +==== /src/compiler/parser.ts (0 errors) ==== + export {}; +==== /src/services/services.ts (0 errors) ==== + import {} from "../compiler/parser.ts"; \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/typeErrorAfterStringCompletionsInNestedCall2.baseline b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/typeErrorAfterStringCompletionsInNestedCall2.baseline new file mode 100644 index 0000000000..3a2bd6eedd --- /dev/null +++ b/testdata/baselines/reference/fourslash/syntaxandSemanticDiagnostics/typeErrorAfterStringCompletionsInNestedCall2.baseline @@ -0,0 +1,68 @@ +// === Syntax and Semantic Diagnostics === +/typeErrorAfterStringCompletionsInNestedCall2.ts(40,5): error TS2322: Type '{ ({ event }: { event: { type: "FOO"; }; }): void; _out_TEvent?: { type: "BARx"; } | undefined; }' is not assignable to type 'ActionFunction<{ type: "FOO"; }, { type: "FOO"; } | { type: "BAR"; }>'. + Types of property '_out_TEvent' are incompatible. + Type '{ type: "BARx"; } | undefined' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; } | undefined'. + Type '{ type: "BARx"; }' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; } | undefined'. + Type '{ type: "BARx"; }' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; }'. + Type '{ type: "BARx"; }' is not assignable to type '{ type: "BAR"; }'. + Types of property 'type' are incompatible. + Type '"BARx"' is not assignable to type '"BAR"'. + + +==== /typeErrorAfterStringCompletionsInNestedCall2.ts (1 errors) ==== + type ActionFunction< + TExpressionEvent extends { type: string }, + out TEvent extends { type: string } + > = { + ({ event }: { event: TExpressionEvent }): void; + _out_TEvent?: TEvent; + }; + + interface MachineConfig { + types: { + events: TEvent; + }; + on: { + [K in TEvent["type"]]?: ActionFunction< + Extract, + TEvent + >; + }; + } + + declare function raise< + TExpressionEvent extends { type: string }, + TEvent extends { type: string } + >( + resolve: ({ event }: { event: TExpressionEvent }) => TEvent + ): { + ({ event }: { event: TExpressionEvent }): void; + _out_TEvent?: TEvent; + }; + + declare function createMachine( + config: MachineConfig + ): void; + + createMachine({ + types: { + events: {} as { type: "FOO" } | { type: "BAR" }, + }, + on: { + FOO: raise(({ event }) => { + ~~~ +!!! error TS2322: Type '{ ({ event }: { event: { type: "FOO"; }; }): void; _out_TEvent?: { type: "BARx"; } | undefined; }' is not assignable to type 'ActionFunction<{ type: "FOO"; }, { type: "FOO"; } | { type: "BAR"; }>'. +!!! error TS2322: Types of property '_out_TEvent' are incompatible. +!!! error TS2322: Type '{ type: "BARx"; } | undefined' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; } | undefined'. +!!! error TS2322: Type '{ type: "BARx"; }' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; } | undefined'. +!!! error TS2322: Type '{ type: "BARx"; }' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; }'. +!!! error TS2322: Type '{ type: "BARx"; }' is not assignable to type '{ type: "BAR"; }'. +!!! error TS2322: Types of property 'type' are incompatible. +!!! error TS2322: Type '"BARx"' is not assignable to type '"BAR"'. +!!! related TS2322 /typeErrorAfterStringCompletionsInNestedCall2.ts:13:7: The expected type comes from property 'FOO' which is declared here on type '{ BAR?: ActionFunction<{ type: "BAR"; }, { type: "FOO"; } | { type: "BAR"; }> | undefined; FOO?: ActionFunction<{ type: "FOO"; }, { type: "FOO"; } | { type: "BAR"; }> | undefined; }' + return { + type: "BARx" as const, + }; + }), + }, + }); \ No newline at end of file