Skip to content

Commit 72a522c

Browse files
committed
make sure completions work across files
1 parent e3d1470 commit 72a522c

File tree

6 files changed

+233
-13
lines changed

6 files changed

+233
-13
lines changed

analysis/src/CompletionBackEnd.ml

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,12 @@ let getCompletionsForPath ~debug ~opens ~full ~pos ~exact ~scope
636636
| None -> [])
637637

638638
(** Completions intended for piping, from a completion path. *)
639-
let completionsForPipeFromCompletionPath ~opens ~pos ~scope ~debug ~prefix ~env
640-
~rawOpens ~full completionPath =
639+
let completionsForPipeFromCompletionPath ~envCompletionIsMadeFrom ~opens ~pos
640+
~scope ~debug ~prefix ~env ~rawOpens ~full completionPath =
641+
let completionPath =
642+
TypeUtils.removeCurrentModuleIfNeeded ~envCompletionIsMadeFrom
643+
completionPath
644+
in
641645
let completionPathMinusOpens =
642646
TypeUtils.removeOpensFromCompletionPath ~rawOpens ~package:full.package
643647
completionPath
@@ -814,6 +818,7 @@ and completionsGetTypeEnv2 ~debug (completions : Completion.t list) ~full ~opens
814818

815819
and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
816820
~scope ?(mode = Regular) contextPath =
821+
let envCompletionIsMadeFrom = env in
817822
if debug then
818823
Printf.printf "ContextPath %s\n"
819824
(Completable.contextPathToString contextPath);
@@ -1036,25 +1041,34 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
10361041
in
10371042
match extracted with
10381043
| None -> []
1039-
| Some (env, fields, recordAsString, path, attributes) ->
1044+
| Some (envFromExtracted, fields, recordAsString, path, attributes) ->
10401045
let pipeCompletion =
10411046
match
10421047
(path, ProcessAttributes.findEditorCompleteFromAttribute attributes)
10431048
with
10441049
| Some path, _ when Path.last path = "t" ->
1050+
if Debug.verbose () then Printf.printf "CPField--> type is type t\n";
10451051
Some
10461052
( path,
10471053
path |> SharedTypes.pathIdentToString |> String.split_on_char '.'
10481054
|> List.rev |> List.tl )
1049-
| Some path, Some modulePath -> Some (path, modulePath)
1055+
| Some path, Some modulePath ->
1056+
if Debug.verbose () then
1057+
Printf.printf
1058+
"CPField--> type has completeFrom config for module %s, hd: %s, \
1059+
env moduleName: %s\n"
1060+
(modulePath |> SharedTypes.pathToString)
1061+
(List.hd modulePath) env.file.moduleName;
1062+
Some (path, modulePath)
10501063
| _ -> None
10511064
in
10521065
let pipeCompletionsForModule =
10531066
match pipeCompletion with
10541067
| Some (path, completionPath) ->
10551068
completionsForPipeFromCompletionPath ~opens ~pos ~scope ~debug
1056-
~prefix:fieldName ~env ~rawOpens ~full completionPath
1057-
|> TypeUtils.filterPipeableFunctions ~env ~full ~path
1069+
~prefix:fieldName ~envCompletionIsMadeFrom:env ~env:envFromExtracted
1070+
~rawOpens ~full completionPath
1071+
|> TypeUtils.filterPipeableFunctions ~env:envFromExtracted ~full ~path
10581072
~replaceRange:fieldNameLoc
10591073
| None -> []
10601074
in
@@ -1063,7 +1077,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
10631077
|> Utils.filterMap (fun field ->
10641078
if Utils.checkName field.fname.txt ~prefix:fieldName ~exact then
10651079
Some
1066-
(Completion.create field.fname.txt ~env
1080+
(Completion.create field.fname.txt ~env:envFromExtracted
10671081
?deprecated:field.deprecated ~docstring:field.docstring
10681082
~kind:(Completion.Field (field, recordAsString)))
10691083
else None)))
@@ -1108,7 +1122,8 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
11081122
| Some (typ, envFromCompletionItem) -> (
11091123
(* Extract any module to draw extra completions from for the identified type. *)
11101124
let extraModuleToCompleteFrom =
1111-
TypeUtils.getExtraModuleToCompleteFromForType typ ~env ~full
1125+
TypeUtils.getExtraModuleToCompleteFromForType typ
1126+
~env:envFromCompletionItem ~full
11121127
in
11131128
let env, typ =
11141129
typ
@@ -1164,14 +1179,20 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
11641179
match extraModuleToCompleteFrom with
11651180
| None -> []
11661181
| Some completionPath ->
1167-
completionsForPipeFromCompletionPath ~opens ~pos ~scope ~debug
1168-
~prefix:funNamePrefix ~env ~rawOpens ~full completionPath
1182+
if Debug.verbose () then
1183+
Printf.printf
1184+
"[ctx_path]--> CPPipe --> Found extra module to complete from: %s\n"
1185+
(completionPath |> SharedTypes.pathToString);
1186+
completionsForPipeFromCompletionPath ~envCompletionIsMadeFrom ~opens
1187+
~pos ~scope ~debug ~prefix:funNamePrefix ~env ~rawOpens ~full
1188+
completionPath
11691189
in
11701190
match completionPath with
11711191
| Some completionPath -> (
11721192
let completionsFromMainFn =
1173-
completionsForPipeFromCompletionPath ~opens ~pos ~scope ~debug
1174-
~prefix:funNamePrefix ~env ~rawOpens ~full completionPath
1193+
completionsForPipeFromCompletionPath ~envCompletionIsMadeFrom ~opens
1194+
~pos ~scope ~debug ~prefix:funNamePrefix ~env ~rawOpens ~full
1195+
completionPath
11751196
in
11761197
let completions = completionsFromMainFn @ completionsFromExtraModule in
11771198
(* We add React element functions to the completion if we're in a JSX context *)

analysis/src/TypeUtils.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,3 +1196,10 @@ let filterPipeableFunctions ~env ~full ~path ~replaceRange completions =
11961196
| Value t when fnTakesType ~env ~full ~path t ->
11971197
transformCompletionToPipeCompletion ~env ~replaceRange completion
11981198
| _ -> None)
1199+
1200+
let removeCurrentModuleIfNeeded ~envCompletionIsMadeFrom completionPath =
1201+
if
1202+
List.length completionPath > 0
1203+
&& List.hd completionPath = envCompletionIsMadeFrom.QueryEnv.file.moduleName
1204+
then List.tl completionPath
1205+
else completionPath

analysis/tests/src/CompletionFromModule.res

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ let n = {SomeModule.name: "hello"}
1111
// n.
1212
// ^com
1313

14-
@editor.completeFrom(SomeOtherModule)
14+
@editor.completeFrom(CompletionFromModule.SomeOtherModule)
1515
type typeOutsideModule = {nname: string}
1616

1717
module SomeOtherModule = {
@@ -38,3 +38,7 @@ let nnn: typeOutsideModule = {nname: "hello"}
3838

3939
// nnn->
4040
// ^com
41+
42+
open SomeOtherModule
43+
// nnn->
44+
// ^com
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Used to check completions across files
2+
// WRONG! Missing pipe functions (because of type t)
3+
// CompletionFromModule.n.
4+
// ^com
5+
6+
// CompletionFromModule.nn.
7+
// ^com
8+
9+
// CompletionFromModule.nnn->
10+
// ^com
11+
12+
open CompletionFromModule.SomeOtherModule
13+
// CompletionFromModule.nnn->
14+
// ^com

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,42 @@ Path SomeOtherModule.
120120
"documentation": null
121121
}]
122122

123+
Complete src/CompletionFromModule.res 42:8
124+
posCursor:[42:8] posNoWhite:[42:7] Found expr:[42:3->0:-1]
125+
Completable: Cpath Value[nnn]->
126+
Raw opens: 1 SomeOtherModule.place holder
127+
Package opens Pervasives.JsxModules.place holder
128+
Resolved opens 2 pervasives CompletionFromModule.res
129+
ContextPath Value[nnn]->
130+
ContextPath Value[nnn]
131+
Path nnn
132+
CPPipe env:CompletionFromModule
133+
CPPipe type path:typeOutsideModule
134+
CPPipe pathFromEnv: found:true
135+
Path SomeOtherModule.
136+
[{
137+
"label": "getNName",
138+
"kind": 12,
139+
"tags": [],
140+
"detail": "t => string",
141+
"documentation": null
142+
}, {
143+
"label": "getNName3",
144+
"kind": 12,
145+
"tags": [],
146+
"detail": "irrelevantType => string",
147+
"documentation": null
148+
}, {
149+
"label": "thisShouldNotBeCompletedFor",
150+
"kind": 12,
151+
"tags": [],
152+
"detail": "unit => string",
153+
"documentation": null
154+
}, {
155+
"label": "getNName2",
156+
"kind": 12,
157+
"tags": [],
158+
"detail": "typeOutsideModule => string",
159+
"documentation": null
160+
}]
161+
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
Complete src/CompletionFromModule2.res 2:26
2+
posCursor:[2:26] posNoWhite:[2:25] Found expr:[2:3->2:26]
3+
Pexp_field [2:3->2:25] _:[11:0->2:26]
4+
Completable: Cpath Value[CompletionFromModule, n].""
5+
Package opens Pervasives.JsxModules.place holder
6+
Resolved opens 1 pervasives
7+
ContextPath Value[CompletionFromModule, n].""
8+
ContextPath Value[CompletionFromModule, n]
9+
Path CompletionFromModule.n
10+
Path SomeModule.
11+
[{
12+
"label": "name",
13+
"kind": 5,
14+
"tags": [],
15+
"detail": "string",
16+
"documentation": {"kind": "markdown", "value": "```rescript\nname: string\n```\n\n```rescript\ntype t = {name: string}\n```"}
17+
}]
18+
19+
Complete src/CompletionFromModule2.res 5:27
20+
posCursor:[5:27] posNoWhite:[5:26] Found expr:[5:3->5:27]
21+
Pexp_field [5:3->5:26] _:[11:0->5:27]
22+
Completable: Cpath Value[CompletionFromModule, nn].""
23+
Package opens Pervasives.JsxModules.place holder
24+
Resolved opens 1 pervasives
25+
ContextPath Value[CompletionFromModule, nn].""
26+
ContextPath Value[CompletionFromModule, nn]
27+
Path CompletionFromModule.nn
28+
Path CompletionFromModule.SomeOtherModule.
29+
[{
30+
"label": "->CompletionFromModule.SomeOtherModule.getNName",
31+
"kind": 12,
32+
"tags": [],
33+
"detail": "t => string",
34+
"documentation": null,
35+
"sortText": "getNName",
36+
"textEdit": {
37+
"range": {"start": {"line": 5, "character": 26}, "end": {"line": 5, "character": 26}},
38+
"newText": "->CompletionFromModule.SomeOtherModule.getNName"
39+
}
40+
}, {
41+
"label": "->CompletionFromModule.SomeOtherModule.getNName2",
42+
"kind": 12,
43+
"tags": [],
44+
"detail": "typeOutsideModule => string",
45+
"documentation": null,
46+
"sortText": "getNName2",
47+
"textEdit": {
48+
"range": {"start": {"line": 5, "character": 26}, "end": {"line": 5, "character": 26}},
49+
"newText": "->CompletionFromModule.SomeOtherModule.getNName2"
50+
}
51+
}, {
52+
"label": "nname",
53+
"kind": 5,
54+
"tags": [],
55+
"detail": "string",
56+
"documentation": {"kind": "markdown", "value": "```rescript\nnname: string\n```\n\n```rescript\ntype typeOutsideModule = {nname: string}\n```"}
57+
}]
58+
59+
Complete src/CompletionFromModule2.res 8:29
60+
posCursor:[8:29] posNoWhite:[8:28] Found expr:[8:3->0:-1]
61+
Completable: Cpath Value[CompletionFromModule, nnn]->
62+
Package opens Pervasives.JsxModules.place holder
63+
Resolved opens 1 pervasives
64+
ContextPath Value[CompletionFromModule, nnn]->
65+
ContextPath Value[CompletionFromModule, nnn]
66+
Path CompletionFromModule.nnn
67+
CPPipe env:CompletionFromModule2 envFromCompletionItem:CompletionFromModule
68+
CPPipe type path:typeOutsideModule
69+
CPPipe pathFromEnv: found:true
70+
Path CompletionFromModule.SomeOtherModule.
71+
[{
72+
"label": "CompletionFromModule.SomeOtherModule.getNName",
73+
"kind": 12,
74+
"tags": [],
75+
"detail": "t => string",
76+
"documentation": null
77+
}, {
78+
"label": "CompletionFromModule.SomeOtherModule.getNName3",
79+
"kind": 12,
80+
"tags": [],
81+
"detail": "irrelevantType => string",
82+
"documentation": null
83+
}, {
84+
"label": "CompletionFromModule.SomeOtherModule.thisShouldNotBeCompletedFor",
85+
"kind": 12,
86+
"tags": [],
87+
"detail": "unit => string",
88+
"documentation": null
89+
}, {
90+
"label": "CompletionFromModule.SomeOtherModule.getNName2",
91+
"kind": 12,
92+
"tags": [],
93+
"detail": "typeOutsideModule => string",
94+
"documentation": null
95+
}]
96+
97+
Complete src/CompletionFromModule2.res 12:29
98+
posCursor:[12:29] posNoWhite:[12:28] Found expr:[12:3->0:-1]
99+
Completable: Cpath Value[CompletionFromModule, nnn]->
100+
Raw opens: 1 CompletionFromModule.SomeOtherModule.place holder
101+
Package opens Pervasives.JsxModules.place holder
102+
Resolved opens 2 pervasives CompletionFromModule.res
103+
ContextPath Value[CompletionFromModule, nnn]->
104+
ContextPath Value[CompletionFromModule, nnn]
105+
Path CompletionFromModule.nnn
106+
CPPipe env:CompletionFromModule2 envFromCompletionItem:CompletionFromModule
107+
CPPipe type path:typeOutsideModule
108+
CPPipe pathFromEnv: found:true
109+
Path CompletionFromModule.SomeOtherModule.
110+
[{
111+
"label": "getNName",
112+
"kind": 12,
113+
"tags": [],
114+
"detail": "t => string",
115+
"documentation": null
116+
}, {
117+
"label": "getNName3",
118+
"kind": 12,
119+
"tags": [],
120+
"detail": "irrelevantType => string",
121+
"documentation": null
122+
}, {
123+
"label": "thisShouldNotBeCompletedFor",
124+
"kind": 12,
125+
"tags": [],
126+
"detail": "unit => string",
127+
"documentation": null
128+
}, {
129+
"label": "getNName2",
130+
"kind": 12,
131+
"tags": [],
132+
"detail": "typeOutsideModule => string",
133+
"documentation": null
134+
}]
135+

0 commit comments

Comments
 (0)