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