diff --git a/CHANGELOG.md b/CHANGELOG.md index c749bb74ae..720da66ed6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/analysis/bin/main.ml b/analysis/bin/main.ml index 481cec377c..ef40fdcb9a 100644 --- a/analysis/bin/main.ml +++ b/analysis/bin/main.ml @@ -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) @@ -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 @@ -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] -> diff --git a/analysis/src/cli.ml b/analysis/src/cli.ml index 7622bf5c9e..a30e36530a 100644 --- a/analysis/src/cli.ml +++ b/analysis/src/cli.ml @@ -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) + ~debug |> List.map (fun c -> Lsp.Types.CodeAction.yojson_of_t c) |> print_list @@ -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 @@ -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 @@ -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 ^ ":" @@ -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 @@ -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 diff --git a/analysis/src/cmt.ml b/analysis/src/cmt.ml index 6462b68208..a2c5e92eed 100644 --- a/analysis/src/cmt.ml +++ b/analysis/src/cmt.ml @@ -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 = diff --git a/analysis/src/create_interface.ml b/analysis/src/create_interface.ml index 9805a65e3a..506b52cc77 100644 --- a/analysis/src/create_interface.ml +++ b/analysis/src/create_interface.ml @@ -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 @@ -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) diff --git a/analysis/src/document_symbol.ml b/analysis/src/document_symbol.ml index 49ae7b32d7..5fec0db5d7 100644 --- a/analysis/src/document_symbol.ml +++ b/analysis/src/document_symbol.ml @@ -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 @@ -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 ({ @@ -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 diff --git a/analysis/src/hint.ml b/analysis/src/hint.ml index df5cc3625e..7206a6beb8 100644 --- a/analysis/src/hint.ml +++ b/analysis/src/hint.ml @@ -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 = @@ -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) diff --git a/analysis/src/xform.ml b/analysis/src/xform.ml index 3f3320928d..ac12e16035 100644 --- a/analysis/src/xform.ml +++ b/analysis/src/xform.ml @@ -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 @@ -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; diff --git a/tests/analysis_tests/tests/not_compiled/expected/DocTemplate.res.txt b/tests/analysis_tests/tests/not_compiled/expected/DocTemplate.res.txt index 2e222e81d6..5921931b5e 100644 --- a/tests/analysis_tests/tests/not_compiled/expected/DocTemplate.res.txt +++ b/tests/analysis_tests/tests/not_compiled/expected/DocTemplate.res.txt @@ -1,5 +1,4 @@ Xform not_compiled/DocTemplate.res 3:3 -can't find module DocTemplate Hit: Add Documentation template TextDocumentEdit: DocTemplate.res @@ -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 @@ -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 @@ -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 @@ -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 @@ -109,7 +104,6 @@ newText: Xform not_compiled/DocTemplate.res 14:6 -can't find module DocTemplate Hit: Add Documentation template TextDocumentEdit: DocTemplate.res @@ -149,7 +143,6 @@ newText: Xform not_compiled/DocTemplate.res 18:2 -can't find module DocTemplate Hit: Add Documentation template TextDocumentEdit: DocTemplate.res