From a3c28813be3c024fe5032a636bfef79e3d032873 Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Sun, 25 Feb 2024 22:01:34 +0400 Subject: [PATCH 1/5] Add completion for type t values --- analysis/src/CompletionBackEnd.ml | 76 ++++++++++++++++++------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/analysis/src/CompletionBackEnd.ml b/analysis/src/CompletionBackEnd.ml index d5d1a1462..d387dc19f 100644 --- a/analysis/src/CompletionBackEnd.ml +++ b/analysis/src/CompletionBackEnd.ml @@ -1257,6 +1257,12 @@ let rec completeTypedValue ?(typeArgContext : typeArgContext option) ~rawOpens match t with | TtypeT {env; path} -> if Debug.verbose () then print_endline "[complete_typed_value]--> TtypeT"; + (* Find all values in the module with type t *) + let valueWithTypeT t = + match t.Types.desc with + | Tconstr (Pident {name = "t"}, [], _) -> true + | _ -> false + in (* Find all functions in the module that returns type t *) let rec fnReturnsTypeT t = match t.Types.desc with @@ -1277,41 +1283,49 @@ let rec completeTypedValue ?(typeArgContext : typeArgContext option) ~rawOpens | _ -> false) | _ -> false in - let functionsReturningTypeT = - Hashtbl.create (Hashtbl.length env.exported.values_) + let getComplitionName exportedValueName = + let fnNname = + TypeUtils.getPathRelativeToEnv ~debug:false + ~env:(QueryEnv.fromFile full.file) + ~envFromItem:env (Utils.expandPath path) + in + match fnNname with + | None -> None + | Some base -> + let base = + TypeUtils.removeOpensFromCompletionPath ~rawOpens + ~package:full.package base + in + Some ((base |> String.concat ".") ^ "." ^ exportedValueName) + in + let getExportedValueComplition name (declared : Types.type_expr Declared.t) + = + let typeExpr = declared.item in + if valueWithTypeT typeExpr then + getComplitionName name + |> Option.map (fun name -> + createWithSnippet ~name ~insertText:name ~kind:(Value typeExpr) + ~env ()) + else if fnReturnsTypeT typeExpr then + getComplitionName name + |> Option.map (fun name -> + createWithSnippet + ~name:(Printf.sprintf "%s()" name) + ~insertText:(name ^ "($0)") ~kind:(Value typeExpr) ~env ()) + else None in - env.exported.values_ - |> Hashtbl.iter (fun name stamp -> - match Stamps.findValue env.file.stamps stamp with - | None -> () - | Some {item} -> ( - if fnReturnsTypeT item then - let fnNname = - TypeUtils.getPathRelativeToEnv ~debug:false - ~env:(QueryEnv.fromFile full.file) - ~envFromItem:env (Utils.expandPath path) - in - - match fnNname with - | None -> () - | Some base -> - let base = - TypeUtils.removeOpensFromCompletionPath ~rawOpens - ~package:full.package base - in - Hashtbl.add functionsReturningTypeT - ((base |> String.concat ".") ^ "." ^ name) - item)); - let completionItems = Hashtbl.fold - (fun fnName typeExpr all -> - createWithSnippet - ~name:(Printf.sprintf "%s()" fnName) - ~insertText:(fnName ^ "($0)") ~kind:(Value typeExpr) ~env () - :: all) - functionsReturningTypeT [] + (fun name stamp all -> + match Stamps.findValue env.file.stamps stamp with + | None -> all + | Some declaredTypeExpr -> ( + match getExportedValueComplition name declaredTypeExpr with + | None -> all + | Some completion -> completion :: all)) + env.exported.values_ [] in + (* Special casing for things where we want extra things in the completions *) let completionItems = match path with From 84c31292f6b874063c9604728441332f7d8459c3 Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Sun, 25 Feb 2024 22:12:23 +0400 Subject: [PATCH 2/5] Update snapshots --- .../tests/src/expected/CompletionExpressions.res.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/analysis/tests/src/expected/CompletionExpressions.res.txt b/analysis/tests/src/expected/CompletionExpressions.res.txt index d84e5bfe5..e3b20b708 100644 --- a/analysis/tests/src/expected/CompletionExpressions.res.txt +++ b/analysis/tests/src/expected/CompletionExpressions.res.txt @@ -1315,20 +1315,20 @@ Path mkStuff "insertText": "%re(\"/$0/g\")", "insertTextFormat": 2 }, { - "label": "Js.Re.fromStringWithFlags()", + "label": "Js.Re.fromString()", "kind": 12, "tags": [], - "detail": "(string, ~flags: string) => t", + "detail": "string => t", "documentation": null, - "insertText": "Js.Re.fromStringWithFlags($0)", + "insertText": "Js.Re.fromString($0)", "insertTextFormat": 2 }, { - "label": "Js.Re.fromString()", + "label": "Js.Re.fromStringWithFlags()", "kind": 12, "tags": [], - "detail": "string => t", + "detail": "(string, ~flags: string) => t", "documentation": null, - "insertText": "Js.Re.fromString($0)", + "insertText": "Js.Re.fromStringWithFlags($0)", "insertTextFormat": 2 }] From c39ba92f288d78c35e755660d6208c9f1f9e99d1 Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Sun, 25 Feb 2024 22:19:38 +0400 Subject: [PATCH 3/5] Add test --- analysis/tests/src/CompletionExpressions.res | 31 ++++++++++++++++ .../expected/CompletionExpressions.res.txt | 36 +++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/analysis/tests/src/CompletionExpressions.res b/analysis/tests/src/CompletionExpressions.res index 3572caede..5ff95e5e1 100644 --- a/analysis/tests/src/CompletionExpressions.res +++ b/analysis/tests/src/CompletionExpressions.res @@ -321,3 +321,34 @@ let mkStuff = (r: Js.Re.t) => { // mkStuff() // ^com + +module Money: { + type t + + let zero: t + + let nonTType: string + + let make: unit => t + + let fromInt: int => t + + let plus: (t, t) => t +} = { + type t = string + + let zero: t = "0" + + let nonTType = "0" + + let make = (): t => zero + + let fromInt = (int): t => int->Js.Int.toString + + let plus = (m1, _) => m1 +} + +let tArgCompletionTestFn = (tVal: Money.t) => () + +// tArgCompletionTestFn() +// ^com diff --git a/analysis/tests/src/expected/CompletionExpressions.res.txt b/analysis/tests/src/expected/CompletionExpressions.res.txt index e3b20b708..063cfd8c7 100644 --- a/analysis/tests/src/expected/CompletionExpressions.res.txt +++ b/analysis/tests/src/expected/CompletionExpressions.res.txt @@ -1332,3 +1332,39 @@ Path mkStuff "insertTextFormat": 2 }] +Complete src/CompletionExpressions.res 352:24 +posCursor:[352:24] posNoWhite:[352:23] Found expr:[352:3->352:25] +Pexp_apply ...[352:3->352:23] (...[352:24->352:25]) +Completable: Cexpression CArgument Value[tArgCompletionTestFn]($0) +Raw opens: 1 CompletionSupport.place holder +Package opens Pervasives.JsxModules.place holder +Resolved opens 2 pervasives CompletionSupport.res +ContextPath CArgument Value[tArgCompletionTestFn]($0) +ContextPath Value[tArgCompletionTestFn] +Path tArgCompletionTestFn +[{ + "label": "Money.fromInt()", + "kind": 12, + "tags": [], + "detail": "int => t", + "documentation": null, + "insertText": "Money.fromInt($0)", + "insertTextFormat": 2 + }, { + "label": "Money.make()", + "kind": 12, + "tags": [], + "detail": "unit => t", + "documentation": null, + "insertText": "Money.make($0)", + "insertTextFormat": 2 + }, { + "label": "Money.zero", + "kind": 12, + "tags": [], + "detail": "t", + "documentation": null, + "insertText": "Money.zero", + "insertTextFormat": 2 + }] + From e75466bcf2838025bc45779d259cf5705f6ec7d6 Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Sun, 25 Feb 2024 22:21:23 +0400 Subject: [PATCH 4/5] Add test for labeled arg as well --- analysis/tests/src/CompletionExpressions.res | 5 +++ .../expected/CompletionExpressions.res.txt | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/analysis/tests/src/CompletionExpressions.res b/analysis/tests/src/CompletionExpressions.res index 5ff95e5e1..c4f14d6ee 100644 --- a/analysis/tests/src/CompletionExpressions.res +++ b/analysis/tests/src/CompletionExpressions.res @@ -352,3 +352,8 @@ let tArgCompletionTestFn = (tVal: Money.t) => () // tArgCompletionTestFn() // ^com + +let labeledTArgCompletionTestFn = (~tVal: Money.t) => () + +// labeledTArgCompletionTestFn(~tVal=) +// ^com diff --git a/analysis/tests/src/expected/CompletionExpressions.res.txt b/analysis/tests/src/expected/CompletionExpressions.res.txt index 063cfd8c7..a95c7ed00 100644 --- a/analysis/tests/src/expected/CompletionExpressions.res.txt +++ b/analysis/tests/src/expected/CompletionExpressions.res.txt @@ -1368,3 +1368,39 @@ Path tArgCompletionTestFn "insertTextFormat": 2 }] +Complete src/CompletionExpressions.res 357:37 +posCursor:[357:37] posNoWhite:[357:36] Found expr:[357:3->357:38] +Pexp_apply ...[357:3->357:30] (~tVal357:32->357:36=...__ghost__[0:-1->0:-1]) +Completable: Cexpression CArgument Value[labeledTArgCompletionTestFn](~tVal) +Raw opens: 1 CompletionSupport.place holder +Package opens Pervasives.JsxModules.place holder +Resolved opens 2 pervasives CompletionSupport.res +ContextPath CArgument Value[labeledTArgCompletionTestFn](~tVal) +ContextPath Value[labeledTArgCompletionTestFn] +Path labeledTArgCompletionTestFn +[{ + "label": "Money.fromInt()", + "kind": 12, + "tags": [], + "detail": "int => t", + "documentation": null, + "insertText": "Money.fromInt($0)", + "insertTextFormat": 2 + }, { + "label": "Money.make()", + "kind": 12, + "tags": [], + "detail": "unit => t", + "documentation": null, + "insertText": "Money.make($0)", + "insertTextFormat": 2 + }, { + "label": "Money.zero", + "kind": 12, + "tags": [], + "detail": "t", + "documentation": null, + "insertText": "Money.zero", + "insertTextFormat": 2 + }] + From 7ac0320ca2b8cd1235683b5a118e437365dd7189 Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Tue, 27 Feb 2024 11:04:49 +0400 Subject: [PATCH 5/5] Fixes after review --- CHANGELOG.md | 1 + analysis/src/CompletionBackEnd.ml | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8991cdac..c55b8bc1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Latest parser for newest syntax features. https://github.com/rescript-lang/rescript-vscode/pull/917 - Handle completion for DOM/element attributes and attribute values properly when using a generic JSX transform. https://github.com/rescript-lang/rescript-vscode/pull/919 - Highlight tagged template literal functions as functions. https://github.com/rescript-lang/rescript-vscode/pull/920 +- Complete for `type t` values when encountering a `type t` in relevant scenarios. https://github.com/rescript-lang/rescript-vscode/pull/924 ## 1.38.0 diff --git a/analysis/src/CompletionBackEnd.ml b/analysis/src/CompletionBackEnd.ml index d387dc19f..891b41d69 100644 --- a/analysis/src/CompletionBackEnd.ml +++ b/analysis/src/CompletionBackEnd.ml @@ -1283,7 +1283,7 @@ let rec completeTypedValue ?(typeArgContext : typeArgContext option) ~rawOpens | _ -> false) | _ -> false in - let getComplitionName exportedValueName = + let getCompletionName exportedValueName = let fnNname = TypeUtils.getPathRelativeToEnv ~debug:false ~env:(QueryEnv.fromFile full.file) @@ -1298,16 +1298,16 @@ let rec completeTypedValue ?(typeArgContext : typeArgContext option) ~rawOpens in Some ((base |> String.concat ".") ^ "." ^ exportedValueName) in - let getExportedValueComplition name (declared : Types.type_expr Declared.t) + let getExportedValueCompletion name (declared : Types.type_expr Declared.t) = let typeExpr = declared.item in if valueWithTypeT typeExpr then - getComplitionName name + getCompletionName name |> Option.map (fun name -> createWithSnippet ~name ~insertText:name ~kind:(Value typeExpr) ~env ()) else if fnReturnsTypeT typeExpr then - getComplitionName name + getCompletionName name |> Option.map (fun name -> createWithSnippet ~name:(Printf.sprintf "%s()" name) @@ -1320,7 +1320,7 @@ let rec completeTypedValue ?(typeArgContext : typeArgContext option) ~rawOpens match Stamps.findValue env.file.stamps stamp with | None -> all | Some declaredTypeExpr -> ( - match getExportedValueComplition name declaredTypeExpr with + match getExportedValueCompletion name declaredTypeExpr with | None -> all | Some completion -> completion :: all)) env.exported.values_ []