From d3a3d9a6368bd531a33d08bc37371a115007cec3 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 16 Dec 2022 13:09:14 +0100 Subject: [PATCH 1/5] Emit nested document symbols. Fixes https://github.com/rescript-lang/rescript-vscode/issues/654. The change in https://github.com/rescript-lang/rescript-vscode/pull/629 moved to a non-deprecated representation of document symbol. The new representation is the "Ikea" version of the old one, where children symbol are not computed for you, but need to be provided. This PR computes and emits the tree of symbols using the `children` field. --- CHANGELOG.md | 2 + analysis/src/DocumentSymbol.ml | 89 +++++++--- analysis/src/Protocol.ml | 33 +++- .../tests/src/expected/DocumentSymbol.res.txt | 157 +++++++++--------- 4 files changed, 173 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e2fe53dd..f74aaac34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,8 @@ - Fix issue where jump to definition would go to the wrong place when there are aliased identifiers in submodules https://github.com/rescript-lang/rescript-vscode/pull/653 +- Fix issue where document symbols were not shown nested + ## v1.8.2 #### :rocket: New Feature diff --git a/analysis/src/DocumentSymbol.ml b/analysis/src/DocumentSymbol.ml index 0eb5628ea..357eba216 100644 --- a/analysis/src/DocumentSymbol.ml +++ b/analysis/src/DocumentSymbol.ml @@ -26,6 +26,13 @@ let kindNumber = function let command ~path = let symbols = ref [] in + let addSymbol name loc kind = + let range = Utils.cmtLocToRange loc in + let symbol : Protocol.documentSymbolItem = + {name; range; kind = kindNumber kind; children = []} + in + symbols := symbol :: !symbols + in let rec exprKind (exp : Parsetree.expression) = match exp.pexp_desc with | Pexp_fun _ -> Function @@ -41,43 +48,41 @@ let command ~path = | Ptype_variant constrDecls -> constrDecls |> List.iter (fun (cd : Parsetree.constructor_declaration) -> - symbols := (cd.pcd_name.txt, cd.pcd_loc, EnumMember) :: !symbols) + addSymbol cd.pcd_name.txt cd.pcd_loc EnumMember) | Ptype_record labelDecls -> labelDecls |> List.iter (fun (ld : Parsetree.label_declaration) -> - symbols := (ld.pld_name.txt, ld.pld_loc, Property) :: !symbols) + addSymbol ld.pld_name.txt ld.pld_loc Property) | _ -> () in let processTypeDeclaration (td : Parsetree.type_declaration) = - symbols := (td.ptype_name.txt, td.ptype_loc, TypeParameter) :: !symbols; + addSymbol td.ptype_name.txt td.ptype_loc TypeParameter; processTypeKind td.ptype_kind in let processValueDescription (vd : Parsetree.value_description) = - symbols := (vd.pval_name.txt, vd.pval_loc, Variable) :: !symbols + addSymbol vd.pval_name.txt vd.pval_loc Variable in let processModuleBinding (mb : Parsetree.module_binding) = - symbols := (mb.pmb_name.txt, mb.pmb_loc, Module) :: !symbols + addSymbol mb.pmb_name.txt mb.pmb_loc Module in let processModuleDeclaration (md : Parsetree.module_declaration) = - symbols := (md.pmd_name.txt, md.pmd_loc, Module) :: !symbols + addSymbol md.pmd_name.txt md.pmd_loc Module in let processExtensionConstructor (et : Parsetree.extension_constructor) = - symbols := (et.pext_name.txt, et.pext_loc, Constructor) :: !symbols + addSymbol et.pext_name.txt et.pext_loc Constructor in let value_binding (iterator : Ast_iterator.iterator) (vb : Parsetree.value_binding) = (match vb.pvb_pat.ppat_desc with | Ppat_var {txt} | Ppat_constraint ({ppat_desc = Ppat_var {txt}}, _) -> - symbols := (txt, vb.pvb_loc, exprKind vb.pvb_expr) :: !symbols + addSymbol txt vb.pvb_loc (exprKind vb.pvb_expr) | _ -> ()); Ast_iterator.default_iterator.value_binding iterator vb in let expr (iterator : Ast_iterator.iterator) (e : Parsetree.expression) = (match e.pexp_desc with | Pexp_letmodule ({txt}, modExpr, _) -> - symbols := - (txt, {e.pexp_loc with loc_end = modExpr.pmod_loc.loc_end}, Module) - :: !symbols + addSymbol txt {e.pexp_loc with loc_end = modExpr.pmod_loc.loc_end} Module | Pexp_letexception (ec, _) -> processExtensionConstructor ec | _ -> ()); Ast_iterator.default_iterator.expr iterator e @@ -134,12 +139,56 @@ let command ~path = let parser = Res_driver.parsingEngine.parseInterface ~forPrinter:false in let {Res_driver.parsetree = signature} = parser ~filename:path in iterator.signature iterator signature |> ignore); - let result = - !symbols - |> List.rev_map (fun (name, loc, kind) -> - let range = Utils.cmtLocToRange loc in - Protocol.stringifyDocumentSymbolItem - {name; range; selectionRange = range; kind = kindNumber kind}) - |> String.concat ",\n" - in - print_endline ("[\n" ^ result ^ "\n]") + let isInside + ({ + range = + { + start = {line = sl1; character = sc1}; + end_ = {line = el1; character = ec1}; + }; + } : + Protocol.documentSymbolItem) + ({ + range = + { + start = {line = sl2; character = sc2}; + end_ = {line = el2; character = ec2}; + }; + } : + Protocol.documentSymbolItem) = + (sl1 > sl2 || (sl1 = sl2 && sc1 >= sc2)) + && (el1 < el2 || (el1 = el2 && ec1 <= ec2)) + in + let compareSymbol (s1 : Protocol.documentSymbolItem) + (s2 : Protocol.documentSymbolItem) = + let n = compare s1.range.start.line s2.range.start.line in + if n <> 0 then n + else + let n = compare s1.range.start.character s2.range.start.character in + if n <> 0 then n + else + let n = compare s1.range.end_.line s2.range.end_.line in + if n <> 0 then n + else compare s1.range.end_.character s2.range.end_.character + in + let rec addSymbolToChildren children symbol = + match children with + | [] -> [symbol] + | last :: rest -> + if isInside symbol last then + let newLast = + {last with children = addSymbolToChildren last.children symbol} + in + newLast :: rest + else symbol :: children + in + let rec addSortedSymbolsToChildren ~sortedSymbols children = + match sortedSymbols with + | [] -> children + | firstSymbol :: rest -> + let newChildren = addSymbolToChildren children firstSymbol in + addSortedSymbolsToChildren ~sortedSymbols:rest newChildren + in + let sortedSymbols = !symbols |> List.sort compareSymbol in + let symbolsWithChildren = [] |> addSortedSymbolsToChildren ~sortedSymbols in + print_endline (Protocol.stringifyDocumentSymbolItems symbolsWithChildren) diff --git a/analysis/src/Protocol.ml b/analysis/src/Protocol.ml index e1809f12c..68e1e64e1 100644 --- a/analysis/src/Protocol.ml +++ b/analysis/src/Protocol.ml @@ -46,7 +46,7 @@ type documentSymbolItem = { name: string; kind: int; range: range; - selectionRange: range; + children: documentSymbolItem list; } type renameFile = {oldUri: string; newUri: string} type textEdit = {range: range; newText: string} @@ -102,22 +102,39 @@ let stringifyCompletionItem c = | None -> null | Some doc -> stringifyMarkupContent doc) -let stringifyHover value = Printf.sprintf {|{"contents": %s}|} (stringifyMarkupContent {kind = "markdown"; value}) +let stringifyHover value = + Printf.sprintf {|{"contents": %s}|} + (stringifyMarkupContent {kind = "markdown"; value}) let stringifyLocation (h : location) = Printf.sprintf {|{"uri": "%s", "range": %s}|} (Json.escape h.uri) (stringifyRange h.range) -let stringifyDocumentSymbolItem (i : documentSymbolItem) = +let rec stringifyDocumentSymbolItem (i : documentSymbolItem) = let range = stringifyRange i.range in + let children = + if i.children = [] then "" + else + Printf.sprintf {|, + "children": [%s]|} + (i.children + |> List.rev_map stringifyDocumentSymbolItem + |> String.concat ", ") + in Printf.sprintf {|{ - "name": "%s", - "kind": %i, - "range": %s, - "selectionRange": %s + "name": "%s", + "kind": %i, + "range": %s, + "selectionRange": %s%s }|} - (Json.escape i.name) i.kind range range + (Json.escape i.name) i.kind range range children + +let stringifyDocumentSymbolItems items = + let result = + items |> List.rev_map stringifyDocumentSymbolItem |> String.concat ",\n" + in + "[\n" ^ result ^ "\n]" let stringifyRenameFile {oldUri; newUri} = Printf.sprintf {|{ diff --git a/analysis/tests/src/expected/DocumentSymbol.res.txt b/analysis/tests/src/expected/DocumentSymbol.res.txt index ef8583dee..01304b6f9 100644 --- a/analysis/tests/src/expected/DocumentSymbol.res.txt +++ b/analysis/tests/src/expected/DocumentSymbol.res.txt @@ -1,100 +1,97 @@ DocumentSymbol src/DocumentSymbol.res [ { - "name": "MyList", - "kind": 2, - "range": {"start": {"line": 0, "character": 7}, "end": {"line": 0, "character": 25}}, - "selectionRange": {"start": {"line": 0, "character": 7}, "end": {"line": 0, "character": 25}} + "name": "MyList", + "kind": 2, + "range": {"start": {"line": 0, "character": 7}, "end": {"line": 0, "character": 25}}, + "selectionRange": {"start": {"line": 0, "character": 7}, "end": {"line": 0, "character": 25}} }, { - "name": "Dep", - "kind": 2, - "range": {"start": {"line": 2, "character": 7}, "end": {"line": 7, "character": 1}}, - "selectionRange": {"start": {"line": 2, "character": 7}, "end": {"line": 7, "character": 1}} + "name": "Dep", + "kind": 2, + "range": {"start": {"line": 2, "character": 7}, "end": {"line": 7, "character": 1}}, + "selectionRange": {"start": {"line": 2, "character": 7}, "end": {"line": 7, "character": 1}}, + "children": [{ + "name": "customDouble", + "kind": 12, + "range": {"start": {"line": 6, "character": 2}, "end": {"line": 6, "character": 35}}, + "selectionRange": {"start": {"line": 6, "character": 2}, "end": {"line": 6, "character": 35}} +}] }, { - "name": "customDouble", - "kind": 12, - "range": {"start": {"line": 6, "character": 2}, "end": {"line": 6, "character": 35}}, - "selectionRange": {"start": {"line": 6, "character": 2}, "end": {"line": 6, "character": 35}} + "name": "Lib", + "kind": 2, + "range": {"start": {"line": 9, "character": 7}, "end": {"line": 12, "character": 1}}, + "selectionRange": {"start": {"line": 9, "character": 7}, "end": {"line": 12, "character": 1}}, + "children": [{ + "name": "foo", + "kind": 12, + "range": {"start": {"line": 10, "character": 2}, "end": {"line": 10, "character": 55}}, + "selectionRange": {"start": {"line": 10, "character": 2}, "end": {"line": 10, "character": 55}} +}, { + "name": "next", + "kind": 12, + "range": {"start": {"line": 11, "character": 2}, "end": {"line": 11, "character": 48}}, + "selectionRange": {"start": {"line": 11, "character": 2}, "end": {"line": 11, "character": 48}} +}] }, { - "name": "Lib", - "kind": 2, - "range": {"start": {"line": 9, "character": 7}, "end": {"line": 12, "character": 1}}, - "selectionRange": {"start": {"line": 9, "character": 7}, "end": {"line": 12, "character": 1}} + "name": "op", + "kind": 13, + "range": {"start": {"line": 14, "character": 0}, "end": {"line": 14, "character": 16}}, + "selectionRange": {"start": {"line": 14, "character": 0}, "end": {"line": 14, "character": 16}} }, { - "name": "foo", - "kind": 12, - "range": {"start": {"line": 10, "character": 2}, "end": {"line": 10, "character": 55}}, - "selectionRange": {"start": {"line": 10, "character": 2}, "end": {"line": 10, "character": 55}} + "name": "ForAuto", + "kind": 2, + "range": {"start": {"line": 16, "character": 7}, "end": {"line": 20, "character": 1}}, + "selectionRange": {"start": {"line": 16, "character": 7}, "end": {"line": 20, "character": 1}}, + "children": [{ + "name": "t", + "kind": 26, + "range": {"start": {"line": 17, "character": 2}, "end": {"line": 17, "character": 14}}, + "selectionRange": {"start": {"line": 17, "character": 2}, "end": {"line": 17, "character": 14}} +}, { + "name": "abc", + "kind": 12, + "range": {"start": {"line": 18, "character": 2}, "end": {"line": 18, "character": 32}}, + "selectionRange": {"start": {"line": 18, "character": 2}, "end": {"line": 18, "character": 32}} +}, { + "name": "abd", + "kind": 12, + "range": {"start": {"line": 19, "character": 2}, "end": {"line": 19, "character": 32}}, + "selectionRange": {"start": {"line": 19, "character": 2}, "end": {"line": 19, "character": 32}} +}] }, { - "name": "next", - "kind": 12, - "range": {"start": {"line": 11, "character": 2}, "end": {"line": 11, "character": 48}}, - "selectionRange": {"start": {"line": 11, "character": 2}, "end": {"line": 11, "character": 48}} + "name": "fa", + "kind": 16, + "range": {"start": {"line": 22, "character": 0}, "end": {"line": 22, "character": 22}}, + "selectionRange": {"start": {"line": 22, "character": 0}, "end": {"line": 22, "character": 22}} }, { - "name": "op", - "kind": 13, - "range": {"start": {"line": 14, "character": 0}, "end": {"line": 14, "character": 16}}, - "selectionRange": {"start": {"line": 14, "character": 0}, "end": {"line": 14, "character": 16}} + "name": "O", + "kind": 2, + "range": {"start": {"line": 24, "character": 7}, "end": {"line": 29, "character": 1}}, + "selectionRange": {"start": {"line": 24, "character": 7}, "end": {"line": 29, "character": 1}}, + "children": [{ + "name": "Comp", + "kind": 2, + "range": {"start": {"line": 25, "character": 9}, "end": {"line": 28, "character": 3}}, + "selectionRange": {"start": {"line": 25, "character": 9}, "end": {"line": 28, "character": 3}}, + "children": [{ + "name": "make", + "kind": 12, + "range": {"start": {"line": 27, "character": 4}, "end": {"line": 27, "character": 98}}, + "selectionRange": {"start": {"line": 27, "character": 4}, "end": {"line": 27, "character": 98}} +}] +}] }, { - "name": "ForAuto", - "kind": 2, - "range": {"start": {"line": 16, "character": 7}, "end": {"line": 20, "character": 1}}, - "selectionRange": {"start": {"line": 16, "character": 7}, "end": {"line": 20, "character": 1}} -}, -{ - "name": "t", - "kind": 26, - "range": {"start": {"line": 17, "character": 2}, "end": {"line": 17, "character": 14}}, - "selectionRange": {"start": {"line": 17, "character": 2}, "end": {"line": 17, "character": 14}} -}, -{ - "name": "abc", - "kind": 12, - "range": {"start": {"line": 18, "character": 2}, "end": {"line": 18, "character": 32}}, - "selectionRange": {"start": {"line": 18, "character": 2}, "end": {"line": 18, "character": 32}} -}, -{ - "name": "abd", - "kind": 12, - "range": {"start": {"line": 19, "character": 2}, "end": {"line": 19, "character": 32}}, - "selectionRange": {"start": {"line": 19, "character": 2}, "end": {"line": 19, "character": 32}} -}, -{ - "name": "fa", - "kind": 16, - "range": {"start": {"line": 22, "character": 0}, "end": {"line": 22, "character": 22}}, - "selectionRange": {"start": {"line": 22, "character": 0}, "end": {"line": 22, "character": 22}} -}, -{ - "name": "O", - "kind": 2, - "range": {"start": {"line": 24, "character": 7}, "end": {"line": 29, "character": 1}}, - "selectionRange": {"start": {"line": 24, "character": 7}, "end": {"line": 29, "character": 1}} -}, -{ - "name": "Comp", - "kind": 2, - "range": {"start": {"line": 25, "character": 9}, "end": {"line": 28, "character": 3}}, - "selectionRange": {"start": {"line": 25, "character": 9}, "end": {"line": 28, "character": 3}} -}, -{ - "name": "make", - "kind": 12, - "range": {"start": {"line": 27, "character": 4}, "end": {"line": 27, "character": 98}}, - "selectionRange": {"start": {"line": 27, "character": 4}, "end": {"line": 27, "character": 98}} -}, -{ - "name": "zzz", - "kind": 16, - "range": {"start": {"line": 31, "character": 0}, "end": {"line": 31, "character": 12}}, - "selectionRange": {"start": {"line": 31, "character": 0}, "end": {"line": 31, "character": 12}} + "name": "zzz", + "kind": 16, + "range": {"start": {"line": 31, "character": 0}, "end": {"line": 31, "character": 12}}, + "selectionRange": {"start": {"line": 31, "character": 0}, "end": {"line": 31, "character": 12}} } ] From f13ed794d4081eb207d4a9b5fb43b14fecfe8efc Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 16 Dec 2022 14:19:35 +0100 Subject: [PATCH 2/5] indent --- analysis/src/Protocol.ml | 55 ++++++----- .../tests/src/expected/DocumentSymbol.res.txt | 98 ++++++++++--------- 2 files changed, 85 insertions(+), 68 deletions(-) diff --git a/analysis/src/Protocol.ml b/analysis/src/Protocol.ml index 68e1e64e1..21fda391c 100644 --- a/analysis/src/Protocol.ml +++ b/analysis/src/Protocol.ml @@ -110,31 +110,40 @@ let stringifyLocation (h : location) = Printf.sprintf {|{"uri": "%s", "range": %s}|} (Json.escape h.uri) (stringifyRange h.range) -let rec stringifyDocumentSymbolItem (i : documentSymbolItem) = - let range = stringifyRange i.range in - let children = - if i.children = [] then "" - else - Printf.sprintf {|, - "children": [%s]|} - (i.children - |> List.rev_map stringifyDocumentSymbolItem - |> String.concat ", ") - in - Printf.sprintf - {|{ - "name": "%s", - "kind": %i, - "range": %s, - "selectionRange": %s%s -}|} - (Json.escape i.name) i.kind range range children - let stringifyDocumentSymbolItems items = - let result = - items |> List.rev_map stringifyDocumentSymbolItem |> String.concat ",\n" + let buf = Buffer.create 10 in + let rec emitOne indent isLast (i : documentSymbolItem) = + let open_ = Printf.sprintf "%s{\n" indent in + let close = Printf.sprintf "\n%s}" indent in + let indent = indent ^ " " in + let range = stringifyRange i.range in + Buffer.add_string buf open_; + Buffer.add_string buf + (Printf.sprintf "%s\"name\": \"%s\",\n" indent (Json.escape i.name)); + Buffer.add_string buf (Printf.sprintf "%s\"kind\": %i,\n" indent i.kind); + Buffer.add_string buf (Printf.sprintf "%s\"range\": %s,\n" indent range); + Buffer.add_string buf + (Printf.sprintf "%s\"selectionRange\": %s" indent range); + if i.children <> [] then ( + Buffer.add_string buf (Printf.sprintf ",\n%s\"children\": [\n" indent); + emitBody indent (List.rev i.children); + Buffer.add_string buf "]"); + Buffer.add_string buf close; + if isLast then Buffer.add_string buf ",\n" + and emitBody indent items = + match items with + | [] -> () + | item :: rest -> + emitOne indent (rest <> []) item; + emitBody indent rest + and emitMany indent items = + Buffer.add_string buf "[\n"; + emitBody indent items; + Buffer.add_string buf "\n]" in - "[\n" ^ result ^ "\n]" + let indent = "" in + emitMany indent (List.rev items); + Buffer.contents buf let stringifyRenameFile {oldUri; newUri} = Printf.sprintf {|{ diff --git a/analysis/tests/src/expected/DocumentSymbol.res.txt b/analysis/tests/src/expected/DocumentSymbol.res.txt index 01304b6f9..5710a1d5e 100644 --- a/analysis/tests/src/expected/DocumentSymbol.res.txt +++ b/analysis/tests/src/expected/DocumentSymbol.res.txt @@ -11,29 +11,32 @@ DocumentSymbol src/DocumentSymbol.res "kind": 2, "range": {"start": {"line": 2, "character": 7}, "end": {"line": 7, "character": 1}}, "selectionRange": {"start": {"line": 2, "character": 7}, "end": {"line": 7, "character": 1}}, - "children": [{ - "name": "customDouble", - "kind": 12, - "range": {"start": {"line": 6, "character": 2}, "end": {"line": 6, "character": 35}}, - "selectionRange": {"start": {"line": 6, "character": 2}, "end": {"line": 6, "character": 35}} -}] + "children": [ + { + "name": "customDouble", + "kind": 12, + "range": {"start": {"line": 6, "character": 2}, "end": {"line": 6, "character": 35}}, + "selectionRange": {"start": {"line": 6, "character": 2}, "end": {"line": 6, "character": 35}} + }] }, { "name": "Lib", "kind": 2, "range": {"start": {"line": 9, "character": 7}, "end": {"line": 12, "character": 1}}, "selectionRange": {"start": {"line": 9, "character": 7}, "end": {"line": 12, "character": 1}}, - "children": [{ - "name": "foo", - "kind": 12, - "range": {"start": {"line": 10, "character": 2}, "end": {"line": 10, "character": 55}}, - "selectionRange": {"start": {"line": 10, "character": 2}, "end": {"line": 10, "character": 55}} -}, { - "name": "next", - "kind": 12, - "range": {"start": {"line": 11, "character": 2}, "end": {"line": 11, "character": 48}}, - "selectionRange": {"start": {"line": 11, "character": 2}, "end": {"line": 11, "character": 48}} -}] + "children": [ + { + "name": "foo", + "kind": 12, + "range": {"start": {"line": 10, "character": 2}, "end": {"line": 10, "character": 55}}, + "selectionRange": {"start": {"line": 10, "character": 2}, "end": {"line": 10, "character": 55}} + }, + { + "name": "next", + "kind": 12, + "range": {"start": {"line": 11, "character": 2}, "end": {"line": 11, "character": 48}}, + "selectionRange": {"start": {"line": 11, "character": 2}, "end": {"line": 11, "character": 48}} + }] }, { "name": "op", @@ -46,22 +49,25 @@ DocumentSymbol src/DocumentSymbol.res "kind": 2, "range": {"start": {"line": 16, "character": 7}, "end": {"line": 20, "character": 1}}, "selectionRange": {"start": {"line": 16, "character": 7}, "end": {"line": 20, "character": 1}}, - "children": [{ - "name": "t", - "kind": 26, - "range": {"start": {"line": 17, "character": 2}, "end": {"line": 17, "character": 14}}, - "selectionRange": {"start": {"line": 17, "character": 2}, "end": {"line": 17, "character": 14}} -}, { - "name": "abc", - "kind": 12, - "range": {"start": {"line": 18, "character": 2}, "end": {"line": 18, "character": 32}}, - "selectionRange": {"start": {"line": 18, "character": 2}, "end": {"line": 18, "character": 32}} -}, { - "name": "abd", - "kind": 12, - "range": {"start": {"line": 19, "character": 2}, "end": {"line": 19, "character": 32}}, - "selectionRange": {"start": {"line": 19, "character": 2}, "end": {"line": 19, "character": 32}} -}] + "children": [ + { + "name": "t", + "kind": 26, + "range": {"start": {"line": 17, "character": 2}, "end": {"line": 17, "character": 14}}, + "selectionRange": {"start": {"line": 17, "character": 2}, "end": {"line": 17, "character": 14}} + }, + { + "name": "abc", + "kind": 12, + "range": {"start": {"line": 18, "character": 2}, "end": {"line": 18, "character": 32}}, + "selectionRange": {"start": {"line": 18, "character": 2}, "end": {"line": 18, "character": 32}} + }, + { + "name": "abd", + "kind": 12, + "range": {"start": {"line": 19, "character": 2}, "end": {"line": 19, "character": 32}}, + "selectionRange": {"start": {"line": 19, "character": 2}, "end": {"line": 19, "character": 32}} + }] }, { "name": "fa", @@ -74,18 +80,20 @@ DocumentSymbol src/DocumentSymbol.res "kind": 2, "range": {"start": {"line": 24, "character": 7}, "end": {"line": 29, "character": 1}}, "selectionRange": {"start": {"line": 24, "character": 7}, "end": {"line": 29, "character": 1}}, - "children": [{ - "name": "Comp", - "kind": 2, - "range": {"start": {"line": 25, "character": 9}, "end": {"line": 28, "character": 3}}, - "selectionRange": {"start": {"line": 25, "character": 9}, "end": {"line": 28, "character": 3}}, - "children": [{ - "name": "make", - "kind": 12, - "range": {"start": {"line": 27, "character": 4}, "end": {"line": 27, "character": 98}}, - "selectionRange": {"start": {"line": 27, "character": 4}, "end": {"line": 27, "character": 98}} -}] -}] + "children": [ + { + "name": "Comp", + "kind": 2, + "range": {"start": {"line": 25, "character": 9}, "end": {"line": 28, "character": 3}}, + "selectionRange": {"start": {"line": 25, "character": 9}, "end": {"line": 28, "character": 3}}, + "children": [ + { + "name": "make", + "kind": 12, + "range": {"start": {"line": 27, "character": 4}, "end": {"line": 27, "character": 98}}, + "selectionRange": {"start": {"line": 27, "character": 4}, "end": {"line": 27, "character": 98}} + }] + }] }, { "name": "zzz", From 863bcaaba859afb67c6687cbe8897f698b74e057 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 16 Dec 2022 14:51:12 +0100 Subject: [PATCH 3/5] Refactor code for indentation. --- analysis/src/Protocol.ml | 56 ++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/analysis/src/Protocol.ml b/analysis/src/Protocol.ml index 21fda391c..68cd7661c 100644 --- a/analysis/src/Protocol.ml +++ b/analysis/src/Protocol.ml @@ -112,37 +112,43 @@ let stringifyLocation (h : location) = let stringifyDocumentSymbolItems items = let buf = Buffer.create 10 in - let rec emitOne indent isLast (i : documentSymbolItem) = - let open_ = Printf.sprintf "%s{\n" indent in - let close = Printf.sprintf "\n%s}" indent in + let stringifyName name = Printf.sprintf "\"%s\"" (Json.escape name) in + let stringifyKind kind = string_of_int kind in + let emitStr = Buffer.add_string buf in + let emitSep () = emitStr ",\n" in + let rec emitItem ~indent item = + let openBrace = Printf.sprintf "%s{\n" indent in + let closeBrace = Printf.sprintf "\n%s}" indent in let indent = indent ^ " " in - let range = stringifyRange i.range in - Buffer.add_string buf open_; - Buffer.add_string buf - (Printf.sprintf "%s\"name\": \"%s\",\n" indent (Json.escape i.name)); - Buffer.add_string buf (Printf.sprintf "%s\"kind\": %i,\n" indent i.kind); - Buffer.add_string buf (Printf.sprintf "%s\"range\": %s,\n" indent range); - Buffer.add_string buf - (Printf.sprintf "%s\"selectionRange\": %s" indent range); - if i.children <> [] then ( - Buffer.add_string buf (Printf.sprintf ",\n%s\"children\": [\n" indent); - emitBody indent (List.rev i.children); - Buffer.add_string buf "]"); - Buffer.add_string buf close; - if isLast then Buffer.add_string buf ",\n" - and emitBody indent items = + let emitField name s = + emitStr (Printf.sprintf "%s\"%s\": %s" indent name s) + in + emitStr openBrace; + emitField "name" (stringifyName item.name); + emitSep (); + emitField "kind" (stringifyKind item.kind); + emitSep (); + emitField "range" (stringifyRange item.range); + emitSep (); + emitField "selectionRange" (stringifyRange item.range); + if item.children <> [] then ( + emitSep (); + emitField "children" "[\n"; + emitBody ~indent (List.rev item.children); + emitStr "]"); + emitStr closeBrace + and emitBody ~indent items = match items with | [] -> () | item :: rest -> - emitOne indent (rest <> []) item; - emitBody indent rest - and emitMany indent items = - Buffer.add_string buf "[\n"; - emitBody indent items; - Buffer.add_string buf "\n]" + emitItem ~indent item; + if rest <> [] then emitSep (); + emitBody ~indent rest in let indent = "" in - emitMany indent (List.rev items); + emitStr "[\n"; + emitBody ~indent (List.rev items); + emitStr "\n]"; Buffer.contents buf let stringifyRenameFile {oldUri; newUri} = From b23e614c89689425c34e30bb2509ffc75034fb02 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 16 Dec 2022 14:53:29 +0100 Subject: [PATCH 4/5] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f74aaac34..b75a006df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,7 +45,7 @@ - Fix issue where jump to definition would go to the wrong place when there are aliased identifiers in submodules https://github.com/rescript-lang/rescript-vscode/pull/653 -- Fix issue where document symbols were not shown nested +- Fix issue where document symbols were not shown nested https://github.com/rescript-lang/rescript-vscode/pull/655 ## v1.8.2 From c2c8d562f25d2ba34a6406c8c3a1ab64ceea9c0e Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 16 Dec 2022 14:59:30 +0100 Subject: [PATCH 5/5] cleanup --- analysis/src/DocumentSymbol.ml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/analysis/src/DocumentSymbol.ml b/analysis/src/DocumentSymbol.ml index 357eba216..bd77bc19e 100644 --- a/analysis/src/DocumentSymbol.ml +++ b/analysis/src/DocumentSymbol.ml @@ -171,13 +171,13 @@ let command ~path = if n <> 0 then n else compare s1.range.end_.character s2.range.end_.character in - let rec addSymbolToChildren children symbol = + let rec addSymbolToChildren ~symbol children = match children with | [] -> [symbol] | last :: rest -> if isInside symbol last then let newLast = - {last with children = addSymbolToChildren last.children symbol} + {last with children = last.children |> addSymbolToChildren ~symbol} in newLast :: rest else symbol :: children @@ -186,8 +186,9 @@ let command ~path = match sortedSymbols with | [] -> children | firstSymbol :: rest -> - let newChildren = addSymbolToChildren children firstSymbol in - addSortedSymbolsToChildren ~sortedSymbols:rest newChildren + children + |> addSymbolToChildren ~symbol:firstSymbol + |> addSortedSymbolsToChildren ~sortedSymbols:rest in let sortedSymbols = !symbols |> List.sort compareSymbol in let symbolsWithChildren = [] |> addSortedSymbolsToChildren ~sortedSymbols in