From 8865ce6cab00bc3a5e7912c43cfe49f3be8c4cf8 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 20 Aug 2023 12:27:33 +0200 Subject: [PATCH 1/2] instantiate variant types as needed --- analysis/src/SharedTypes.ml | 2 ++ analysis/src/TypeUtils.ml | 33 ++++++++++++----- analysis/tests/src/CompletionPattern.res | 5 +++ .../src/expected/CompletionPattern.res.txt | 36 +++++++++++++++++++ 4 files changed, 68 insertions(+), 8 deletions(-) diff --git a/analysis/src/SharedTypes.ml b/analysis/src/SharedTypes.ml index 8e60f1cf4..aee6e046b 100644 --- a/analysis/src/SharedTypes.ml +++ b/analysis/src/SharedTypes.ml @@ -320,6 +320,8 @@ and completionType = constructors: Constructor.t list; variantDecl: Types.type_declaration; variantName: string; + typeArgs: Types.type_expr list; + typeParams: Types.type_expr list; } | Tpolyvariant of { env: QueryEnv.t; diff --git a/analysis/src/TypeUtils.ml b/analysis/src/TypeUtils.ml index 0afeb2490..d8da5bc8f 100644 --- a/analysis/src/TypeUtils.ml +++ b/analysis/src/TypeUtils.ml @@ -128,14 +128,23 @@ let rec extractType ~env ~package (t : Types.type_expr) = | args, _tRet when args <> [] -> Some (Tfunction {env; args; typ = t; uncurried = true}) | _args, _tRet -> None) - | Tconstr (path, _, _) -> ( + | Tconstr (path, typeArgs, _) -> ( match References.digConstructor ~env ~package path with - | Some (env, {item = {decl = {type_manifest = Some t1}}}) -> - extractType ~env ~package t1 - | Some (env, {name; item = {decl; kind = Type.Variant constructors}}) -> + | Some (_env, {item = {decl = {type_manifest = Some t1; type_params}}}) -> + t1 + |> instantiateType ~typeParams:type_params ~typeArgs + |> extractType ~env ~package + | Some (_env, {name; item = {decl; kind = Type.Variant constructors}}) -> Some (Tvariant - {env; constructors; variantName = name.txt; variantDecl = decl}) + { + env; + constructors; + variantName = name.txt; + variantDecl = decl; + typeArgs; + typeParams = decl.type_params; + }) | Some (env, {item = {kind = Record fields}}) -> Some (Trecord {env; fields; definition = `TypeExpr t}) | _ -> None) @@ -280,7 +289,14 @@ let extractTypeFromResolvedType (typ : Type.t) ~env ~full = | Variant constructors -> Some (Tvariant - {env; constructors; variantName = typ.name; variantDecl = typ.decl}) + { + env; + constructors; + variantName = typ.name; + variantDecl = typ.decl; + typeParams = typ.decl.type_params; + typeArgs = []; + }) | Abstract _ | Open -> ( match typ.decl.type_manifest with | None -> None @@ -345,8 +361,8 @@ let rec resolveNested ~env ~full ~nested ?ctx (typ : completionType) = typ |> extractType ~env ~package:full.package |> Utils.Option.flatMap (fun t -> t |> resolveNested ~env ~full ~nested) - | NVariantPayload {constructorName; itemNum}, Tvariant {env; constructors} - -> ( + | ( NVariantPayload {constructorName; itemNum}, + Tvariant {env; constructors; typeParams; typeArgs} ) -> ( match constructors |> List.find_opt (fun (c : Constructor.t) -> @@ -357,6 +373,7 @@ let rec resolveNested ~env ~full ~nested ?ctx (typ : completionType) = | None -> None | Some (typ, _) -> typ + |> instantiateType ~typeParams ~typeArgs |> extractType ~env ~package:full.package |> Utils.Option.flatMap (fun typ -> typ |> resolveNested ~env ~full ~nested)) diff --git a/analysis/tests/src/CompletionPattern.res b/analysis/tests/src/CompletionPattern.res index aae445bb9..3fed00c55 100644 --- a/analysis/tests/src/CompletionPattern.res +++ b/analysis/tests/src/CompletionPattern.res @@ -211,3 +211,8 @@ let getThing = async () => One // switch await getThing() { | } // ^com + +let res: result = Ok(One) + +// switch res { | Ok() } +// ^com diff --git a/analysis/tests/src/expected/CompletionPattern.res.txt b/analysis/tests/src/expected/CompletionPattern.res.txt index d74cfec1a..028058000 100644 --- a/analysis/tests/src/expected/CompletionPattern.res.txt +++ b/analysis/tests/src/expected/CompletionPattern.res.txt @@ -1105,3 +1105,39 @@ Path getThing "insertTextFormat": 2 }] +Complete src/CompletionPattern.res 216:21 +posCursor:[216:21] posNoWhite:[216:20] Found pattern:[216:18->216:22] +Ppat_construct Ok:[216:18->216:20] +posCursor:[216:21] posNoWhite:[216:20] Found pattern:[216:20->216:22] +Ppat_construct ():[216:20->216:22] +Completable: Cpattern Value[res]->variantPayload::Ok($0) +Package opens Pervasives.JsxModules.place holder +Resolved opens 1 pervasives +ContextPath Value[res] +Path res +[{ + "label": "One", + "kind": 4, + "tags": [], + "detail": "One\n\ntype someVariant = One | Two(bool) | Three(someRecord, bool)", + "documentation": null, + "insertText": "One", + "insertTextFormat": 2 + }, { + "label": "Two(_)", + "kind": 4, + "tags": [], + "detail": "Two(bool)\n\ntype someVariant = One | Two(bool) | Three(someRecord, bool)", + "documentation": null, + "insertText": "Two(${1:_})", + "insertTextFormat": 2 + }, { + "label": "Three(_, _)", + "kind": 4, + "tags": [], + "detail": "Three(someRecord, bool)\n\ntype someVariant = One | Two(bool) | Three(someRecord, bool)", + "documentation": null, + "insertText": "Three(${1:_}, ${2:_})", + "insertTextFormat": 2 + }] + From b76665e34c8f5ea0c797971122cb046fa859c116 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 20 Aug 2023 12:30:19 +0200 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7db9c4332..f097e5d66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - Fix JS syntax highlighting in single-line FFI extension points. https://github.com/rescript-lang/rescript-vscode/pull/807 - Fix signature help in uncurried mode. https://github.com/rescript-lang/rescript-vscode/pull/809 - Fix various issues in uncurried mode. https://github.com/rescript-lang/rescript-vscode/pull/810 +- Fixes a bug in pattern completion where for example `result` wouldn't complete, due to type variables getting lost/not being instantiated. https://github.com/rescript-lang/rescript-vscode/pull/814 ## 1.18.0