vendor tsgo

This commit is contained in:
2026-07-09 16:50:43 -04:00
parent c06ea2e5a4
commit 98978e4930
5804 changed files with 1556156 additions and 101 deletions

View File

@@ -0,0 +1,93 @@
package lsp_test
import (
"context"
"io"
"strings"
"testing"
"github.com/microsoft/typescript-go/internal/bundled"
"github.com/microsoft/typescript-go/internal/lsp"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil/lsptestutil"
"github.com/microsoft/typescript-go/internal/vfs/vfstest"
"gotest.tools/v3/assert"
)
// TestSemanticTokensCRLF reproduces a crash where semantic tokens panics with
// "token spans multiple lines" when the editor opens a file with CRLF line endings
// but the project originally loaded the file from disk with LF line endings.
//
// The SourceFile AST keeps positions from the LF text, but the converter's
// line map is recomputed from the CRLF overlay, causing a mismatch.
func TestSemanticTokensCRLF(t *testing.T) {
t.Parallel()
if !bundled.Embedded {
t.Skip("bundled files are not embedded")
}
// Enough lines so the cumulative \r\n vs \n offset difference
// causes an LF-based position to land on a \r in the CRLF text.
fileOnDisk := "var x\nvar x\nvar x\nvar x\nvar x\nvar x\nconst a = 1\n"
fileFromEditor := strings.ReplaceAll(fileOnDisk, "\n", "\r\n")
files := map[string]string{
"/home/projects/tsconfig.json": `{}`,
"/home/projects/test.ts": fileOnDisk,
"/home/projects/other.ts": "export {}",
}
fs := bundled.WrapFS(vfstest.FromMap(files, false))
onServerRequest := func(_ context.Context, req *lsproto.RequestMessage) *lsproto.ResponseMessage {
if req.Method == lsproto.MethodClientRegisterCapability || req.Method == lsproto.MethodClientUnregisterCapability {
return &lsproto.ResponseMessage{ID: req.ID, JSONRPC: req.JSONRPC, Result: lsproto.Null{}}
}
return nil
}
client, closeClient := lsptestutil.NewLSPClient(t, lsp.ServerOptions{
Err: io.Discard, Cwd: "/home/projects", FS: fs, DefaultLibraryPath: bundled.LibPath(),
}, onServerRequest)
t.Cleanup(func() { _ = closeClient() })
initMsg, _, ok := lsptestutil.SendRequest(t, client, lsproto.InitializeInfo, &lsproto.InitializeParams{
Capabilities: &lsproto.ClientCapabilities{
TextDocument: &lsproto.TextDocumentClientCapabilities{
SemanticTokens: &lsproto.SemanticTokensClientCapabilities{
Requests: &lsproto.ClientSemanticTokensRequestOptions{
Full: &lsproto.BooleanOrClientSemanticTokensRequestFullDelta{Boolean: new(true)},
},
TokenTypes: []string{"namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator"},
TokenModifiers: []string{"declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary", "local"},
},
},
},
})
assert.Assert(t, ok && initMsg.AsResponse().Error == nil, "Initialize failed")
lsptestutil.SendNotification(t, client, lsproto.InitializedInfo, &lsproto.InitializedParams{})
<-client.Server.InitComplete()
// Open another project file to force the project to load test.ts from disk (LF).
otherUri := lsproto.DocumentUri("file:///home/projects/other.ts")
lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{
TextDocument: &lsproto.TextDocumentItem{Uri: otherUri, LanguageId: "typescript", Text: files["/home/projects/other.ts"]},
})
msg1, _, _ := lsptestutil.SendRequest(t, client, lsproto.TextDocumentSemanticTokensFullInfo, &lsproto.SemanticTokensParams{
TextDocument: lsproto.TextDocumentIdentifier{Uri: otherUri},
})
assert.Assert(t, msg1.AsResponse().Error == nil, "Initial request failed")
// Open test.ts with CRLF content; the project already parsed it from disk (LF).
uri := lsproto.DocumentUri("file:///home/projects/test.ts")
lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{
TextDocument: &lsproto.TextDocumentItem{Uri: uri, LanguageId: "typescript", Text: fileFromEditor},
})
// This panics: AST positions are LF-based but the line map is CRLF-based.
msg, _, _ := lsptestutil.SendRequest(t, client, lsproto.TextDocumentSemanticTokensFullInfo, &lsproto.SemanticTokensParams{
TextDocument: lsproto.TextDocumentIdentifier{Uri: uri},
})
if msg.AsResponse().Error != nil {
t.Fatalf("Semantic tokens request failed: %s", msg.AsResponse().Error.Message)
}
}