Skip to content

Commit 187bb06

Browse files
committed
Merge branch 'master' into move-tools-to-ocaml
2 parents bff2928 + f41521e commit 187bb06

15 files changed

+192
-20
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616

1717
- Move `rescript-tools` to OCaml code and make `analysis` an library. https://github.com/rescript-lang/rescript-vscode/pull/855
1818

19+
## 1.32.0
20+
21+
#### :bug: Bug Fix
22+
23+
- Fix so that you don't need a leading `#` to complete for polyvariant constructors. https://github.com/rescript-lang/rescript-vscode/pull/874
24+
- Print keyword polyvariant constructors with quotes when doing completions. https://github.com/rescript-lang/rescript-vscode/pull/877
25+
1926
## 1.30.0
2027

2128
#### :rocket: New Feature

analysis/src/CompletionBackEnd.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1237,7 +1237,8 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode
12371237
(PolyvariantConstructor
12381238
(constructor, typeExpr |> Shared.typeToString))
12391239
~env ())
1240-
|> filterItems ~prefix
1240+
|> filterItems
1241+
~prefix:(if Utils.startsWith prefix "#" then prefix else "#" ^ prefix)
12411242
| Toption (env, t) ->
12421243
let innerType =
12431244
match t with

analysis/src/CompletionFrontEnd.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,14 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor
249249
Some text.[offsetNoWhite]
250250
else None
251251
in
252+
let charAtCursor =
253+
if offset < String.length text then text.[offset] else '\n'
254+
in
252255
let posBeforeCursor = Pos.posBeforeCursor posCursor in
253256
let charBeforeCursor, blankAfterCursor =
254257
match Pos.positionToOffset text posCursor with
255258
| Some offset when offset > 0 -> (
256259
let charBeforeCursor = text.[offset - 1] in
257-
let charAtCursor =
258-
if offset < String.length text then text.[offset] else '\n'
259-
in
260260
match charAtCursor with
261261
| ' ' | '\t' | '\r' | '\n' ->
262262
(Some charBeforeCursor, Some charBeforeCursor)
@@ -918,7 +918,7 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor
918918
CompletionJsx.findJsxPropsCompletable ~jsxProps
919919
~endPos:(Loc.end_ expr.pexp_loc) ~posBeforeCursor
920920
~posAfterCompName:(Loc.end_ compName.loc)
921-
~firstCharBeforeCursorNoWhite
921+
~firstCharBeforeCursorNoWhite ~charAtCursor
922922
in
923923
if jsxCompletable <> None then setResultOpt jsxCompletable
924924
else if compName.loc |> Loc.hasPos ~pos:posBeforeCursor then

analysis/src/CompletionJsx.ml

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -802,12 +802,17 @@ type jsxProps = {
802802
}
803803

804804
let findJsxPropsCompletable ~jsxProps ~endPos ~posBeforeCursor
805-
~firstCharBeforeCursorNoWhite ~posAfterCompName =
805+
~firstCharBeforeCursorNoWhite ~charAtCursor ~posAfterCompName =
806806
let allLabels =
807807
List.fold_right
808808
(fun prop allLabels -> prop.name :: allLabels)
809809
jsxProps.props []
810810
in
811+
let beforeChildrenStart =
812+
match jsxProps.childrenStart with
813+
| Some childrenPos -> posBeforeCursor < childrenPos
814+
| None -> posBeforeCursor <= endPos
815+
in
811816
let rec loop props =
812817
match props with
813818
| prop :: rest ->
@@ -860,13 +865,26 @@ let findJsxPropsCompletable ~jsxProps ~endPos ~posBeforeCursor
860865
nested = [];
861866
})
862867
else None
868+
else if rest = [] && beforeChildrenStart && charAtCursor = '>' then
869+
(* This is a special case for: <SomeComponent someProp=> (completing directly after the '=').
870+
The completion comes at the end of the component, after the equals sign, but before any
871+
children starts, and '>' marks that it's at the end of the component JSX.
872+
This little heuristic makes sure we pick up this special case. *)
873+
Some
874+
(Cexpression
875+
{
876+
contextPath =
877+
CJsxPropValue
878+
{
879+
pathToComponent =
880+
Utils.flattenLongIdent ~jsx:true jsxProps.compName.txt;
881+
propName = prop.name;
882+
};
883+
prefix = "";
884+
nested = [];
885+
})
863886
else loop rest
864887
| [] ->
865-
let beforeChildrenStart =
866-
match jsxProps.childrenStart with
867-
| Some childrenPos -> posBeforeCursor < childrenPos
868-
| None -> posBeforeCursor <= endPos
869-
in
870888
let afterCompName = posBeforeCursor >= posAfterCompName in
871889
if afterCompName && beforeChildrenStart then
872890
Some

analysis/src/Utils.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,4 @@ let printMaybeExoticIdent ?(allowUident = false) txt =
259259
| 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '\'' | '_' -> loop (i + 1)
260260
| _ -> "\"" ^ txt ^ "\""
261261
in
262-
loop 0
262+
if Res_token.isKeywordTxt txt then "\"" ^ txt ^ "\"" else loop 0

analysis/tests/src/CompletionExpressions.res

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,19 @@ let takesExotic = (e: exoticPolyvariant) => {
271271

272272
// takesExotic()
273273
// ^com
274+
275+
let fnTakingPolyVariant = (a: somePolyVariant) => {
276+
ignore(a)
277+
}
278+
279+
// fnTakingPolyVariant()
280+
// ^com
281+
282+
// fnTakingPolyVariant(#)
283+
// ^com
284+
285+
// fnTakingPolyVariant(#o)
286+
// ^com
287+
288+
// fnTakingPolyVariant(o)
289+
// ^com

analysis/tests/src/CompletionJsx.res

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,6 @@ module CompWithoutJsxPpx = {
4545

4646
// <CompWithoutJsxPpx n
4747
// ^com
48+
49+
// <SomeComponent someProp=>
50+
// ^com

analysis/tests/src/ExhaustiveSwitch.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
type someVariant = One | Two | Three(option<bool>)
2-
type somePolyVariant = [#one | #two | #three(option<bool>) | #"exotic ident"]
2+
type somePolyVariant = [#one | #two | #three(option<bool>) | #"exotic ident" | #"switch"]
33

44
let withSomeVariant = One
55
let withSomePoly: somePolyVariant = #one

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

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,3 +1132,111 @@ Path takesExotic
11321132
"insertTextFormat": 2
11331133
}]
11341134

1135+
Complete src/CompletionExpressions.res 278:23
1136+
posCursor:[278:23] posNoWhite:[278:22] Found expr:[278:3->278:24]
1137+
Pexp_apply ...[278:3->278:22] (...[278:23->278:24])
1138+
Completable: Cexpression CArgument Value[fnTakingPolyVariant]($0)
1139+
Package opens Pervasives.JsxModules.place holder
1140+
Resolved opens 1 pervasives
1141+
ContextPath CArgument Value[fnTakingPolyVariant]($0)
1142+
ContextPath Value[fnTakingPolyVariant]
1143+
Path fnTakingPolyVariant
1144+
[{
1145+
"label": "#one",
1146+
"kind": 4,
1147+
"tags": [],
1148+
"detail": "#one\n\n[#one | #three(someRecord, bool) | #two(bool)]",
1149+
"documentation": null,
1150+
"insertText": "#one",
1151+
"insertTextFormat": 2
1152+
}, {
1153+
"label": "#three(_, _)",
1154+
"kind": 4,
1155+
"tags": [],
1156+
"detail": "#three(someRecord, bool)\n\n[#one | #three(someRecord, bool) | #two(bool)]",
1157+
"documentation": null,
1158+
"insertText": "#three(${1:_}, ${2:_})",
1159+
"insertTextFormat": 2
1160+
}, {
1161+
"label": "#two(_)",
1162+
"kind": 4,
1163+
"tags": [],
1164+
"detail": "#two(bool)\n\n[#one | #three(someRecord, bool) | #two(bool)]",
1165+
"documentation": null,
1166+
"insertText": "#two(${1:_})",
1167+
"insertTextFormat": 2
1168+
}]
1169+
1170+
Complete src/CompletionExpressions.res 281:24
1171+
posCursor:[281:24] posNoWhite:[281:23] Found expr:[281:3->281:25]
1172+
Pexp_apply ...[281:3->281:22] (...[281:23->281:25])
1173+
Completable: Cexpression CArgument Value[fnTakingPolyVariant]($0)=#
1174+
Package opens Pervasives.JsxModules.place holder
1175+
Resolved opens 1 pervasives
1176+
ContextPath CArgument Value[fnTakingPolyVariant]($0)
1177+
ContextPath Value[fnTakingPolyVariant]
1178+
Path fnTakingPolyVariant
1179+
[{
1180+
"label": "#one",
1181+
"kind": 4,
1182+
"tags": [],
1183+
"detail": "#one\n\n[#one | #three(someRecord, bool) | #two(bool)]",
1184+
"documentation": null,
1185+
"insertText": "one",
1186+
"insertTextFormat": 2
1187+
}, {
1188+
"label": "#three(_, _)",
1189+
"kind": 4,
1190+
"tags": [],
1191+
"detail": "#three(someRecord, bool)\n\n[#one | #three(someRecord, bool) | #two(bool)]",
1192+
"documentation": null,
1193+
"insertText": "three(${1:_}, ${2:_})",
1194+
"insertTextFormat": 2
1195+
}, {
1196+
"label": "#two(_)",
1197+
"kind": 4,
1198+
"tags": [],
1199+
"detail": "#two(bool)\n\n[#one | #three(someRecord, bool) | #two(bool)]",
1200+
"documentation": null,
1201+
"insertText": "two(${1:_})",
1202+
"insertTextFormat": 2
1203+
}]
1204+
1205+
Complete src/CompletionExpressions.res 284:25
1206+
posCursor:[284:25] posNoWhite:[284:24] Found expr:[284:3->284:26]
1207+
Pexp_apply ...[284:3->284:22] (...[284:23->284:25])
1208+
Completable: Cexpression CArgument Value[fnTakingPolyVariant]($0)=#o
1209+
Package opens Pervasives.JsxModules.place holder
1210+
Resolved opens 1 pervasives
1211+
ContextPath CArgument Value[fnTakingPolyVariant]($0)
1212+
ContextPath Value[fnTakingPolyVariant]
1213+
Path fnTakingPolyVariant
1214+
[{
1215+
"label": "#one",
1216+
"kind": 4,
1217+
"tags": [],
1218+
"detail": "#one\n\n[#one | #three(someRecord, bool) | #two(bool)]",
1219+
"documentation": null,
1220+
"insertText": "one",
1221+
"insertTextFormat": 2
1222+
}]
1223+
1224+
Complete src/CompletionExpressions.res 287:24
1225+
posCursor:[287:24] posNoWhite:[287:23] Found expr:[287:3->287:25]
1226+
Pexp_apply ...[287:3->287:22] (...[287:23->287:24])
1227+
Completable: Cexpression CArgument Value[fnTakingPolyVariant]($0)=o
1228+
Package opens Pervasives.JsxModules.place holder
1229+
Resolved opens 1 pervasives
1230+
ContextPath CArgument Value[fnTakingPolyVariant]($0)
1231+
ContextPath Value[fnTakingPolyVariant]
1232+
Path fnTakingPolyVariant
1233+
[{
1234+
"label": "#one",
1235+
"kind": 4,
1236+
"tags": [],
1237+
"detail": "#one\n\n[#one | #three(someRecord, bool) | #two(bool)]",
1238+
"documentation": null,
1239+
"insertText": "#one",
1240+
"insertTextFormat": 2
1241+
}]
1242+

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,3 +473,22 @@ Path CompWithoutJsxPpx.make
473473
"documentation": null
474474
}]
475475

476+
Complete src/CompletionJsx.res 48:27
477+
posCursor:[48:27] posNoWhite:[48:26] Found expr:[48:4->48:28]
478+
JSX <SomeComponent:[48:4->48:17] someProp[48:18->48:26]=...[48:18->48:26]> _children:None
479+
Completable: Cexpression CJsxPropValue [SomeComponent] someProp
480+
Package opens Pervasives.JsxModules.place holder
481+
Resolved opens 1 pervasives
482+
ContextPath CJsxPropValue [SomeComponent] someProp
483+
Path SomeComponent.make
484+
[{
485+
"label": "\"\"",
486+
"kind": 12,
487+
"tags": [],
488+
"detail": "string",
489+
"documentation": null,
490+
"sortText": "A",
491+
"insertText": "{\"$0\"}",
492+
"insertTextFormat": 2
493+
}]
494+

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Path withSomePol
4242
"detail": "insert exhaustive switch for value",
4343
"documentation": null,
4444
"filterText": "withSomePoly",
45-
"insertText": "withSomePoly {\n | #one => ${1:failwith(\"todo\")}\n | #three(_) => ${2:failwith(\"todo\")}\n | #two => ${3:failwith(\"todo\")}\n | #\"exotic ident\" => ${4:failwith(\"todo\")}\n }",
45+
"insertText": "withSomePoly {\n | #\"switch\" => ${1:failwith(\"todo\")}\n | #one => ${2:failwith(\"todo\")}\n | #three(_) => ${3:failwith(\"todo\")}\n | #two => ${4:failwith(\"todo\")}\n | #\"exotic ident\" => ${5:failwith(\"todo\")}\n }",
4646
"insertTextFormat": 2
4747
}]
4848

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "ReScript language support (official)",
55
"author": "ReScript Team",
66
"license": "MIT",
7-
"version": "1.30.0",
7+
"version": "1.32.0",
88
"repository": {
99
"type": "git",
1010
"url": "https://github.com/rescript-lang/rescript-vscode"

server/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@rescript/language-server",
33
"description": "LSP server for ReScript",
4-
"version": "1.30.0",
4+
"version": "1.32.0",
55
"author": "ReScript Team",
66
"license": "MIT",
77
"bin": {

0 commit comments

Comments
 (0)