@@ -544,6 +544,24 @@ let getCompletionsForPath ~debug ~package ~opens ~full ~pos ~exact ~scope
544
544
findAllCompletions ~env ~prefix ~exact ~names Used ~completion Context
545
545
| None -> [] )
546
546
547
+ let rec digToRecordFieldsForCompletion ~debug ~package ~opens ~full ~pos ~env
548
+ ~scope path =
549
+ match
550
+ path
551
+ |> getCompletionsForPath ~debug ~completion Context:Type ~exact: true ~package
552
+ ~opens ~full ~pos ~env ~scope
553
+ with
554
+ | {kind = Type {kind = Abstract (Some (p , _ ))} } :: _ ->
555
+ (* This case happens when what we're looking for is a type alias.
556
+ This is the case in newer rescript-react versions where
557
+ ReactDOM.domProps is an alias for JsxEvent.t. *)
558
+ let pathRev = p |> Utils. expandPath in
559
+ pathRev |> List. rev
560
+ |> digToRecordFieldsForCompletion ~debug ~package ~opens ~full ~pos ~env
561
+ ~scope
562
+ | {kind = Type {kind = Record fields } } :: _ -> Some fields
563
+ | _ -> None
564
+
547
565
let mkItem ~name ~kind ~detail ~deprecated ~docstring =
548
566
let docContent =
549
567
(match deprecated with
@@ -567,7 +585,7 @@ let mkItem ~name ~kind ~detail ~deprecated ~docstring =
567
585
detail;
568
586
documentation =
569
587
(if docContent = " " then None
570
- else Some {kind = " markdown" ; value = docContent});
588
+ else Some {kind = " markdown" ; value = docContent});
571
589
sortText = None ;
572
590
insertText = None ;
573
591
insertTextFormat = None ;
@@ -1039,25 +1057,16 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
1039
1057
in
1040
1058
let targetLabel =
1041
1059
if lowercaseComponent then
1042
- let rec digToTypeForCompletion path =
1043
- match
1044
- path
1045
- |> getCompletionsForPath ~debug ~completion Context:Type ~exact: true
1046
- ~package ~opens ~full ~pos ~env ~scope
1047
- with
1048
- | {kind = Type {kind = Abstract (Some (p , _ ))} } :: _ ->
1049
- (* This case happens when what we're looking for is a type alias.
1050
- This is the case in newer rescript-react versions where
1051
- ReactDOM.domProps is an alias for JsxEvent.t. *)
1052
- let pathRev = p |> Utils. expandPath in
1053
- pathRev |> List. rev |> digToTypeForCompletion
1054
- | {kind = Type {kind = Record fields } } :: _ -> (
1055
- match fields |> List. find_opt (fun f -> f.fname.txt = propName) with
1056
- | None -> None
1057
- | Some f -> Some (f.fname.txt, f.typ, env))
1058
- | _ -> None
1059
- in
1060
- [" ReactDOM" ; " domProps" ] |> digToTypeForCompletion
1060
+ match
1061
+ [" ReactDOM" ; " domProps" ]
1062
+ |> digToRecordFieldsForCompletion ~debug ~package ~opens ~full ~pos
1063
+ ~env ~scope
1064
+ with
1065
+ | None -> None
1066
+ | Some fields -> (
1067
+ match fields |> List. find_opt (fun f -> f.fname.txt = propName) with
1068
+ | None -> None
1069
+ | Some f -> Some (f.fname.txt, f.typ, env))
1061
1070
else
1062
1071
CompletionJsx. getJsxLabels ~component Path:pathToComponent
1063
1072
~find TypeOfValue ~package
@@ -1537,20 +1546,47 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
1537
1546
contextPath
1538
1547
|> getCompletionsForContextPath ~debug ~full ~opens ~raw Opens ~pos ~env
1539
1548
~exact: forHover ~scope
1540
- | Cjsx ([id ], prefix , identsSeen ) when String. uncapitalize_ascii id = id ->
1549
+ | Cjsx ([id ], prefix , identsSeen ) when String. uncapitalize_ascii id = id -> (
1541
1550
(* Lowercase JSX tag means builtin *)
1542
1551
let mkLabel (name , typString ) =
1543
1552
Completion. create name ~kind: (Label typString) ~env
1544
1553
in
1545
1554
let keyLabels =
1546
1555
if Utils. startsWith " key" prefix then [mkLabel (" key" , " string" )] else []
1547
1556
in
1548
- (CompletionJsx. domLabels
1549
- |> List. filter (fun (name , _t ) ->
1550
- Utils. startsWith name prefix
1551
- && (forHover || not (List. mem name identsSeen)))
1552
- |> List. map mkLabel)
1553
- @ keyLabels
1557
+ (* We always try to look up completion from the actual domProps type first.
1558
+ This works in JSXv4. For JSXv3, we have a backup hardcoded list of dom
1559
+ labels we can use for completion. *)
1560
+ let fromDomProps =
1561
+ match
1562
+ [" ReactDOM" ; " domProps" ]
1563
+ |> digToRecordFieldsForCompletion ~debug ~package ~opens ~full ~pos ~env
1564
+ ~scope
1565
+ with
1566
+ | None -> None
1567
+ | Some fields ->
1568
+ Some
1569
+ (fields
1570
+ |> List. filter_map (fun (f : field ) ->
1571
+ if
1572
+ Utils. startsWith f.fname.txt prefix
1573
+ && (forHover || not (List. mem f.fname.txt identsSeen))
1574
+ then
1575
+ Some
1576
+ ( f.fname.txt,
1577
+ Shared. typeToString (Utils. unwrapIfOption f.typ) )
1578
+ else None )
1579
+ |> List. map mkLabel)
1580
+ in
1581
+ match fromDomProps with
1582
+ | Some domProps -> domProps
1583
+ | None ->
1584
+ (CompletionJsx. domLabels
1585
+ |> List. filter (fun (name , _t ) ->
1586
+ Utils. startsWith name prefix
1587
+ && (forHover || not (List. mem name identsSeen)))
1588
+ |> List. map mkLabel)
1589
+ @ keyLabels)
1554
1590
| Cjsx (componentPath , prefix , identsSeen ) ->
1555
1591
let labels =
1556
1592
CompletionJsx. getJsxLabels ~component Path ~find TypeOfValue ~package
0 commit comments