Skip to content

Commit a1586f0

Browse files
authored
refactor: refactor language server (#263)
1 parent df2caed commit a1586f0

File tree

6 files changed

+730
-211
lines changed

6 files changed

+730
-211
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
name: Test Go
2222
runs-on: ${{ matrix.runner }}
2323
strategy:
24+
fail-fast: false
2425
matrix:
2526
runner:
2627
[
@@ -64,6 +65,7 @@ jobs:
6465
name: Test npm packages
6566
runs-on: ${{ matrix.os }}
6667
strategy:
68+
fail-fast: false
6769
matrix:
6870
os: [rspack-ubuntu-22.04-large, windows-latest]
6971
go-version: ['1.24.1']

cmd/rslint/lsp.go

Lines changed: 88 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,103 @@
1+
// modified based on https://github.com/microsoft/typescript-go/blob/cedc0cbe6c188f9bfe6a51af00c79be48c9ab74d/cmd/tsgo/lsp.go#L1
12
package main
23

34
import (
4-
"context"
5-
"io"
6-
"log"
75
"os"
6+
"runtime"
87

9-
"github.com/sourcegraph/jsonrpc2"
8+
"github.com/microsoft/typescript-go/shim/bundled"
9+
"github.com/microsoft/typescript-go/shim/core"
10+
"github.com/microsoft/typescript-go/shim/tspath"
11+
"github.com/microsoft/typescript-go/shim/vfs/osvfs"
1012
"github.com/web-infra-dev/rslint/internal/lsp"
13+
"github.com/web-infra-dev/rslint/internal/utils"
1114
)
1215

13-
func runLSP() int {
14-
log.SetOutput(os.Stderr) // Send logs to stderr so they don't interfere with LSP communication
16+
func runLSP(args []string) int {
1517

16-
server := lsp.NewLSPServer()
18+
fs := bundled.WrapFS(osvfs.FS())
19+
defaultLibraryPath := bundled.LibPath()
20+
typingsLocation := getGlobalTypingsCacheLocation()
1721

18-
// Create a simple ReadWriteCloser from stdin/stdout
19-
stream := &struct {
20-
io.Reader
21-
io.Writer
22-
io.Closer
23-
}{
24-
Reader: os.Stdin,
25-
Writer: os.Stdout,
26-
Closer: os.Stdin,
22+
s := lsp.NewServer(&lsp.ServerOptions{
23+
In: lsp.ToReader(os.Stdin),
24+
Out: lsp.ToWriter(os.Stdout),
25+
Err: os.Stderr,
26+
Cwd: utils.Must(os.Getwd()),
27+
FS: fs,
28+
DefaultLibraryPath: defaultLibraryPath,
29+
TypingsLocation: typingsLocation,
30+
})
31+
32+
if err := s.Run(); err != nil {
33+
return 1
2734
}
35+
return 0
36+
}
2837

29-
// Create connection using stdin/stdout
30-
conn := jsonrpc2.NewConn(
31-
context.Background(),
32-
jsonrpc2.NewBufferedStream(stream, jsonrpc2.VSCodeObjectCodec{}),
33-
jsonrpc2.HandlerWithError(server.Handle),
34-
)
38+
func getGlobalTypingsCacheLocation() string {
39+
switch runtime.GOOS {
40+
case "windows":
41+
return tspath.CombinePaths(tspath.CombinePaths(getWindowsCacheLocation(), "Microsoft/TypeScript"), core.VersionMajorMinor())
42+
case "openbsd", "freebsd", "netbsd", "darwin", "linux", "android":
43+
return tspath.CombinePaths(tspath.CombinePaths(getNonWindowsCacheLocation(), "typescript"), core.VersionMajorMinor())
44+
default:
45+
panic("unsupported platform: " + runtime.GOOS)
46+
}
47+
}
3548

36-
// Wait for connection to close
37-
<-conn.DisconnectNotify()
49+
func getWindowsCacheLocation() string {
50+
basePath, err := os.UserCacheDir()
51+
if err != nil {
52+
if basePath, err = os.UserConfigDir(); err != nil {
53+
if basePath, err = os.UserHomeDir(); err != nil {
54+
if userProfile := os.Getenv("USERPROFILE"); userProfile != "" {
55+
basePath = userProfile
56+
} else if homeDrive, homePath := os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"); homeDrive != "" && homePath != "" {
57+
basePath = homeDrive + homePath
58+
} else {
59+
basePath = os.TempDir()
60+
}
61+
}
62+
}
63+
}
64+
return basePath
65+
}
3866

39-
return 0
67+
func getNonWindowsCacheLocation() string {
68+
if xdgCacheHome := os.Getenv("XDG_CACHE_HOME"); xdgCacheHome != "" {
69+
return xdgCacheHome
70+
}
71+
const platformIsDarwin = runtime.GOOS == "darwin"
72+
var usersDir string
73+
if platformIsDarwin {
74+
usersDir = "Users"
75+
} else {
76+
usersDir = "home"
77+
}
78+
homePath, err := os.UserHomeDir()
79+
if err != nil {
80+
if home := os.Getenv("HOME"); home != "" {
81+
homePath = home
82+
} else {
83+
var userName string
84+
if logName := os.Getenv("LOGNAME"); logName != "" {
85+
userName = logName
86+
} else if user := os.Getenv("USER"); user != "" {
87+
userName = user
88+
}
89+
if userName != "" {
90+
homePath = "/" + usersDir + "/" + userName
91+
} else {
92+
homePath = os.TempDir()
93+
}
94+
}
95+
}
96+
var cacheFolder string
97+
if platformIsDarwin {
98+
cacheFolder = "Library/Caches"
99+
} else {
100+
cacheFolder = ".cache"
101+
}
102+
return tspath.CombinePaths(homePath, cacheFolder)
40103
}

cmd/rslint/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func runMain() int {
2020
switch args[0] {
2121
case "--lsp":
2222
// run in LSP mode for Language Server
23-
return runLSP()
23+
return runLSP(args[1:])
2424
case "--api":
2525
// run in API mode for JS API
2626
return runAPI()

0 commit comments

Comments
 (0)