Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
- Remove dead and unreachable compiler error and warning variants; add fixtures for the ones found to be reachable. https://github.com/rescript-lang/rescript/pull/8459
- Convert OCaml codebase to snake case format. https://github.com/rescript-lang/rescript/pull/8456
- Analysis refactor: remove global state `Shared_types.state`. https://github.com/rescript-lang/rescript/pull/8465

- Refactor analysis CLI helpers to use source input. https://github.com/rescript-lang/rescript/pull/8466

# 13.0.0-alpha.4

Expand Down
9 changes: 5 additions & 4 deletions analysis/bin/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ let main () =
Cli.type_definition ~state ~path
~pos:(int_of_string line, int_of_string col)
~debug
| [_; "documentSymbol"; path] -> Document_symbol.command ~path
| [_; "documentSymbol"; path] -> Cli.document_symbol ~path
| [_; "hover"; path; line; col; current_file; supports_markdown_links] ->
Cli.hover ~state ~path
~pos:(int_of_string line, int_of_string col)
Expand All @@ -174,6 +174,9 @@ let main () =
| "true" -> true
| _ -> false)
| [_; "inlayHint"; path; line_start; line_end; max_length] ->
let max_length =
try Some (int_of_string max_length) with Failure _ -> None
in
Cli.inlayhint ~state ~path
~pos:(int_of_string line_start, int_of_string line_end)
~max_length ~debug
Expand Down Expand Up @@ -214,9 +217,7 @@ let main () =
| [_; "semanticTokens"; current_file] ->
Cli.semantic_tokens ~path:current_file
| [_; "createInterface"; path; cmi_file] ->
`String (Create_interface.command ~state ~path ~cmi_file)
|> Yojson.Safe.pretty_to_string ~std:true
|> print_endline
Cli.create_interface ~path ~cmi_file
| [_; "format"; path] -> Cli.format ~path
| [_; "test"; path] -> Cli.test ~state ~path
| [_; "cmt"; rescript_json; cmt_path] ->
Expand Down
34 changes: 28 additions & 6 deletions analysis/src/cli.ml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ let code_action ~state ~path ~start_pos ~end_pos ~current_file ~debug =
| None -> print_null ()
| Some source ->
Xform.extract_code_actions ~state ~path ~start_pos ~end_pos ~source
~kind_file ~debug
~kind_file
~full:(Cmt.load_full_cmt_from_path ~state ~path)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 Badge Avoid loading CMTs for interface-only code actions

When current_file is a .resi, Xform.extract_code_actions never uses full, but this eager call still tries to resolve a CMT for path before dispatching. In uncompiled/interface-only cases this now emits can't find module ... (as shown by the updated DocTemplate fixture) and does unnecessary package/CMT lookup for doc-template actions that work purely from source; compute full only for implementation actions that need type information.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6d26568

~debug
|> List.map (fun c -> Lsp.Types.CodeAction.yojson_of_t c)
|> print_list

Expand Down Expand Up @@ -161,6 +163,25 @@ let semantic_tokens ~path =
let tokens = Semantic_tokens.semantic_tokens ~source ~kind_file in
Lsp.Types.SemanticTokens.yojson_of_t tokens |> print_string

let document_symbol ~path =
match Files.read_file path with
| None -> print_null ()
| Some source ->
let kind_file = Files.classify_source_file path in
let symbols = Document_symbol.get_symbols ~source ~kind_file in
print_list (symbols |> List.map Lsp.Types.DocumentSymbol.yojson_of_t)

let create_interface ~path ~cmi_file =
let result =
match Files.read_file path with
| None -> ""
| Some source -> (
match Create_interface.command ~source ~cmi_file with
| Ok content -> content
| Error _ -> "")
in
Printf.printf "%s" result

let test ~state ~path =
Uri.strip_path := true;
match Files.read_file path with
Expand Down Expand Up @@ -247,7 +268,7 @@ let test ~state ~path =
Dce_command.command ()
| "doc" ->
print_endline ("DocumentSymbol " ^ path);
Document_symbol.command ~path
document_symbol ~path
| "hig" ->
print_endline ("Highlight " ^ path);
let source = Files.read_file path |> Option.get in
Expand Down Expand Up @@ -281,7 +302,7 @@ let test ~state ~path =
let dir = dirname path in
dir ++ parent_dir_name ++ "lib" ++ "bs" ++ "src" ++ name
in
Printf.printf "%s" (Create_interface.command ~state ~path ~cmi_file)
create_interface ~path ~cmi_file
| "ref" ->
print_endline
("References " ^ path ^ " " ^ string_of_int line ^ ":"
Expand Down Expand Up @@ -323,10 +344,11 @@ let test ~state ~path =
let source =
Files.read_file current_file |> Option.value ~default:""
in
let full = Cmt.load_full_cmt_from_path ~state ~path in
let kind_file = Files.classify_source_file current_file in
let code_actions =
Xform.extract_code_actions ~state ~path ~start_pos ~end_pos
~source ~kind_file ~debug:true
~source ~kind_file ~full ~debug:true
in
Sys.remove current_file;
code_actions
Expand Down Expand Up @@ -404,8 +426,8 @@ let test ~state ~path =
print_endline
("Inlay Hint " ^ path ^ " " ^ string_of_int line_start ^ ":"
^ string_of_int line_end);
inlayhint ~state ~path ~pos:(line_start, line_end) ~max_length:"25"
~debug:false
inlayhint ~state ~path ~pos:(line_start, line_end)
~max_length:(Some 25) ~debug:false
| "cle" ->
print_endline ("Code Lens " ^ path);
code_lens ~state ~path ~debug:false
Expand Down
3 changes: 2 additions & 1 deletion analysis/src/cmt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ let full_from_uri ~state ~uri =
let cmt = get_cmt_path ~uri paths in
full_for_cmt ~module_name ~package ~uri cmt
| None ->
prerr_endline ("can't find module " ^ module_name);
if Debug.verbose () then
prerr_endline ("can't find module " ^ module_name);
None))

let full_from_module ~package ~module_name =
Expand Down
15 changes: 4 additions & 11 deletions analysis/src/create_interface.ml
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
module Source_file_extractor = struct
let create ~path =
match Files.read_file path with
| None -> [||]
| Some text -> text |> String.split_on_char '\n' |> Array.of_list

let extract lines ~pos_start ~pos_end =
let line_start, col_start = pos_start in
let line_end, col_end = pos_end in
Expand Down Expand Up @@ -319,11 +314,9 @@ let print_signature ~extractor ~signature =
process_signature ~indent:"" signature;
Buffer.contents buf

let command ~state ~path ~cmi_file =
let command ~source ~cmi_file =
match Shared.try_read_cmi cmi_file with
| Some cmi_info ->
(* For reading the config *)
ignore (Cmt.load_full_cmt_from_path ~state ~path);
let extractor = Source_file_extractor.create ~path in
print_signature ~extractor ~signature:cmi_info.cmi_sign
| None -> ""
let extractor = source |> String.split_on_char '\n' |> Array.of_list in
Ok (print_signature ~extractor ~signature:cmi_info.cmi_sign)
| None -> Error ("Failed to read cmi file " ^ cmi_file)
20 changes: 8 additions & 12 deletions analysis/src/document_symbol.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(* https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentSymbol *)

let command ~path =
let get_symbols ~source ~kind_file =
let symbols = ref [] in
let add_symbol name loc kind =
if
Expand Down Expand Up @@ -115,17 +115,18 @@ let command ~path =
}
in

(if Filename.check_suffix path ".res" then
(if kind_file = Files.Res then
let parser =
Res_driver.parsing_engine.parse_implementation ~for_printer:false
Res_driver.parsing_engine.parse_implementation_from_source
~for_printer:false
in
let {Res_driver.parsetree = structure} = parser ~filename:path in
let {Res_driver.parsetree = structure} = parser ~source in
iterator.structure iterator structure |> ignore
else
let parser =
Res_driver.parsing_engine.parse_interface ~for_printer:false
Res_driver.parsing_engine.parse_interface_from_source ~for_printer:false
in
let {Res_driver.parsetree = signature} = parser ~filename:path in
let {Res_driver.parsetree = signature} = parser ~source in
iterator.signature iterator signature |> ignore);
let is_inside
({
Expand Down Expand Up @@ -182,9 +183,4 @@ let command ~path =
|> add_sorted_symbols_to_children ~sorted_symbols:rest
in
let sorted_symbols = !symbols |> List.sort compare_symbol in
let symbols_with_children =
[] |> add_sorted_symbols_to_children ~sorted_symbols
in
`List (symbols_with_children |> List.map Lsp.Types.DocumentSymbol.yojson_of_t)
|> Yojson.Safe.pretty_to_string ~std:true
|> print_endline
[] |> add_sorted_symbols_to_children ~sorted_symbols
3 changes: 1 addition & 2 deletions analysis/src/hint.ml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ let loc_item_to_type_hint ~state ~full:{file; package} loc_item =
| _ -> None

let inlay ~source ~kind_file ~pos ~max_length ~full ~state ~debug =
let maxlen = try Some (int_of_string max_length) with Failure _ -> None in
let hints = ref [] in
let start_line, end_line = pos in
let push loc kind =
Expand Down Expand Up @@ -103,7 +102,7 @@ let inlay ~source ~kind_file ~pos ~max_length ~full ~state ~debug =
Lsp.Types.InlayHint.create ~position ~kind ~paddingLeft:true
~paddingRight:false ~label:(`String label) ()
in
match maxlen with
match max_length with
| Some value ->
if String.length label > value then None else Some result
| None -> Some result)
Expand Down
4 changes: 2 additions & 2 deletions analysis/src/xform.ml
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ let parse_interface ~source =
(structure, print_signature_item)

let extract_code_actions ~state ~path ~start_pos ~end_pos ~source ~kind_file
~debug =
~full ~debug =
let pos = start_pos in
let code_actions = ref [] in
match kind_file with
Expand All @@ -934,7 +934,7 @@ let extract_code_actions ~state ~path ~start_pos ~end_pos ~source ~kind_file

(* This Code Action needs type info *)
let () =
match Cmt.load_full_cmt_from_path ~state ~path with
match full with
| Some full ->
Add_type_annotation.xform ~path ~pos ~full ~structure ~code_actions
~debug;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
Xform not_compiled/DocTemplate.res 3:3
can't find module DocTemplate
Hit: Add Documentation template

TextDocumentEdit: DocTemplate.res
Expand All @@ -17,7 +16,6 @@ type rec t = A | B
and e = C

Xform not_compiled/DocTemplate.res 6:15
can't find module DocTemplate
Hit: Add Documentation template

TextDocumentEdit: DocTemplate.res
Expand All @@ -33,7 +31,6 @@ newText:
@unboxed type name = Name(string)

Xform not_compiled/DocTemplate.res 8:4
can't find module DocTemplate
Hit: Add Documentation template

TextDocumentEdit: DocTemplate.res
Expand All @@ -49,7 +46,6 @@ newText:
let a = 1

Xform not_compiled/DocTemplate.res 10:4
can't find module DocTemplate
Hit: Add Documentation template

TextDocumentEdit: DocTemplate.res
Expand All @@ -65,7 +61,6 @@ newText:
let inc = x => x + 1

Xform not_compiled/DocTemplate.res 12:7
can't find module DocTemplate
Hit: Add Documentation template

TextDocumentEdit: DocTemplate.res
Expand Down Expand Up @@ -109,7 +104,6 @@ newText:


Xform not_compiled/DocTemplate.res 14:6
can't find module DocTemplate
Hit: Add Documentation template

TextDocumentEdit: DocTemplate.res
Expand Down Expand Up @@ -149,7 +143,6 @@ newText:


Xform not_compiled/DocTemplate.res 18:2
can't find module DocTemplate
Hit: Add Documentation template

TextDocumentEdit: DocTemplate.res
Expand Down
Loading