Skip to content

Commit 9934131

Browse files
zthcristianoc
authored andcommitted
follow polyvariant payloads
1 parent 35b5849 commit 9934131

File tree

3 files changed

+85
-33
lines changed

3 files changed

+85
-33
lines changed

analysis/src/TypeUtils.ml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,18 @@ let findTypeOfConstructorArg constructors ~constructorName ~payloadNum ~env =
371371
Some (ExtractedType (TinlineRecord {env; fields}))
372372
| _ -> None
373373

374+
let findTypeOfPolyvariantArg constructors ~constructorName ~payloadNum =
375+
match
376+
constructors
377+
|> List.find_opt (fun (c : polyVariantConstructor) ->
378+
c.name = constructorName)
379+
with
380+
| Some {args} -> (
381+
match List.nth_opt args payloadNum with
382+
| None -> None
383+
| Some typ -> Some typ)
384+
| None -> None
385+
374386
let rec resolveNestedPatternPath (typ : innerType) ~env ~full ~nested =
375387
let t =
376388
match typ with
@@ -401,6 +413,14 @@ let rec resolveNestedPatternPath (typ : innerType) ~env ~full ~nested =
401413
with
402414
| Some typ -> Some (typ, env)
403415
| None -> None)
416+
| ( NPolyvariantPayload {constructorName; itemNum},
417+
Tpolyvariant {env; constructors} ) -> (
418+
match
419+
constructors
420+
|> findTypeOfPolyvariantArg ~constructorName ~payloadNum:itemNum
421+
with
422+
| Some typ -> Some (TypeExpr typ, env)
423+
| None -> None)
404424
| _ -> None))
405425
| patternPath :: nested -> (
406426
match t with
@@ -434,6 +454,15 @@ let rec resolveNestedPatternPath (typ : innerType) ~env ~full ~nested =
434454
with
435455
| Some typ -> typ |> resolveNestedPatternPath ~env ~full ~nested
436456
| None -> None)
457+
| ( NPolyvariantPayload {constructorName; itemNum},
458+
Tpolyvariant {env; constructors} ) -> (
459+
match
460+
constructors
461+
|> findTypeOfPolyvariantArg ~constructorName ~payloadNum:itemNum
462+
with
463+
| Some typ ->
464+
TypeExpr typ |> resolveNestedPatternPath ~env ~full ~nested
465+
| None -> None)
437466
| _ -> None))
438467

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

analysis/tests/src/CompletionInferValues.res

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ module Div = {
5959
// ^com
6060

6161
type someVariant = One | Two | Three(int, string)
62+
type somePolyVariant = [#one | #two | #three(int, string)]
6263
type someNestedRecord = {someRecord: someRecord}
6364

6465
type someRecordWithNestedStuff = {
@@ -69,7 +70,7 @@ type someRecordWithNestedStuff = {
6970
someStuff: bool,
7071
}
7172

72-
type otherNestedRecord = {someRecord: someRecord, someTuple: (someVariant, int)}
73+
type otherNestedRecord = {someRecord: someRecord, someTuple: (someVariant, int, somePolyVariant)}
7374

7475
// Destructure record
7576
// let x: someRecordWithNestedStuff = Obj.magic(); let {srecord} = x; srecord.
@@ -92,16 +93,21 @@ type otherNestedRecord = {someRecord: someRecord, someTuple: (someVariant, int)}
9293
// ^com
9394

9495
// Follow tuples
95-
// let x: otherNestedRecord = Obj.magic(); let {someTuple} = x; let (_, someInt) = someTuple; someInt->toS
96-
// ^com
96+
// let x: otherNestedRecord = Obj.magic(); let {someTuple} = x; let (_, someInt, _) = someTuple; someInt->toS
97+
// ^com
9798

9899
// Same as above, but follow in switch case
99-
// let x: otherNestedRecord; switch x { | {someTuple} => let (_, someInt) = someTuple; someInt->toS }
100-
// ^com
100+
// let x: otherNestedRecord; switch x { | {someTuple} => let (_, someInt, _) = someTuple; someInt->toS }
101+
// ^com
101102

102103
// Follow variant payloads
103-
// let x: otherNestedRecord; switch x { | {someTuple:(Three(_, str), _)} => str->slic }
104-
// ^com
104+
// let x: otherNestedRecord; switch x { | {someTuple:(Three(_, str), _, _)} => str->slic }
105+
// ^com
106+
107+
// Follow polyvariant payloads
108+
// let x: otherNestedRecord; switch x { | {someTuple:(_, _, #three(_, str))} => str->slic }
109+
// ^com
110+
105111
let fnWithRecordCallback = (cb: someRecord => unit) => {
106112
let _ = cb
107113
}

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

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,9 @@ Completable: Cpath Value[x].""
220220
"documentation": null
221221
}]
222222

223-
Complete src/CompletionInferValues.res 74:78
224-
posCursor:[74:78] posNoWhite:[74:77] Found expr:[74:70->74:78]
225-
Pexp_field [74:70->74:77] _:[104:0->74:78]
223+
Complete src/CompletionInferValues.res 75:78
224+
posCursor:[75:78] posNoWhite:[75:77] Found expr:[75:70->75:78]
225+
Pexp_field [75:70->75:77] _:[110:0->75:78]
226226
Completable: Cpath Value[srecord].""
227227
[{
228228
"label": "name",
@@ -238,9 +238,9 @@ Completable: Cpath Value[srecord].""
238238
"documentation": null
239239
}]
240240

241-
Complete src/CompletionInferValues.res 78:86
242-
posCursor:[78:86] posNoWhite:[78:85] Found expr:[78:78->78:86]
243-
Pexp_field [78:78->78:85] _:[104:0->78:86]
241+
Complete src/CompletionInferValues.res 79:86
242+
posCursor:[79:86] posNoWhite:[79:85] Found expr:[79:78->79:86]
243+
Pexp_field [79:78->79:85] _:[110:0->79:86]
244244
Completable: Cpath Value[aliased].""
245245
[{
246246
"label": "someRecord",
@@ -250,9 +250,9 @@ Completable: Cpath Value[aliased].""
250250
"documentation": null
251251
}]
252252

253-
Complete src/CompletionInferValues.res 82:103
254-
posCursor:[82:103] posNoWhite:[82:102] Found expr:[82:92->82:103]
255-
Pexp_field [82:92->82:102] _:[104:0->82:103]
253+
Complete src/CompletionInferValues.res 83:103
254+
posCursor:[83:103] posNoWhite:[83:102] Found expr:[83:92->83:103]
255+
Pexp_field [83:92->83:102] _:[110:0->83:103]
256256
Completable: Cpath Value[someRecord].""
257257
[{
258258
"label": "name",
@@ -268,8 +268,8 @@ Completable: Cpath Value[someRecord].""
268268
"documentation": null
269269
}]
270270

271-
Complete src/CompletionInferValues.res 86:81
272-
posCursor:[86:81] posNoWhite:[86:80] Found expr:[86:69->86:81]
271+
Complete src/CompletionInferValues.res 87:81
272+
posCursor:[87:81] posNoWhite:[87:80] Found expr:[87:69->87:81]
273273
Completable: Cpath Value[things]->slic
274274
[{
275275
"label": "Js.String2.sliceToEnd",
@@ -285,8 +285,8 @@ Completable: Cpath Value[things]->slic
285285
"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"}
286286
}]
287287

288-
Complete src/CompletionInferValues.res 90:82
289-
posCursor:[90:82] posNoWhite:[90:81] Found expr:[90:70->90:82]
288+
Complete src/CompletionInferValues.res 91:82
289+
posCursor:[91:82] posNoWhite:[91:81] Found expr:[91:70->91:82]
290290
Completable: Cpath Value[someInt]->toS
291291
[{
292292
"label": "Belt.Int.toString",
@@ -296,8 +296,8 @@ Completable: Cpath Value[someInt]->toS
296296
"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"}
297297
}]
298298

299-
Complete src/CompletionInferValues.res 94:106
300-
posCursor:[94:106] posNoWhite:[94:105] Found expr:[94:94->94:106]
299+
Complete src/CompletionInferValues.res 95:109
300+
posCursor:[95:109] posNoWhite:[95:108] Found expr:[95:97->95:109]
301301
Completable: Cpath Value[someInt]->toS
302302
[{
303303
"label": "Belt.Int.toString",
@@ -307,9 +307,9 @@ Completable: Cpath Value[someInt]->toS
307307
"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"}
308308
}]
309309

310-
Complete src/CompletionInferValues.res 98:99
311-
posCursor:[98:99] posNoWhite:[98:98] Found expr:[98:57->98:99]
312-
posCursor:[98:99] posNoWhite:[98:98] Found expr:[98:87->98:99]
310+
Complete src/CompletionInferValues.res 99:102
311+
posCursor:[99:102] posNoWhite:[99:101] Found expr:[99:57->99:102]
312+
posCursor:[99:102] posNoWhite:[99:101] Found expr:[99:90->99:102]
313313
Completable: Cpath Value[someInt]->toS
314314
[{
315315
"label": "Belt.Int.toString",
@@ -319,8 +319,8 @@ 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 102:85
323-
posCursor:[102:85] posNoWhite:[102:84] Found expr:[102:76->102:85]
322+
Complete src/CompletionInferValues.res 103:88
323+
posCursor:[103:88] posNoWhite:[103:87] Found expr:[103:79->103:88]
324324
Completable: Cpath Value[str]->slic
325325
[{
326326
"label": "Js.String2.sliceToEnd",
@@ -336,12 +336,29 @@ Completable: Cpath Value[str]->slic
336336
"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"}
337337
}]
338338

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]
339+
Complete src/CompletionInferValues.res 107:89
340+
posCursor:[107:89] posNoWhite:[107:88] Found expr:[107:80->107:89]
341+
Completable: Cpath Value[str]->slic
342+
[{
343+
"label": "Js.String2.sliceToEnd",
344+
"kind": 12,
345+
"tags": [],
346+
"detail": "(t, ~from: int) => t",
347+
"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"}
348+
}, {
349+
"label": "Js.String2.slice",
350+
"kind": 12,
351+
"tags": [],
352+
"detail": "(t, ~from: int, ~to_: int) => t",
353+
"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"}
354+
}]
355+
356+
Complete src/CompletionInferValues.res 115:26
357+
posCursor:[115:26] posNoWhite:[115:25] Found expr:[115:3->115:37]
358+
Pexp_apply ...[115:3->115:23] (...[115:24->115:36])
359+
posCursor:[115:26] posNoWhite:[115:25] Found expr:[115:24->115:36]
360+
posCursor:[115:26] posNoWhite:[115:25] Found pattern:[115:25->115:27]
361+
posCursor:[115:26] posNoWhite:[115:25] Found pattern:[115:25->115:27]
345362
Completable: Cpattern CArgument CArgument Value[fnWithRecordCallback]($0)($0)->recordBody
346363
[{
347364
"label": "name",

0 commit comments

Comments
 (0)