Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
693422c
initial lsp
aspeddro Dec 1, 2024
34bcd22
Merge branch 'master' into lsp
aspeddro Dec 30, 2024
7f209ef
Merge branch 'master' into lsp
aspeddro Mar 17, 2025
e203450
Merge branch 'master' into lsp
aspeddro Jun 20, 2025
e1273d6
Merge branch 'master' into lsp
aspeddro Apr 28, 2026
129af21
update
aspeddro Apr 29, 2026
6b65a25
add state
aspeddro Apr 30, 2026
e2989d0
Extract server I/O into Server module and simplify handlers
aspeddro May 12, 2026
a99abc6
Add parse_implementation_from_source and refactor LSP server
aspeddro May 12, 2026
2529f30
Merge branch 'master' into lsp
aspeddro May 13, 2026
365836c
Split LSP into bin/src layout and add hover integration test
aspeddro May 14, 2026
1692629
Refactor analysis to decouple I/O from core logic
aspeddro May 16, 2026
743126f
Delegate hover logic to `Analysis.Commands.hover`
aspeddro May 16, 2026
0e522be
Rename `tokenModifiersString` to `tokenModifiers` with correct type
aspeddro May 16, 2026
9da83c8
Merge branch 'master' into lsp
aspeddro May 22, 2026
9df9079
Update dune-project
aspeddro May 22, 2026
1b65e21
Merge branch 'master' into lsp
aspeddro May 30, 2026
768a040
Merge branch 'master' into lsp
aspeddro May 31, 2026
29cd3d7
Refactor LSP test infrastructure
aspeddro May 31, 2026
a20da0d
ci: add linux-headers
aspeddro May 31, 2026
5a57bbc
ci: add linux-headers-generic
aspeddro May 31, 2026
9442c4b
ci: linux-libc-dev
aspeddro May 31, 2026
64dffd8
ci: add build-essential
aspeddro May 31, 2026
e0f6296
ci: add build-essential and linux-libc-dev
aspeddro May 31, 2026
8cebaf2
ci: update cache version to v5
aspeddro May 31, 2026
85138b1
ci: make Linux headers visible to musl-gcc
aspeddro Jun 1, 2026
ee6de86
Merge branch 'master' into lsp
aspeddro Jun 1, 2026
66b69fe
ci: support arm and disable test for build for ocaml 5.0
aspeddro Jun 1, 2026
c50f613
makefile: add test-lsp
aspeddro Jun 2, 2026
fd83f06
Merge branch 'master' into lsp
aspeddro Jun 3, 2026
890fd16
Add LSP compiler diagnostics and file watching
aspeddro Jun 5, 2026
39639c6
Comment to add more compiler log test
aspeddro Jun 6, 2026
5e002cb
ci: add lsp test step
aspeddro Jun 6, 2026
5781622
fix opam install ppx_expect
aspeddro Jun 6, 2026
728c4bf
ci: run test inside opam `opam exec --`
aspeddro Jun 6, 2026
33edc85
lsp: disable hover supports_markdown_links for now
aspeddro Jun 6, 2026
75a6123
Move Eio_main setup to LSP executable
aspeddro Jun 6, 2026
126f67a
ci: skip lsp tests on Windows
aspeddro Jun 6, 2026
5d14a57
Expand LSP request handling and diagnostics
aspeddro Jun 7, 2026
015a2d2
Enforce LSP server lifecycle
aspeddro Jun 7, 2026
bbcb7b9
analysis refactor: remove global state `Shared_types.state`
aspeddro Jun 7, 2026
b63a60f
lsp: use analysis state
aspeddro Jun 7, 2026
88190b9
Revert "analysis refactor: remove global state `Shared_types.state`"
aspeddro Jun 8, 2026
4632fab
Merge branch 'master' into lsp
aspeddro Jun 8, 2026
3be179c
analysis: add state_to_yojson
aspeddro Jun 8, 2026
9bc661c
lsp: refactor load_full
aspeddro Jun 8, 2026
8ec52ae
add minimal param to State.to_yojson
aspeddro Jun 9, 2026
22a5eeb
Makefile: skip test on Windows and update ci
aspeddro Jun 9, 2026
16e4fb2
refactor: add `discover_subpackages_and_populate`
aspeddro Jun 10, 2026
2a1bf04
Merge branch 'master' into lsp
aspeddro Jun 10, 2026
67a741f
fix type error from latest master merge
aspeddro Jun 10, 2026
d9ca156
Improve LSP workspace initialization and package resolution
aspeddro Jun 10, 2026
ac07b29
Implement code_actions.ml
aspeddro Jun 13, 2026
ba293ab
lsp format: use `rescript format` command
aspeddro Jun 13, 2026
87e280d
Add code actions from compiler log
aspeddro Jun 13, 2026
9f6c805
Add LSP configuration handling
aspeddro Jun 14, 2026
b4e797c
Circular dependency diagnostics: expand end character
aspeddro Jun 14, 2026
1566ae2
Add LSP compiler config parsing
aspeddro Jun 14, 2026
fc76cba
add code actions and custom requests
aspeddro Jun 14, 2026
2fae316
fix dune tests
aspeddro Jun 14, 2026
0107015
code action: check for window/showDocuent support
aspeddro Jun 15, 2026
85942cd
Add LSP file navigation commands
aspeddro Jun 16, 2026
2bcd312
chore: renames and minor fixes
aspeddro Jun 16, 2026
879995d
add todo comments and minor fixes
aspeddro Jun 16, 2026
e246eef
add lsp.md
aspeddro Jun 16, 2026
b9d2730
Update lsp.md
aspeddro Jun 16, 2026
138172b
Merge branch 'master' into lsp
aspeddro Jun 17, 2026
55d0431
Omit empty document symbol children
aspeddro Jun 17, 2026
4194057
Fix lsp document symbol
aspeddro Jun 17, 2026
cc7ed4f
Update lsp.md
aspeddro Jun 17, 2026
de08232
Add server notification `rescript/compilationFinished`
aspeddro Jun 17, 2026
1152368
compiler_log: add warning number
aspeddro Jun 17, 2026
d2afded
add warning number in diagnostic message
aspeddro Jun 18, 2026
d3cfd95
Add more test to compiler log parser
aspeddro Jun 18, 2026
11ac541
Add cli
aspeddro Jun 18, 2026
1ccc66e
fix Neovim bug document symbol
aspeddro Jun 19, 2026
94d0d87
minimal refactor on rescript_language_server.ml
aspeddro Jun 19, 2026
2943e98
support `workspace/codeLens/refresh`
aspeddro Jun 19, 2026
0c4e43a
Resolve runtime packages from workspace node_modules
aspeddro Jun 19, 2026
47bae3b
build system: remove `RESCRIPT_RUNTIME` env var
aspeddro Jun 19, 2026
5133b39
Make Configuration unstrict
aspeddro Jun 19, 2026
a41e580
add more log message for invalid settings
aspeddro Jun 19, 2026
9a1bbb8
dump server state: add configuration and order elements
aspeddro Jun 19, 2026
08d0f48
Server request settings from item `rescript.settings`
aspeddro Jun 19, 2026
e0dcc88
move Exit to end
aspeddro Jun 19, 2026
d8e0e67
Support TextDocumentDiagnostic and improve TextDocumentDidOpen
aspeddro Jun 19, 2026
7c7c209
Keep diagnostic sources separate
aspeddro Jun 19, 2026
5813157
Use sourcedirs for initial compiler diagnostics
aspeddro Jun 19, 2026
393a6c3
remove double newline from message diagnostic
aspeddro Jun 19, 2026
dd758b8
update analysis tests
aspeddro Jun 19, 2026
81b6f1d
refactor compiler log parser
aspeddro Jun 20, 2026
d18955c
cli, print to stderr
aspeddro Jun 20, 2026
abf9743
refactor compiler log to use option for range
aspeddro Jun 20, 2026
e3eab6e
Update compiler log tests snapshots
aspeddro Jun 20, 2026
0eef9a4
Update compiler_config.ml
aspeddro Jun 20, 2026
07cfb97
Remove comment from code_actions.ml
aspeddro Jun 20, 2026
3737687
Avoid duplicate syntax diagnostics on document changes
aspeddro Jun 20, 2026
1fd9414
minor fixes: add todo comment and fix typos in messages
aspeddro Jun 20, 2026
acb52a5
workspace/configuration section must use `rescript`
aspeddro Jun 20, 2026
2f10c7f
Improve todo comments
aspeddro Jun 20, 2026
f8c0d4a
Update lsp.md
aspeddro Jun 20, 2026
42fe2ae
Update lsp.md
aspeddro Jun 20, 2026
be81434
Refactor cmt_viewer.dump for serve-side
aspeddro Jun 20, 2026
c80ae00
Refactor execute commands. Move logic to module execute_commands.ml
aspeddro Jun 21, 2026
6ddcce5
Move format logic to module Formatter.ml
aspeddro Jun 21, 2026
2d411c9
Refactor code, better error messages
aspeddro Jun 21, 2026
0f16ff5
Analysis cmt dump return a string instead a option
aspeddro Jun 21, 2026
a5f8c82
Update lsp.md
aspeddro Jun 21, 2026
b712f28
minor fixes
aspeddro Jun 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 63 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,13 @@ jobs:
exe-suffix: ".exe"
dune-profile: release

# Disable for now. eio and eio_main require ocaml >= 5.2.0
# Verify that the compiler still builds with the oldest OCaml version we support.
- os: ubuntu-24.04
ocaml_compiler: ocaml-variants.5.0.0+options,ocaml-option-static
node-target: linux-x64
rust-target: x86_64-unknown-linux-musl
dune-profile: static
# - os: ubuntu-24.04
# ocaml_compiler: ocaml-variants.5.0.0+options,ocaml-option-static
# node-target: linux-x64
# rust-target: x86_64-unknown-linux-musl
# dune-profile: static

runs-on: ${{matrix.os}}

Expand Down Expand Up @@ -107,7 +108,7 @@ jobs:
# https://github.com/ocaml/setup-ocaml/blob/2f57267f071bc8547dfcb9433ff21d44fffef190/packages/setup-ocaml/src/unix.ts#L48
# plus OPAM wants cmake
packages: bubblewrap darcs g++-multilib gcc-multilib mercurial musl-tools rsync cmake
version: v4
version: v5

- name: Restore rewatch build cache
id: rewatch-build-cache
Expand Down Expand Up @@ -176,6 +177,56 @@ jobs:
C:\.opam
key: ${{ env.opam_cache_key }}

# The static OCaml switch uses musl-gcc. linux-libc-dev installs Linux
# headers under /usr/include, but musl-gcc searches the musl include dir.
# Link the Linux headers into musl's include path so packages with C stubs
# such as uring can include <linux/...> headers.
- name: Make Linux headers visible to musl-gcc
if: runner.os == 'Linux'
run: |
set -eux

# Get the GNU multiarch triplet for the current machine.
# Examples:
# x86_64-linux-gnu
# aarch64-linux-gnu
GNU_MULTIARCH="$(gcc -print-multiarch)"

# Convert the GNU triplet into the musl include directory name.
# Examples:
# x86_64-linux-gnu -> x86_64-linux-musl
# aarch64-linux-gnu -> aarch64-linux-musl
MUSL_MULTIARCH="${GNU_MULTIARCH%-gnu}-musl"

# musl-gcc searches this include directory.
MUSL_INCLUDE="/usr/include/${MUSL_MULTIARCH}"

# Linux arch-specific asm headers are installed here by linux-libc-dev.
GNU_ASM="/usr/include/${GNU_MULTIARCH}/asm"

# Ensure the musl include directory exists.
sudo mkdir -p "$MUSL_INCLUDE"

# Remove old paths first.
# This avoids silently keeping broken/stale symlinks from previous runs.
sudo rm -rf "$MUSL_INCLUDE/linux"
sudo rm -rf "$MUSL_INCLUDE/asm"
sudo rm -rf "$MUSL_INCLUDE/asm-generic"

# Expose Linux UAPI headers to musl-gcc.
# This fixes packages that include headers like <linux/swab.h>.
sudo ln -s /usr/include/linux "$MUSL_INCLUDE/linux"

# Expose architecture-specific asm headers to musl-gcc.
sudo ln -s "$GNU_ASM" "$MUSL_INCLUDE/asm"

# Expose generic asm headers used by many Linux headers.
sudo ln -s /usr/include/asm-generic "$MUSL_INCLUDE/asm-generic"

# Smoke test: fail early if musl-gcc still cannot find Linux headers.
echo '#include <linux/swab.h>' > /tmp/test.c
musl-gcc -c /tmp/test.c -o /tmp/test.o

- name: Use OCaml ${{matrix.ocaml_compiler}}
uses: ocaml/setup-ocaml@v3.6.0
if: steps.cache-opam-env.outputs.cache-hit != 'true'
Expand Down Expand Up @@ -326,6 +377,11 @@ jobs:
if: runner.os != 'Windows'
run: make -C tests/gentype_tests/typescript-react-example clean test

# The Makefile skip some tests on Windows because OCaml Eio process operations is not supported on Windows yet
# Eio.Stdenv.process_mgr raise a error, see https://github.com/ocaml-multicore/eio/blob/37d6e67f7e25b43e4a66574ed98838c79f1a21b4/lib_eio_windows/eio_windows.ml#L36
- name: Run LSP tests
run: opam exec -- make test-lsp

# On Windows, after running setup-ocaml (if it wasn't cached yet or the cache couldn't be restored),
# Cygwin bash is used instead of Git Bash for Windows, breaking the rewatch tests.
# So we need to adjust the path to bring back Git Bash for Windows.
Expand Down Expand Up @@ -604,7 +660,7 @@ jobs:
uses: actions/checkout@v6
- name: Run make in dev container
uses: devcontainers/ci@v0.3
with:
with:
push: never
runCmd: make

Expand Down
20 changes: 19 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,25 @@ test-gentype: lib
test-rewatch: lib
./rewatch/tests/suite.sh $(RESCRIPT_EXE)

test-all: test test-gentype test-analysis test-tools test-rewatch
test-lsp: lib
@for dir in tests/lsp_tests/*-workspace/; do \
[ -d "$$dir" ] || continue; \
echo "Building $${dir%/}..."; \
( cd "$$dir" && yarn clean && yarn build ); \
done
@dune runtest
@if [ "$$OS" = "Windows_NT" ]; then \
echo "Skipping lsp-tests executable on Windows"; \
else \
dune exec -- lsp-tests; \
fi
@if [ -n "$$(git ls-files --modified tests/lsp_tests/**/*.expected)" ]; then \
echo "The lsp_tests snapshot doesn't match. Double check that the output is correct, run 'make test-lsp' and stage the diff"; \
git --no-pager diff tests/lsp_tests/**/*.expected; \
exit 1; \
fi \

test-all: test test-gentype test-analysis test-tools test-rewatch test-lsp

# Playground

Expand Down
2 changes: 1 addition & 1 deletion analysis/bin/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ let main () =
| [_; "format"; path] -> Cli.format ~path
| [_; "test"; path] -> Cli.test ~state ~path
| [_; "cmt"; rescript_json; cmt_path] ->
Cmt_viewer.dump ~state rescript_json cmt_path
Cli.dump_cmt ~state ~rescript_json ~cmt_path
| args when List.mem "-h" args || List.mem "--help" args -> prerr_endline help
| _ ->
prerr_endline help;
Expand Down
40 changes: 10 additions & 30 deletions analysis/src/build_system.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,19 @@ let namespaced_name namespace name =

let ( /+ ) = Filename.concat

(*
Editor tooling can more accurately resolve the runtime path and will try and pass it via an environment variable.
Example path: "test-stdlib/node_modules/.pnpm/@rescript+runtime@12.0.0-rc.4/node_modules/@rescript/runtime"
*)

let get_runtime_dir root_path =
match !Cfg.is_doc_gen_from_compiler with
| false -> (
(* First check RESCRIPT_RUNTIME environment variable, like bsc does *)
match Sys.getenv_opt "RESCRIPT_RUNTIME" with
| Some env_path ->
if Debug.verbose () then
Printf.printf "[getRuntimeDir] Using RESCRIPT_RUNTIME=%s\n" env_path;
Some env_path
| None -> (
let result =
Module_resolution.resolve_node_module_path ~start_path:root_path
"@rescript/runtime"
in
match result with
| Some path ->
if Debug.verbose () then
Printf.printf "[getRuntimeDir] Resolved via node_modules: %s\n" path;
Some path
| None ->
let message = "@rescript/runtime could not be found" in
Log.log message;
if Debug.verbose () then
Printf.printf
"[getRuntimeDir] Failed to resolve @rescript/runtime from \
rootPath=%s\n"
root_path;
None))
let result =
Module_resolution.resolve_node_module_path ~start_path:root_path
"@rescript/runtime"
in
match result with
| Some path -> Some path
| None ->
let message = "@rescript/runtime could not be found" in
Log.log message;
None)
| true -> Some root_path

let get_lib_bs path = Files.if_exists (path /+ "lib" /+ "bs")
Expand Down
19 changes: 19 additions & 0 deletions analysis/src/cli.ml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,25 @@ let create_interface ~path ~cmi_file =
in
Printf.printf "%s" result

let dump_cmt ~state ~rescript_json ~cmt_path =
let uri = Uri.from_path (Filename.remove_extension cmt_path ^ ".res") in
let package =
let uri = Uri.from_path rescript_json in
Packages.get_package ~state ~uri
in
match package with
| None -> print_null ()
| Some package -> (
let module_name =
Build_system.namespaced_name package.namespace
(Find_files.get_name cmt_path)
in
match Cmt.full_for_cmt ~module_name ~package ~uri cmt_path with
| None -> print_null ()
| Some full ->
let content = Cmt_viewer.dump ~full ~filter_for_position:None in
Printf.printf "%s" content)

let test ~state ~path =
Uri.strip_path := true;
match Files.read_file path with
Expand Down
Loading
Loading