From 6de71cff16fde3c43ca5a07ae2a1521024df830b Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Wed, 31 Aug 2022 18:33:18 +0200 Subject: [PATCH 1/9] Add example of missing autocompletion requiring type instantiation. See https://github.com/rescript-lang/rescript-vscode/issues/349 --- analysis/tests/src/Hover.res | 5 +++++ analysis/tests/src/expected/Hover.res.txt | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/analysis/tests/src/Hover.res b/analysis/tests/src/Hover.res index 732213a82..094c59bd1 100644 --- a/analysis/tests/src/Hover.res +++ b/analysis/tests/src/Hover.res @@ -165,4 +165,9 @@ module TypeSubstitutionRecords = { // ^hov let x2: foobar = {content: {age: 42}, zzz: ""} // ^hov + + // ^db+ + + // x1.content. + // ^com } diff --git a/analysis/tests/src/expected/Hover.res.txt b/analysis/tests/src/expected/Hover.res.txt index db5dc5dfa..c10e64f58 100644 --- a/analysis/tests/src/expected/Hover.res.txt +++ b/analysis/tests/src/expected/Hover.res.txt @@ -110,3 +110,19 @@ Hover src/Hover.res 163:23 Hover src/Hover.res 165:22 {"contents": "```rescript\nfoobar\n```\n\n```rescript\ntype foobar = foo\n```"} + +Complete src/Hover.res 170:16 +posCursor:[170:16] posNoWhite:[170:15] Found expr:[170:5->170:16] +Pexp_field [170:5->170:15] _:[172:0->170:16] +Completable: Cpath Value[x1].content."" +Ident!! Dep +Ident!! JsLogger +Ident!! A +Ident!! B +Ident!! Comp +Raw ppens: 0 +Package opens +Resolved opens 0 +findLocalCompletionsWithOpens uri:Hover.res pos:170:16 +[] + From 62fdeb89cc6f6f6b9a8288e27426b9f28d92c9c5 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Wed, 31 Aug 2022 20:48:34 +0200 Subject: [PATCH 2/9] Perform type instantiation in field autocompletion Fixes https://github.com/rescript-lang/rescript-vscode/issues/349 --- CHANGELOG.md | 1 + analysis/src/CompletionBackEnd.ml | 59 +++++++++++++++++++++-- analysis/tests/src/Hover.res | 5 +- analysis/tests/src/expected/Hover.res.txt | 36 ++++++++------ 4 files changed, 82 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 990cbb3c9..78d7e69a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ #### :bug: Bug Fix +- Fix issue where field autocomplete in records would not perform type instantiation https://github.com/rescript-lang/rescript-vscode/pull/561 - Fix issue where hovering over a field in record construction would show the type without instantiating its type arguments https://github.com/rescript-lang/rescript-vscode/pull/560 - Fix Incorrect semantic highlighting of `external` declarations https://github.com/rescript-lang/rescript-vscode/pull/517 - Fix issue where doc comment with nested comments inside is not shown properly on hover https://github.com/rescript-lang/rescript-vscode/pull/526 diff --git a/analysis/src/CompletionBackEnd.ml b/analysis/src/CompletionBackEnd.ml index 387abd6b8..e93809af6 100644 --- a/analysis/src/CompletionBackEnd.ml +++ b/analysis/src/CompletionBackEnd.ml @@ -983,10 +983,10 @@ let findLocalCompletionsWithOpens ~pos ~(env : QueryEnv.t) ~prefix ~exact ~opens let rec extractRecordType ~env ~package (t : Types.type_expr) = match t.desc with | Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> extractRecordType ~env ~package t1 - | Tconstr (path, _, _) -> ( + | Tconstr (path, args, _) -> ( match References.digConstructor ~env ~package path with | Some (env, ({item = {kind = Record fields}} as typ)) -> - Some (env, fields, typ) + Some (env, fields, typ, args) | Some (env, {item = {decl = {type_manifest = Some t1}}}) -> extractRecordType ~env ~package t1 | _ -> None) @@ -1087,6 +1087,54 @@ let completionsGetTypeEnv = function | {Completion.kind = Field ({typ}, _); env} :: _ -> Some (typ, env) | _ -> None +let instantiateType ~typeParams ~typeArgs (t : Types.type_expr) = + if typeParams = [] || typeArgs = [] then t + else + let rec applySub tp ta t = + match (tp, ta) with + | t1 :: tRest1, t2 :: tRest2 -> + if t1 = t then t2 else applySub tRest1 tRest2 t + | [], _ | _, [] -> assert false + in + let rec loop (t : Types.type_expr) = + match t.desc with + | Tlink t -> loop t + | Tvar _ -> applySub typeParams typeArgs t + | Tunivar _ -> t + | Tconstr (path, args, memo) -> + {t with desc = Tconstr (path, args |> List.map loop, memo)} + | Tsubst t -> loop t + | Tvariant rd -> {t with desc = Tvariant (rowDesc rd)} + | Tnil -> t + | Tarrow (lbl, t1, t2, c) -> + {t with desc = Tarrow (lbl, loop t1, loop t2, c)} + | Ttuple tl -> {t with desc = Ttuple (tl |> List.map loop)} + | Tobject (t, r) -> {t with desc = Tobject (loop t, r)} + | Tfield (n, k, t1, t2) -> {t with desc = Tfield (n, k, loop t1, loop t2)} + | Tpoly (t, []) -> loop t + | Tpoly (t, tl) -> {t with desc = Tpoly (loop t, tl |> List.map loop)} + | Tpackage (p, l, tl) -> + {t with desc = Tpackage (p, l, tl |> List.map loop)} + and rowDesc (rd : Types.row_desc) = + let row_fields = + rd.row_fields |> List.map (fun (l, rf) -> (l, rowField rf)) + in + let row_more = loop rd.row_more in + let row_name = + match rd.row_name with + | None -> None + | Some (p, tl) -> Some (p, tl |> List.map loop) + in + {rd with row_fields; row_more; row_name} + and rowField (rf : Types.row_field) = + match rf with + | Rpresent None -> rf + | Rpresent (Some t) -> Rpresent (Some (loop t)) + | Reither (b1, tl, b2, r) -> Reither (b1, tl |> List.map loop, b2, r) + | Rabsent -> Rabsent + in + loop t + let rec getCompletionsForContextPath ~package ~opens ~rawOpens ~allFiles ~pos ~env ~exact ~scope (contextPath : Completable.contextPath) = match contextPath with @@ -1163,9 +1211,14 @@ let rec getCompletionsForContextPath ~package ~opens ~rawOpens ~allFiles ~pos with | Some (typ, env) -> ( match typ |> extractRecordType ~env ~package with - | Some (env, fields, typDecl) -> + | Some (env, fields, typDecl, typeArgs) -> + let typeParams = typDecl.item.decl.type_params in fields |> Utils.filterMap (fun field -> + let fieldTyp = + field.typ |> instantiateType ~typeParams ~typeArgs + in + let field = {field with typ = fieldTyp} in if checkName field.fname.txt ~prefix:fieldName ~exact then Some (Completion.create ~name:field.fname.txt ~env diff --git a/analysis/tests/src/Hover.res b/analysis/tests/src/Hover.res index 094c59bd1..487ddd116 100644 --- a/analysis/tests/src/Hover.res +++ b/analysis/tests/src/Hover.res @@ -166,8 +166,9 @@ module TypeSubstitutionRecords = { let x2: foobar = {content: {age: 42}, zzz: ""} // ^hov - // ^db+ - // x1.content. // ^com + + // x2.content. + // ^com } diff --git a/analysis/tests/src/expected/Hover.res.txt b/analysis/tests/src/expected/Hover.res.txt index c10e64f58..b6b7d21e6 100644 --- a/analysis/tests/src/expected/Hover.res.txt +++ b/analysis/tests/src/expected/Hover.res.txt @@ -110,19 +110,27 @@ Hover src/Hover.res 163:23 Hover src/Hover.res 165:22 {"contents": "```rescript\nfoobar\n```\n\n```rescript\ntype foobar = foo\n```"} - -Complete src/Hover.res 170:16 -posCursor:[170:16] posNoWhite:[170:15] Found expr:[170:5->170:16] -Pexp_field [170:5->170:15] _:[172:0->170:16] +Complete src/Hover.res 168:16 +posCursor:[168:16] posNoWhite:[168:15] Found expr:[168:5->168:16] +Pexp_field [168:5->168:15] _:[173:0->168:16] Completable: Cpath Value[x1].content."" -Ident!! Dep -Ident!! JsLogger -Ident!! A -Ident!! B -Ident!! Comp -Raw ppens: 0 -Package opens -Resolved opens 0 -findLocalCompletionsWithOpens uri:Hover.res pos:170:16 -[] +[{ + "label": "age", + "kind": 5, + "tags": [], + "detail": "age: int\n\ntype bar = {age: int}", + "documentation": null + }] + +Complete src/Hover.res 171:16 +posCursor:[171:16] posNoWhite:[171:15] Found expr:[171:5->171:16] +Pexp_field [171:5->171:15] _:[173:0->171:16] +Completable: Cpath Value[x2].content."" +[{ + "label": "age", + "kind": 5, + "tags": [], + "detail": "age: int\n\ntype bar = {age: int}", + "documentation": null + }] From 03204925ba1b3293d1f0c2200fdda8002a273a13 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Thu, 1 Sep 2022 05:23:06 +0200 Subject: [PATCH 3/9] Refactor type substitution inside extractRecordType. This reveals one record case that is not handled. --- analysis/src/CompletionBackEnd.ml | 116 +++++++++++++++--------------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/analysis/src/CompletionBackEnd.ml b/analysis/src/CompletionBackEnd.ml index e93809af6..b2bbe0c7d 100644 --- a/analysis/src/CompletionBackEnd.ml +++ b/analysis/src/CompletionBackEnd.ml @@ -980,13 +980,70 @@ let findLocalCompletionsWithOpens ~pos ~(env : QueryEnv.t) ~prefix ~exact ~opens (* There's no local completion for fields *) [] +let instantiateType ~typeParams ~typeArgs (t : Types.type_expr) = + if typeParams = [] || typeArgs = [] then t + else + let rec applySub tp ta t = + match (tp, ta) with + | t1 :: tRest1, t2 :: tRest2 -> + if t1 = t then t2 else applySub tRest1 tRest2 t + | [], _ | _, [] -> assert false + in + let rec loop (t : Types.type_expr) = + match t.desc with + | Tlink t -> loop t + | Tvar _ -> applySub typeParams typeArgs t + | Tunivar _ -> t + | Tconstr (path, args, memo) -> + {t with desc = Tconstr (path, args |> List.map loop, memo)} + | Tsubst t -> loop t + | Tvariant rd -> {t with desc = Tvariant (rowDesc rd)} + | Tnil -> t + | Tarrow (lbl, t1, t2, c) -> + {t with desc = Tarrow (lbl, loop t1, loop t2, c)} + | Ttuple tl -> {t with desc = Ttuple (tl |> List.map loop)} + | Tobject (t, r) -> {t with desc = Tobject (loop t, r)} + | Tfield (n, k, t1, t2) -> {t with desc = Tfield (n, k, loop t1, loop t2)} + | Tpoly (t, []) -> loop t + | Tpoly (t, tl) -> {t with desc = Tpoly (loop t, tl |> List.map loop)} + | Tpackage (p, l, tl) -> + {t with desc = Tpackage (p, l, tl |> List.map loop)} + and rowDesc (rd : Types.row_desc) = + let row_fields = + rd.row_fields |> List.map (fun (l, rf) -> (l, rowField rf)) + in + let row_more = loop rd.row_more in + let row_name = + match rd.row_name with + | None -> None + | Some (p, tl) -> Some (p, tl |> List.map loop) + in + {rd with row_fields; row_more; row_name} + and rowField (rf : Types.row_field) = + match rf with + | Rpresent None -> rf + | Rpresent (Some t) -> Rpresent (Some (loop t)) + | Reither (b1, tl, b2, r) -> Reither (b1, tl |> List.map loop, b2, r) + | Rabsent -> Rabsent + in + loop t + let rec extractRecordType ~env ~package (t : Types.type_expr) = match t.desc with | Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> extractRecordType ~env ~package t1 - | Tconstr (path, args, _) -> ( + | Tconstr (path, typeArgs, _) -> ( match References.digConstructor ~env ~package path with | Some (env, ({item = {kind = Record fields}} as typ)) -> - Some (env, fields, typ, args) + let typeParams = typ.item.decl.type_params in + let fields = + fields + |> List.map (fun field -> + let fieldTyp = + field.typ |> instantiateType ~typeParams ~typeArgs + in + {field with typ = fieldTyp}) + in + Some (env, fields, typ) | Some (env, {item = {decl = {type_manifest = Some t1}}}) -> extractRecordType ~env ~package t1 | _ -> None) @@ -1087,54 +1144,6 @@ let completionsGetTypeEnv = function | {Completion.kind = Field ({typ}, _); env} :: _ -> Some (typ, env) | _ -> None -let instantiateType ~typeParams ~typeArgs (t : Types.type_expr) = - if typeParams = [] || typeArgs = [] then t - else - let rec applySub tp ta t = - match (tp, ta) with - | t1 :: tRest1, t2 :: tRest2 -> - if t1 = t then t2 else applySub tRest1 tRest2 t - | [], _ | _, [] -> assert false - in - let rec loop (t : Types.type_expr) = - match t.desc with - | Tlink t -> loop t - | Tvar _ -> applySub typeParams typeArgs t - | Tunivar _ -> t - | Tconstr (path, args, memo) -> - {t with desc = Tconstr (path, args |> List.map loop, memo)} - | Tsubst t -> loop t - | Tvariant rd -> {t with desc = Tvariant (rowDesc rd)} - | Tnil -> t - | Tarrow (lbl, t1, t2, c) -> - {t with desc = Tarrow (lbl, loop t1, loop t2, c)} - | Ttuple tl -> {t with desc = Ttuple (tl |> List.map loop)} - | Tobject (t, r) -> {t with desc = Tobject (loop t, r)} - | Tfield (n, k, t1, t2) -> {t with desc = Tfield (n, k, loop t1, loop t2)} - | Tpoly (t, []) -> loop t - | Tpoly (t, tl) -> {t with desc = Tpoly (loop t, tl |> List.map loop)} - | Tpackage (p, l, tl) -> - {t with desc = Tpackage (p, l, tl |> List.map loop)} - and rowDesc (rd : Types.row_desc) = - let row_fields = - rd.row_fields |> List.map (fun (l, rf) -> (l, rowField rf)) - in - let row_more = loop rd.row_more in - let row_name = - match rd.row_name with - | None -> None - | Some (p, tl) -> Some (p, tl |> List.map loop) - in - {rd with row_fields; row_more; row_name} - and rowField (rf : Types.row_field) = - match rf with - | Rpresent None -> rf - | Rpresent (Some t) -> Rpresent (Some (loop t)) - | Reither (b1, tl, b2, r) -> Reither (b1, tl |> List.map loop, b2, r) - | Rabsent -> Rabsent - in - loop t - let rec getCompletionsForContextPath ~package ~opens ~rawOpens ~allFiles ~pos ~env ~exact ~scope (contextPath : Completable.contextPath) = match contextPath with @@ -1211,14 +1220,9 @@ let rec getCompletionsForContextPath ~package ~opens ~rawOpens ~allFiles ~pos with | Some (typ, env) -> ( match typ |> extractRecordType ~env ~package with - | Some (env, fields, typDecl, typeArgs) -> - let typeParams = typDecl.item.decl.type_params in + | Some (env, fields, typDecl) -> fields |> Utils.filterMap (fun field -> - let fieldTyp = - field.typ |> instantiateType ~typeParams ~typeArgs - in - let field = {field with typ = fieldTyp} in if checkName field.fname.txt ~prefix:fieldName ~exact then Some (Completion.create ~name:field.fname.txt ~env From acc38992731e29da6bd712afceb646b1cd2ed11b Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Thu, 1 Sep 2022 05:23:50 +0200 Subject: [PATCH 4/9] Add example of record instantiation and alias -- not working yet. --- analysis/tests/src/Hover.res | 12 ++++++++++++ analysis/tests/src/expected/Hover.res.txt | 16 ++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/analysis/tests/src/Hover.res b/analysis/tests/src/Hover.res index 487ddd116..593d40473 100644 --- a/analysis/tests/src/Hover.res +++ b/analysis/tests/src/Hover.res @@ -171,4 +171,16 @@ module TypeSubstitutionRecords = { // x2.content. // ^com + + type foo2<'b> = foo<'b> + type foobar2 = foo2 + + let y1: foo2 = {content: {age: 42}, zzz: ""} + let y2: foobar2 = {content: {age: 42}, zzz: ""} + + // y1.content. + // ^com + + // y2.content. + // ^com } diff --git a/analysis/tests/src/expected/Hover.res.txt b/analysis/tests/src/expected/Hover.res.txt index b6b7d21e6..676dc4c94 100644 --- a/analysis/tests/src/expected/Hover.res.txt +++ b/analysis/tests/src/expected/Hover.res.txt @@ -112,7 +112,7 @@ Hover src/Hover.res 165:22 Complete src/Hover.res 168:16 posCursor:[168:16] posNoWhite:[168:15] Found expr:[168:5->168:16] -Pexp_field [168:5->168:15] _:[173:0->168:16] +Pexp_field [168:5->168:15] _:[174:2->168:16] Completable: Cpath Value[x1].content."" [{ "label": "age", @@ -124,7 +124,7 @@ Completable: Cpath Value[x1].content."" Complete src/Hover.res 171:16 posCursor:[171:16] posNoWhite:[171:15] Found expr:[171:5->171:16] -Pexp_field [171:5->171:15] _:[173:0->171:16] +Pexp_field [171:5->171:15] _:[174:2->171:16] Completable: Cpath Value[x2].content."" [{ "label": "age", @@ -134,3 +134,15 @@ Completable: Cpath Value[x2].content."" "documentation": null }] +Complete src/Hover.res 180:16 +posCursor:[180:16] posNoWhite:[180:15] Found expr:[180:5->180:16] +Pexp_field [180:5->180:15] _:[185:0->180:16] +Completable: Cpath Value[y1].content."" +[] + +Complete src/Hover.res 183:16 +posCursor:[183:16] posNoWhite:[183:15] Found expr:[183:5->183:16] +Pexp_field [183:5->183:15] _:[185:0->183:16] +Completable: Cpath Value[y2].content."" +[] + From 34694715e09db7a0f234fa449959c1b2ea12afaa Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Thu, 1 Sep 2022 05:26:03 +0200 Subject: [PATCH 5/9] Support type instantiation in the presence of aliasing. --- analysis/src/CompletionBackEnd.ml | 6 +++++- analysis/tests/src/expected/Hover.res.txt | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/analysis/src/CompletionBackEnd.ml b/analysis/src/CompletionBackEnd.ml index b2bbe0c7d..a4a1d326e 100644 --- a/analysis/src/CompletionBackEnd.ml +++ b/analysis/src/CompletionBackEnd.ml @@ -1044,7 +1044,11 @@ let rec extractRecordType ~env ~package (t : Types.type_expr) = {field with typ = fieldTyp}) in Some (env, fields, typ) - | Some (env, {item = {decl = {type_manifest = Some t1}}}) -> + | Some + ( env, + {item = {decl = {type_manifest = Some t1; type_params = typeParams}}} + ) -> + let t1 = t1 |> instantiateType ~typeParams ~typeArgs in extractRecordType ~env ~package t1 | _ -> None) | _ -> None diff --git a/analysis/tests/src/expected/Hover.res.txt b/analysis/tests/src/expected/Hover.res.txt index 676dc4c94..93d8616be 100644 --- a/analysis/tests/src/expected/Hover.res.txt +++ b/analysis/tests/src/expected/Hover.res.txt @@ -138,11 +138,23 @@ Complete src/Hover.res 180:16 posCursor:[180:16] posNoWhite:[180:15] Found expr:[180:5->180:16] Pexp_field [180:5->180:15] _:[185:0->180:16] Completable: Cpath Value[y1].content."" -[] +[{ + "label": "age", + "kind": 5, + "tags": [], + "detail": "age: int\n\ntype bar = {age: int}", + "documentation": null + }] Complete src/Hover.res 183:16 posCursor:[183:16] posNoWhite:[183:15] Found expr:[183:5->183:16] Pexp_field [183:5->183:15] _:[185:0->183:16] Completable: Cpath Value[y2].content."" -[] +[{ + "label": "age", + "kind": 5, + "tags": [], + "detail": "age: int\n\ntype bar = {age: int}", + "documentation": null + }] From 781f80abb549028cfdecd0fb133ae7d2e6f27547 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Thu, 1 Sep 2022 10:08:59 +0200 Subject: [PATCH 6/9] Type instantiation when extracting object or function types. --- analysis/src/CompletionBackEnd.ml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/analysis/src/CompletionBackEnd.ml b/analysis/src/CompletionBackEnd.ml index a4a1d326e..875248142 100644 --- a/analysis/src/CompletionBackEnd.ml +++ b/analysis/src/CompletionBackEnd.ml @@ -1057,9 +1057,10 @@ let rec extractObjectType ~env ~package (t : Types.type_expr) = match t.desc with | Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> extractObjectType ~env ~package t1 | Tobject (tObj, _) -> Some (env, tObj) - | Tconstr (path, _, _) -> ( + | Tconstr (path, typeArgs, _) -> ( match References.digConstructor ~env ~package path with - | Some (env, {item = {decl = {type_manifest = Some t1}}}) -> + | Some (env, {item = {decl = {type_manifest = Some t1; type_params = typeParams}}}) -> + let t1 = t1 |> instantiateType ~typeParams ~typeArgs in extractObjectType ~env ~package t1 | _ -> None) | _ -> None @@ -1069,9 +1070,10 @@ let extractFunctionType ~env ~package typ = match t.desc with | Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> loop ~env acc t1 | Tarrow (label, tArg, tRet, _) -> loop ~env ((label, tArg) :: acc) tRet - | Tconstr (path, _, _) -> ( + | Tconstr (path, typeArgs, _) -> ( match References.digConstructor ~env ~package path with - | Some (env, {item = {decl = {type_manifest = Some t1}}}) -> + | Some (env, {item = {decl = {type_manifest = Some t1; type_params = typeParams}}}) -> + let t1 = t1 |> instantiateType ~typeParams ~typeArgs in loop ~env acc t1 | _ -> (List.rev acc, t)) | _ -> (List.rev acc, t) From 292c6d66ad32b483c95e65bc03e8a73e3995a99f Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Thu, 1 Sep 2022 10:14:08 +0200 Subject: [PATCH 7/9] Handle type instantiation for named argument completion. --- analysis/src/CompletionBackEnd.ml | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/analysis/src/CompletionBackEnd.ml b/analysis/src/CompletionBackEnd.ml index 875248142..1120f3e7f 100644 --- a/analysis/src/CompletionBackEnd.ml +++ b/analysis/src/CompletionBackEnd.ml @@ -1059,7 +1059,10 @@ let rec extractObjectType ~env ~package (t : Types.type_expr) = | Tobject (tObj, _) -> Some (env, tObj) | Tconstr (path, typeArgs, _) -> ( match References.digConstructor ~env ~package path with - | Some (env, {item = {decl = {type_manifest = Some t1; type_params = typeParams}}}) -> + | Some + ( env, + {item = {decl = {type_manifest = Some t1; type_params = typeParams}}} + ) -> let t1 = t1 |> instantiateType ~typeParams ~typeArgs in extractObjectType ~env ~package t1 | _ -> None) @@ -1072,7 +1075,11 @@ let extractFunctionType ~env ~package typ = | Tarrow (label, tArg, tRet, _) -> loop ~env ((label, tArg) :: acc) tRet | Tconstr (path, typeArgs, _) -> ( match References.digConstructor ~env ~package path with - | Some (env, {item = {decl = {type_manifest = Some t1; type_params = typeParams}}}) -> + | Some + ( env, + { + item = {decl = {type_manifest = Some t1; type_params = typeParams}}; + } ) -> let t1 = t1 |> instantiateType ~typeParams ~typeArgs in loop ~env acc t1 | _ -> (List.rev acc, t)) @@ -1731,9 +1738,18 @@ Note: The `@react.component` decorator requires the react-jsx config to be set i | Tarrow ((Labelled l | Optional l), tArg, tRet, _) -> (l, tArg) :: getLabels ~env tRet | Tarrow (Nolabel, _, tRet, _) -> getLabels ~env tRet - | Tconstr (path, _, _) -> ( + | Tconstr (path, typeArgs, _) -> ( match References.digConstructor ~env ~package path with - | Some (env, {item = {decl = {type_manifest = Some t1}}}) -> + | Some + ( env, + { + item = + { + decl = + {type_manifest = Some t1; type_params = typeParams}; + }; + } ) -> + let t1 = t1 |> instantiateType ~typeParams ~typeArgs in getLabels ~env t1 | _ -> []) | _ -> [] From 4c7dd9825bb4115f442a7e14b3c32ce1184bc190 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Thu, 1 Sep 2022 10:16:10 +0200 Subject: [PATCH 8/9] Rename+refactor getConstr to make it clear type instantiation is not required. --- analysis/src/CompletionBackEnd.ml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/analysis/src/CompletionBackEnd.ml b/analysis/src/CompletionBackEnd.ml index 1120f3e7f..603066b95 100644 --- a/analysis/src/CompletionBackEnd.ml +++ b/analysis/src/CompletionBackEnd.ml @@ -1304,17 +1304,17 @@ let rec getCompletionsForContextPath ~package ~opens ~rawOpens ~allFiles ~pos | _ :: rest -> List.rev rest | [] -> []) in - let getConstr typ = + let getConstrPath typ = match typ.Types.desc with - | Tconstr (path, _, _) - | Tlink {desc = Tconstr (path, _, _)} - | Tsubst {desc = Tconstr (path, _, _)} - | Tpoly ({desc = Tconstr (path, _, _)}, []) -> + | Tconstr (path, _typeArgs, _) + | Tlink {desc = Tconstr (path, _typeArgs, _)} + | Tsubst {desc = Tconstr (path, _typeArgs, _)} + | Tpoly ({desc = Tconstr (path, _typeArgs, _)}, []) -> Some path | _ -> None in let fromType typ = - match getConstr typ with + match getConstrPath typ with | None -> None | Some path -> Some (getModulePath path) in From b805dc8c7500d8c3858dbfc303293471574b51b7 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Thu, 1 Sep 2022 10:17:06 +0200 Subject: [PATCH 9/9] Update changelog to talk about type instantiation for autocomplete in general. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78d7e69a9..b0238454a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ #### :bug: Bug Fix -- Fix issue where field autocomplete in records would not perform type instantiation https://github.com/rescript-lang/rescript-vscode/pull/561 +- Fix issue where autocomplete would not perform type instantiation https://github.com/rescript-lang/rescript-vscode/pull/561 - Fix issue where hovering over a field in record construction would show the type without instantiating its type arguments https://github.com/rescript-lang/rescript-vscode/pull/560 - Fix Incorrect semantic highlighting of `external` declarations https://github.com/rescript-lang/rescript-vscode/pull/517 - Fix issue where doc comment with nested comments inside is not shown properly on hover https://github.com/rescript-lang/rescript-vscode/pull/526