@@ -3,7 +3,18 @@ open SharedTypes
3
3
let showConstructor {Constructor. cname = {txt} ; args; res} =
4
4
txt
5
5
^ (match args with
6
- | Args [] | InlineRecord _ -> " "
6
+ | Args [] -> " "
7
+ | InlineRecord fields ->
8
+ " ({"
9
+ ^ (fields
10
+ |> List. map (fun (field : field ) ->
11
+ Printf. sprintf " %s%s: %s" field.fname.txt
12
+ (if field.optional then " ?" else " " )
13
+ (Shared. typeToString
14
+ (if field.optional then Utils. unwrapIfOption field.typ
15
+ else field.typ)))
16
+ |> String. concat " , " )
17
+ ^ " })"
7
18
| Args args ->
8
19
" ("
9
20
^ (args
@@ -686,41 +697,48 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
686
697
let package = full.package in
687
698
match contextPath with
688
699
| CPString ->
700
+ if Debug. verbose () then print_endline " [ctx_path]--> CPString" ;
689
701
[
690
702
Completion. create " dummy" ~env
691
703
~kind:
692
704
(Completion. Value
693
705
(Ctype. newconstr (Path. Pident (Ident. create " string" )) [] ));
694
706
]
695
707
| CPBool ->
708
+ if Debug. verbose () then print_endline " [ctx_path]--> CPBool" ;
696
709
[
697
710
Completion. create " dummy" ~env
698
711
~kind:
699
712
(Completion. Value
700
713
(Ctype. newconstr (Path. Pident (Ident. create " bool" )) [] ));
701
714
]
702
715
| CPInt ->
716
+ if Debug. verbose () then print_endline " [ctx_path]--> CPInt" ;
703
717
[
704
718
Completion. create " dummy" ~env
705
719
~kind:
706
720
(Completion. Value
707
721
(Ctype. newconstr (Path. Pident (Ident. create " int" )) [] ));
708
722
]
709
723
| CPFloat ->
724
+ if Debug. verbose () then print_endline " [ctx_path]--> CPFloat" ;
710
725
[
711
726
Completion. create " dummy" ~env
712
727
~kind:
713
728
(Completion. Value
714
729
(Ctype. newconstr (Path. Pident (Ident. create " float" )) [] ));
715
730
]
716
731
| CPArray None ->
732
+ if Debug. verbose () then print_endline " [ctx_path]--> CPArray (no payload)" ;
717
733
[
718
734
Completion. create " array" ~env
719
735
~kind:
720
736
(Completion. Value
721
737
(Ctype. newconstr (Path. Pident (Ident. create " array" )) [] ));
722
738
]
723
739
| CPArray (Some cp ) -> (
740
+ if Debug. verbose () then
741
+ print_endline " [ctx_path]--> CPArray (with payload)" ;
724
742
match mode with
725
743
| Regular -> (
726
744
match
@@ -746,6 +764,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
746
764
(Ctype. newconstr (Path. Pident (Ident. create " array" )) [] ));
747
765
])
748
766
| CPOption cp -> (
767
+ if Debug. verbose () then print_endline " [ctx_path]--> CPOption" ;
749
768
match
750
769
cp
751
770
|> getCompletionsForContextPath ~debug ~full ~opens ~raw Opens ~pos ~env
@@ -760,6 +779,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
760
779
(Completion. ExtractedType (Toption (env, ExtractedType typ), `Type ));
761
780
])
762
781
| CPAwait cp -> (
782
+ if Debug. verbose () then print_endline " [ctx_path]--> CPAwait" ;
763
783
match
764
784
cp
765
785
|> getCompletionsForContextPath ~debug ~full ~opens ~raw Opens ~pos ~env
@@ -770,10 +790,12 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
770
790
[Completion. create " dummy" ~env ~kind: (Completion. Value typ)]
771
791
| _ -> [] )
772
792
| CPId (path , completionContext ) ->
793
+ if Debug. verbose () then print_endline " [ctx_path]--> CPId" ;
773
794
path
774
795
|> getCompletionsForPath ~debug ~opens ~full ~pos ~exact ~completion Context
775
796
~env ~scope
776
797
| CPApply (cp , labels ) -> (
798
+ if Debug. verbose () then print_endline " [ctx_path]--> CPApply" ;
777
799
match
778
800
cp
779
801
|> getCompletionsForContextPath ~debug ~full ~opens ~raw Opens ~pos ~env
@@ -815,11 +837,13 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
815
837
| _ -> [] )
816
838
| _ -> [])
817
839
| CPField (CPId (path , Module), fieldName ) ->
840
+ if Debug. verbose () then print_endline " [ctx_path]--> CPField: M.field" ;
818
841
(* M.field *)
819
842
path @ [fieldName]
820
843
|> getCompletionsForPath ~debug ~opens ~full ~pos ~exact
821
844
~completion Context:Field ~env ~scope
822
845
| CPField (cp , fieldName ) -> (
846
+ if Debug. verbose () then print_endline " [ctx_path]--> CPField" ;
823
847
let completionsForCtxPath =
824
848
cp
825
849
|> getCompletionsForContextPath ~debug ~full ~opens ~raw Opens ~pos ~env
@@ -858,6 +882,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
858
882
else None ))
859
883
| CPObj (cp , label ) -> (
860
884
(* TODO: Also needs to support ExtractedType *)
885
+ if Debug. verbose () then print_endline " [ctx_path]--> CPObj" ;
861
886
match
862
887
cp
863
888
|> getCompletionsForContextPath ~debug ~full ~opens ~raw Opens ~pos ~env
@@ -885,6 +910,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
885
910
| None -> [] )
886
911
| None -> [] )
887
912
| CPPipe {contextPath = cp ; id = funNamePrefix ; lhsLoc; inJsx} -> (
913
+ if Debug. verbose () then print_endline " [ctx_path]--> CPPipe" ;
888
914
match
889
915
cp
890
916
|> getCompletionsForContextPath ~debug ~full ~opens ~raw Opens ~pos ~env
@@ -997,6 +1023,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
997
1023
| _ -> completions)
998
1024
| None -> [] ))
999
1025
| CTuple ctxPaths ->
1026
+ if Debug. verbose () then print_endline " [ctx_path]--> CTuple" ;
1000
1027
(* Turn a list of context paths into a list of type expressions. *)
1001
1028
let typeExrps =
1002
1029
ctxPaths
@@ -1016,6 +1043,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
1016
1043
]
1017
1044
else []
1018
1045
| CJsxPropValue {pathToComponent; propName} -> (
1046
+ if Debug. verbose () then print_endline " [ctx_path]--> CJsxPropValue" ;
1019
1047
let findTypeOfValue path =
1020
1048
path
1021
1049
|> getCompletionsForPath ~debug ~completion Context:Value ~exact: true
@@ -1027,6 +1055,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
1027
1055
| [elName] when Char. lowercase_ascii elName.[0 ] = elName.[0 ] -> true
1028
1056
| _ -> false
1029
1057
in
1058
+ (* TODO(env-stuff) Does this need to potentially be instantiated with type args too? *)
1030
1059
let targetLabel =
1031
1060
if lowercaseComponent then
1032
1061
let rec digToTypeForCompletion path =
@@ -1061,6 +1090,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
1061
1090
~kind: (Completion. Value (Utils. unwrapIfOption typ));
1062
1091
])
1063
1092
| CArgument {functionContextPath; argumentLabel} -> (
1093
+ if Debug. verbose () then print_endline " [ctx_path]--> CArgument" ;
1064
1094
if Debug. verbose () then
1065
1095
Printf. printf " --> function argument: %s\n "
1066
1096
(match argumentLabel with
@@ -1113,6 +1143,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
1113
1143
(if expandOption then Utils. unwrapIfOption typ else typ));
1114
1144
])
1115
1145
| CPatternPath {rootCtxPath; nested} -> (
1146
+ if Debug. verbose () then print_endline " [ctx_path]--> CPatternPath" ;
1116
1147
(* TODO(env-stuff) Get rid of innerType etc *)
1117
1148
match
1118
1149
rootCtxPath
@@ -1127,6 +1158,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
1127
1158
| None -> [] )
1128
1159
| None -> [] )
1129
1160
| CTypeAtPos loc -> (
1161
+ if Debug. verbose () then print_endline " [ctx_path]--> CTypeAtPos" ;
1130
1162
match
1131
1163
References. getLocItem ~full ~pos: (Pos. ofLexing loc.loc_start) ~debug
1132
1164
with
@@ -1861,6 +1893,22 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
1861
1893
fallbackOrEmpty ~items () )
1862
1894
| None -> fallbackOrEmpty () )
1863
1895
| Cexpression {contextPath; prefix; nested} -> (
1896
+ let isAmbigiousRecordBodyOrJsxWrap =
1897
+ match (contextPath, nested) with
1898
+ | CJsxPropValue _ , [NRecordBody _] -> true
1899
+ | _ -> false
1900
+ in
1901
+ if Debug. verbose () then
1902
+ (* This happens in this scenario: `<SomeComponent someProp={<com>}`
1903
+ Here, we don't know whether `{}` is just wraps for the type of
1904
+ `someProp`, or if it's a record body where we want to complete
1905
+ for the fields in the record. We need to look up what the type is
1906
+ first before deciding what completions to show. So we do that here.*)
1907
+ if isAmbigiousRecordBodyOrJsxWrap then
1908
+ print_endline
1909
+ " [process_completable]--> Cexpression special case: JSX prop value \
1910
+ that might be record body or JSX wrap"
1911
+ else print_endline " [process_completable]--> Cexpression" ;
1864
1912
(* Completions for local things like variables in scope, modules in the
1865
1913
project, etc. We only add completions when there's a prefix of some sort
1866
1914
we can filter on, since we know we're in some sort of context, and
@@ -1879,17 +1927,32 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
1879
1927
with
1880
1928
| None ->
1881
1929
if Debug. verbose () then
1882
- print_endline " --> could not get completions for context path" ;
1930
+ print_endline
1931
+ " [process_completable]--> could not get completions for context path" ;
1883
1932
regularCompletions
1884
1933
| Some (typ , env ) -> (
1885
1934
match typ |> TypeUtils. resolveNested ~env ~full ~nested with
1886
1935
| None ->
1887
1936
if Debug. verbose () then
1888
- print_endline " --> could not resolve nested expression path" ;
1889
- regularCompletions
1937
+ print_endline
1938
+ " [process_completable]--> could not resolve nested expression path" ;
1939
+ if isAmbigiousRecordBodyOrJsxWrap then (
1940
+ if Debug. verbose () then
1941
+ print_endline
1942
+ " [process_completable]--> case is ambigious Jsx prop vs record \
1943
+ body case, complete also for the JSX prop value directly" ;
1944
+ let itemsForRawJsxPropValue =
1945
+ typ
1946
+ |> completeTypedValue ~raw Opens ~mode: Expression ~full ~prefix
1947
+ ~completion Context:None
1948
+ in
1949
+ itemsForRawJsxPropValue @ regularCompletions)
1950
+ else regularCompletions
1890
1951
| Some (typ , _env , completionContext , typeArgContext ) -> (
1891
1952
if Debug. verbose () then
1892
- print_endline " --> found type in nested expression completion" ;
1953
+ print_endline
1954
+ " [process_completable]--> found type in nested expression \
1955
+ completion" ;
1893
1956
(* Wrap the insert text in braces when we're completing the root of a
1894
1957
JSX prop value. *)
1895
1958
let wrapInsertTextInBraces =
0 commit comments