Skip to content

Commit 35b5849

Browse files
zthcristianoc
authored andcommitted
follow variant payloads
1 parent 881edb1 commit 35b5849

File tree

3 files changed

+58
-9
lines changed

3 files changed

+58
-9
lines changed

analysis/src/TypeUtils.ml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,19 @@ let findTypeOfRecordField fields ~fieldName =
358358
let typ = if optional then Utils.unwrapIfOption typ else typ in
359359
Some typ
360360

361+
let findTypeOfConstructorArg constructors ~constructorName ~payloadNum ~env =
362+
match
363+
constructors
364+
|> List.find_opt (fun (c : Constructor.t) -> c.cname.txt = constructorName)
365+
with
366+
| Some {args = Args args} -> (
367+
match List.nth_opt args payloadNum with
368+
| None -> None
369+
| Some (typ, _) -> Some (TypeExpr typ))
370+
| Some {args = InlineRecord fields} when payloadNum = 0 ->
371+
Some (ExtractedType (TinlineRecord {env; fields}))
372+
| _ -> None
373+
361374
let rec resolveNestedPatternPath (typ : innerType) ~env ~full ~nested =
362375
let t =
363376
match typ with
@@ -380,6 +393,14 @@ let rec resolveNestedPatternPath (typ : innerType) ~env ~full ~nested =
380393
match List.nth_opt tupleItems itemNum with
381394
| None -> None
382395
| Some typ -> Some (TypeExpr typ, env))
396+
| NVariantPayload {constructorName; itemNum}, Tvariant {env; constructors}
397+
-> (
398+
match
399+
constructors
400+
|> findTypeOfConstructorArg ~constructorName ~payloadNum:itemNum ~env
401+
with
402+
| Some typ -> Some (typ, env)
403+
| None -> None)
383404
| _ -> None))
384405
| patternPath :: nested -> (
385406
match t with
@@ -405,6 +426,14 @@ let rec resolveNestedPatternPath (typ : innerType) ~env ~full ~nested =
405426
|> Utils.Option.flatMap (fun typ ->
406427
ExtractedType typ
407428
|> resolveNestedPatternPath ~env ~full ~nested))
429+
| NVariantPayload {constructorName; itemNum}, Tvariant {env; constructors}
430+
-> (
431+
match
432+
constructors
433+
|> findTypeOfConstructorArg ~constructorName ~payloadNum:itemNum ~env
434+
with
435+
| Some typ -> typ |> resolveNestedPatternPath ~env ~full ~nested
436+
| None -> None)
408437
| _ -> None))
409438

410439
let getArgs ~env (t : Types.type_expr) ~full =

analysis/tests/src/CompletionInferValues.res

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ type otherNestedRecord = {someRecord: someRecord, someTuple: (someVariant, int)}
9999
// let x: otherNestedRecord; switch x { | {someTuple} => let (_, someInt) = someTuple; someInt->toS }
100100
// ^com
101101

102+
// Follow variant payloads
103+
// let x: otherNestedRecord; switch x { | {someTuple:(Three(_, str), _)} => str->slic }
104+
// ^com
102105
let fnWithRecordCallback = (cb: someRecord => unit) => {
103106
let _ = cb
104107
}

analysis/tests/src/expected/CompletionInferValues.res.txt

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ Completable: Cpath Value[x].""
222222

223223
Complete src/CompletionInferValues.res 74:78
224224
posCursor:[74:78] posNoWhite:[74:77] Found expr:[74:70->74:78]
225-
Pexp_field [74:70->74:77] _:[101:0->74:78]
225+
Pexp_field [74:70->74:77] _:[104:0->74:78]
226226
Completable: Cpath Value[srecord].""
227227
[{
228228
"label": "name",
@@ -240,7 +240,7 @@ Completable: Cpath Value[srecord].""
240240

241241
Complete src/CompletionInferValues.res 78:86
242242
posCursor:[78:86] posNoWhite:[78:85] Found expr:[78:78->78:86]
243-
Pexp_field [78:78->78:85] _:[101:0->78:86]
243+
Pexp_field [78:78->78:85] _:[104:0->78:86]
244244
Completable: Cpath Value[aliased].""
245245
[{
246246
"label": "someRecord",
@@ -252,7 +252,7 @@ Completable: Cpath Value[aliased].""
252252

253253
Complete src/CompletionInferValues.res 82:103
254254
posCursor:[82:103] posNoWhite:[82:102] Found expr:[82:92->82:103]
255-
Pexp_field [82:92->82:102] _:[101:0->82:103]
255+
Pexp_field [82:92->82:102] _:[104:0->82:103]
256256
Completable: Cpath Value[someRecord].""
257257
[{
258258
"label": "name",
@@ -319,12 +319,29 @@ Completable: Cpath Value[someInt]->toS
319319
"documentation": {"kind": "markdown", "value": "\n Converts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n ```res example\n Js.log(Belt.Int.toString(1) === \"1\") /* true */\n ```\n"}
320320
}]
321321

322-
Complete src/CompletionInferValues.res 105:26
323-
posCursor:[105:26] posNoWhite:[105:25] Found expr:[105:3->105:37]
324-
Pexp_apply ...[105:3->105:23] (...[105:24->105:36])
325-
posCursor:[105:26] posNoWhite:[105:25] Found expr:[105:24->105:36]
326-
posCursor:[105:26] posNoWhite:[105:25] Found pattern:[105:25->105:27]
327-
posCursor:[105:26] posNoWhite:[105:25] Found pattern:[105:25->105:27]
322+
Complete src/CompletionInferValues.res 102:85
323+
posCursor:[102:85] posNoWhite:[102:84] Found expr:[102:76->102:85]
324+
Completable: Cpath Value[str]->slic
325+
[{
326+
"label": "Js.String2.sliceToEnd",
327+
"kind": 12,
328+
"tags": [],
329+
"detail": "(t, ~from: int) => t",
330+
"documentation": {"kind": "markdown", "value": "\n`sliceToEnd(str, from:n)` returns the substring of `str` starting at character\n`n` to the end of the string.\n- If `n` is negative, then it is evaluated as `length(str - n)`.\n- If `n` is greater than the length of `str`, then sliceToEnd returns the empty string.\n\nSee [`String.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) on MDN.\n\n```res example\nJs.String2.sliceToEnd(\"abcdefg\", ~from=4) == \"efg\"\nJs.String2.sliceToEnd(\"abcdefg\", ~from=-2) == \"fg\"\nJs.String2.sliceToEnd(\"abcdefg\", ~from=7) == \"\"\n```\n"}
331+
}, {
332+
"label": "Js.String2.slice",
333+
"kind": 12,
334+
"tags": [],
335+
"detail": "(t, ~from: int, ~to_: int) => t",
336+
"documentation": {"kind": "markdown", "value": "\n`slice(str, from:n1, to_:n2)` returns the substring of `str` starting at\ncharacter `n1` up to but not including `n2`.\n- If either `n1` or `n2` is negative, then it is evaluated as `length(str - n1)` or `length(str - n2)`.\n- If `n2` is greater than the length of `str`, then it is treated as `length(str)`.\n- If `n1` is greater than `n2`, slice returns the empty string.\n\nSee [`String.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) on MDN.\n\n```res example\nJs.String2.slice(\"abcdefg\", ~from=2, ~to_=5) == \"cde\"\nJs.String2.slice(\"abcdefg\", ~from=2, ~to_=9) == \"cdefg\"\nJs.String2.slice(\"abcdefg\", ~from=-4, ~to_=-2) == \"de\"\nJs.String2.slice(\"abcdefg\", ~from=5, ~to_=1) == \"\"\n```\n"}
337+
}]
338+
339+
Complete src/CompletionInferValues.res 109:26
340+
posCursor:[109:26] posNoWhite:[109:25] Found expr:[109:3->109:37]
341+
Pexp_apply ...[109:3->109:23] (...[109:24->109:36])
342+
posCursor:[109:26] posNoWhite:[109:25] Found expr:[109:24->109:36]
343+
posCursor:[109:26] posNoWhite:[109:25] Found pattern:[109:25->109:27]
344+
posCursor:[109:26] posNoWhite:[109:25] Found pattern:[109:25->109:27]
328345
Completable: Cpattern CArgument CArgument Value[fnWithRecordCallback]($0)($0)->recordBody
329346
[{
330347
"label": "name",

0 commit comments

Comments
 (0)