@@ -548,6 +548,24 @@ let getCompletionsForPath ~debug ~package ~opens ~full ~pos ~exact ~scope
548548 findAllCompletions ~env ~prefix ~exact ~names Used ~completion Context
549549 | None -> [] )
550550
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+
551569let mkItem ~name ~kind ~detail ~deprecated ~docstring =
552570 let docContent =
553571 (match deprecated with
@@ -571,7 +589,7 @@ let mkItem ~name ~kind ~detail ~deprecated ~docstring =
571589 detail;
572590 documentation =
573591 (if docContent = " " then None
574- else Some {kind = " markdown" ; value = docContent});
592+ else Some {kind = " markdown" ; value = docContent});
575593 sortText = None ;
576594 insertText = None ;
577595 insertTextFormat = None ;
@@ -1043,25 +1061,16 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
10431061 in
10441062 let targetLabel =
10451063 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))
10651074 else
10661075 CompletionJsx. getJsxLabels ~component Path:pathToComponent
10671076 ~find TypeOfValue ~package
@@ -1541,20 +1550,49 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
15411550 contextPath
15421551 |> getCompletionsForContextPath ~debug ~full ~opens ~raw Opens ~pos ~env
15431552 ~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 -> (
15451554 (* Lowercase JSX tag means builtin *)
15461555 let mkLabel (name , typString ) =
15471556 Completion. create name ~kind: (Label typString) ~env
15481557 in
15491558 let keyLabels =
15501559 if Utils. startsWith " key" prefix then [mkLabel (" key" , " string" )] else []
15511560 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)
15581596 | Cjsx (componentPath , prefix , identsSeen ) ->
15591597 let labels =
15601598 CompletionJsx. getJsxLabels ~component Path ~find TypeOfValue ~package
0 commit comments