Skip to content

Commit 88784a6

Browse files
committed
Fix issue with completion inside template expression.
Fixes #416 See rescript-lang/syntax#491
1 parent a643c39 commit 88784a6

File tree

5 files changed

+111
-29
lines changed

5 files changed

+111
-29
lines changed

Diff for: analysis/src/CompletionFrontEnd.ml

+3-2
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,8 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text =
583583
^ if opt then "?" else "")
584584
(Loc.toString exp.pexp_loc))
585585
|> String.concat ", ");
586-
let expApplyCompletable =
586+
587+
let namedArgCompletable =
587588
match exprToContextPath funExpr with
588589
| Some contextPath ->
589590
findNamedArgCompletable ~contextPath ~args
@@ -592,7 +593,7 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text =
592593
| None -> None
593594
in
594595

595-
setResultOpt expApplyCompletable
596+
setResultOpt namedArgCompletable
596597
| Pexp_send (lhs, {txt; loc}) -> (
597598
(* e["txt"]
598599
If the string for txt is not closed, it could go over several lines.

Diff for: analysis/src/vendor/res_outcome_printer/res_core.ml

+21-6
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,16 @@ let parseValuePath p =
680680
Parser.next p;
681681
Location.mkloc ident (mkLoc startPos p.prevEndPos)
682682

683+
let parseValuePathAfterDot p =
684+
let startPos = p.Parser.startPos in
685+
match p.Parser.token with
686+
| Lident _
687+
| Uident _ ->
688+
parseValuePath p
689+
| token ->
690+
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
691+
Location.mkloc (Longident.Lident "_") (mkLoc startPos p.prevEndPos)
692+
683693
let parseValuePathTail p startPos ident =
684694
let rec loop p path =
685695
match p.Parser.token with
@@ -1999,7 +2009,7 @@ and parsePrimaryExpr ~operand ?(noCall=false) p =
19992009
match p.Parser.token with
20002010
| Dot ->
20012011
Parser.next p;
2002-
let lident = parseValuePath p in
2012+
let lident = parseValuePathAfterDot p in
20032013
begin match p.Parser.token with
20042014
| Equal when noCall = false ->
20052015
Parser.leaveBreadcrumb p Grammar.ExprSetField;
@@ -3536,11 +3546,16 @@ and parseValueOrConstructor p =
35363546
let lident = buildLongident (ident::acc) in
35373547
Ast_helper.Exp.ident ~loc (Location.mkloc lident loc)
35383548
| token ->
3539-
Parser.next p;
3540-
let loc = mkLoc startPos p.prevEndPos in
3541-
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
3542-
let lident = buildLongident ("_"::acc) in
3543-
Ast_helper.Exp.ident ~loc (Location.mkloc lident loc)
3549+
if acc = [] then (
3550+
Parser.next p;
3551+
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
3552+
Recover.defaultExpr()
3553+
) else (
3554+
let loc = mkLoc startPos p.prevEndPos in
3555+
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
3556+
let lident = buildLongident ("_"::acc) in
3557+
Ast_helper.Exp.ident ~loc (Location.mkloc lident loc)
3558+
)
35443559
in
35453560
aux p []
35463561

Diff for: analysis/tests/src/Completion.res

+9
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,12 @@ let _ = x =>
375375
// ^com
376376
| _ => 4
377377
}
378+
379+
// let _ = ` ${ForAuto.}`
380+
// ^com
381+
382+
// let _ = `abc ${FAO.forAutoObject[""}`
383+
// ^com
384+
385+
// let _ = `${funRecord.}`
386+
// ^com

Diff for: analysis/tests/src/expected/Completion.res.txt

+76-19
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ Completable: Cpath Value[MyList, m]
7171
}]
7272

7373
Complete tests/src/Completion.res 3:9
74-
posCursor:[3:9] posNoWhite:[3:8] Found expr:[3:3->8:6]
75-
Pexp_ident Array.:[3:3->8:6]
74+
posCursor:[3:9] posNoWhite:[3:8] Found expr:[3:3->3:9]
75+
Pexp_ident Array.:[3:3->3:9]
7676
Completable: Cpath Value[Array, ""]
7777
[{
7878
"label": "fold_left",
@@ -617,8 +617,8 @@ Completable: Cpath Value[no]["x"]["y"][""]
617617
}]
618618

619619
Complete tests/src/Completion.res 110:5
620-
posCursor:[110:5] posNoWhite:[110:4] Found expr:[110:3->116:3]
621-
Pexp_field [110:3->110:4] _:[116:0->116:3]
620+
posCursor:[110:5] posNoWhite:[110:4] Found expr:[110:3->110:5]
621+
Pexp_field [110:3->110:4] _:[116:0->110:5]
622622
Completable: Cpath Value[r].""
623623
[{
624624
"label": "x",
@@ -635,8 +635,8 @@ Completable: Cpath Value[r].""
635635
}]
636636

637637
Complete tests/src/Completion.res 113:21
638-
posCursor:[113:21] posNoWhite:[113:20] Found expr:[113:3->116:3]
639-
Pexp_field [113:3->113:20] _:[116:0->116:3]
638+
posCursor:[113:21] posNoWhite:[113:20] Found expr:[113:3->113:21]
639+
Pexp_field [113:3->113:20] _:[116:0->113:21]
640640
Completable: Cpath Value[Obj, Rec, recordVal].""
641641
[{
642642
"label": "xx",
@@ -697,8 +697,8 @@ Completable: Cpath Module[O, ""]
697697
}]
698698

699699
Complete tests/src/Completion.res 157:8
700-
posCursor:[157:8] posNoWhite:[157:7] Found expr:[157:3->165:6]
701-
Pexp_field [157:3->157:7] _:[165:0->165:6]
700+
posCursor:[157:8] posNoWhite:[157:7] Found expr:[157:3->157:8]
701+
Pexp_field [157:3->157:7] _:[165:0->157:8]
702702
Completable: Cpath Value[q].aa.""
703703
[{
704704
"label": "x",
@@ -822,8 +822,8 @@ Completable: Cpath Module[For]
822822
}]
823823

824824
Complete tests/src/Completion.res 190:11
825-
posCursor:[190:11] posNoWhite:[190:10] Found expr:[190:3->193:6]
826-
Pexp_ident Private.:[190:3->193:6]
825+
posCursor:[190:11] posNoWhite:[190:10] Found expr:[190:3->190:11]
826+
Pexp_ident Private.:[190:3->190:11]
827827
Completable: Cpath Value[Private, ""]
828828
[{
829829
"label": "b",
@@ -882,8 +882,8 @@ Completable: Cpath Value[FAO, forAutoObject][""]
882882
}]
883883

884884
Complete tests/src/Completion.res 224:37
885-
posCursor:[224:37] posNoWhite:[224:36] Found expr:[224:3->233:3]
886-
Pexp_field [224:3->224:36] _:[233:0->233:3]
885+
posCursor:[224:37] posNoWhite:[224:36] Found expr:[224:3->224:37]
886+
Pexp_field [224:3->224:36] _:[233:0->224:37]
887887
Completable: Cpath Value[FAO, forAutoObject]["forAutoLabel"].""
888888
[{
889889
"label": "forAuto",
@@ -956,11 +956,10 @@ Completable: Cnone
956956

957957
Complete tests/src/Completion.res 243:8
958958
posCursor:[243:8] posNoWhite:[243:7] Found expr:[241:8->246:1]
959-
posCursor:[243:8] posNoWhite:[243:7] Found expr:[242:14->245:8]
960-
posCursor:[243:8] posNoWhite:[243:7] Found expr:[242:14->245:1]
961-
Pexp_apply ...[243:3->243:4] (...[242:14->242:15], ...[243:5->245:1])
962-
posCursor:[243:8] posNoWhite:[243:7] Found expr:[243:5->245:1]
963-
Pexp_field [243:5->243:7] _:[245:0->245:1]
959+
posCursor:[243:8] posNoWhite:[243:7] Found expr:[242:14->243:8]
960+
Pexp_apply ...[243:3->243:4] (...[242:14->242:15], ...[243:5->243:8])
961+
posCursor:[243:8] posNoWhite:[243:7] Found expr:[243:5->243:8]
962+
Pexp_field [243:5->243:7] _:[245:0->243:8]
964963
Completable: Cpath Value[_z].""
965964
[{
966965
"label": "x",
@@ -1088,8 +1087,8 @@ Found type for function (~name: string) => unit
10881087
}]
10891088

10901089
Complete tests/src/Completion.res 296:11
1091-
posCursor:[296:11] posNoWhite:[296:10] Found expr:[296:3->299:3]
1092-
Pexp_field [296:3->296:10] _:[299:0->299:3]
1090+
posCursor:[296:11] posNoWhite:[296:10] Found expr:[296:3->296:11]
1091+
Pexp_field [296:3->296:10] _:[299:0->296:11]
10931092
Completable: Cpath Value[retAA](Nolabel).""
10941093
[{
10951094
"label": "x",
@@ -1431,3 +1430,61 @@ Completable: Cpath Value[AndThatOther, T]
14311430
"documentation": null
14321431
}]
14331432

1433+
Complete tests/src/Completion.res 378:24
1434+
posCursor:[378:24] posNoWhite:[378:23] Found expr:[378:12->378:26]
1435+
Pexp_apply ...__ghost__[0:-1->0:-1] (...[378:12->378:16], ...[378:16->378:24])
1436+
posCursor:[378:24] posNoWhite:[378:23] Found expr:[378:16->378:24]
1437+
Pexp_ident ForAuto.:[378:16->378:24]
1438+
Completable: Cpath Value[ForAuto, ""]
1439+
[{
1440+
"label": "abc",
1441+
"kind": 12,
1442+
"tags": [],
1443+
"detail": "(t, int) => t",
1444+
"documentation": null
1445+
}, {
1446+
"label": "abd",
1447+
"kind": 12,
1448+
"tags": [],
1449+
"detail": "(t, int) => t",
1450+
"documentation": null
1451+
}]
1452+
1453+
Complete tests/src/Completion.res 381:38
1454+
posCursor:[381:38] posNoWhite:[381:37] Found expr:[381:12->381:41]
1455+
Pexp_apply ...__ghost__[0:-1->0:-1] (...[381:12->381:19], ...[381:19->381:39])
1456+
posCursor:[381:38] posNoWhite:[381:37] Found expr:[381:19->381:39]
1457+
Pexp_send [381:38->381:38] e:[381:19->381:36]
1458+
Completable: Cpath Value[FAO, forAutoObject][""]
1459+
[{
1460+
"label": "age",
1461+
"kind": 4,
1462+
"tags": [],
1463+
"detail": "int",
1464+
"documentation": null
1465+
}, {
1466+
"label": "forAutoLabel",
1467+
"kind": 4,
1468+
"tags": [],
1469+
"detail": "FAR.forAutoRecord",
1470+
"documentation": null
1471+
}]
1472+
1473+
Complete tests/src/Completion.res 384:24
1474+
posCursor:[384:24] posNoWhite:[384:23] Found expr:[384:11->384:26]
1475+
Pexp_field [384:14->384:23] _:[384:24->384:24]
1476+
Completable: Cpath Value[funRecord].""
1477+
[{
1478+
"label": "someFun",
1479+
"kind": 5,
1480+
"tags": [],
1481+
"detail": "someFun: (~name: string) => unit\n\ntype funRecord = {\n someFun: (~name: string) => unit,\n stuff: string,\n}",
1482+
"documentation": null
1483+
}, {
1484+
"label": "stuff",
1485+
"kind": 5,
1486+
"tags": [],
1487+
"detail": "stuff: string\n\ntype funRecord = {\n someFun: (~name: string) => unit,\n stuff: string,\n}",
1488+
"documentation": null
1489+
}]
1490+

Diff for: analysis/tests/src/expected/Jsx.res.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ Completable: Cpath Value[x].th
310310
[]
311311

312312
Complete tests/src/Jsx.res 106:28
313-
posCursor:[106:28] posNoWhite:[106:27] Found expr:[106:11->111:3]
314-
Pexp_ident DefineSomeFields.:[106:11->111:3]
313+
posCursor:[106:28] posNoWhite:[106:27] Found expr:[106:11->106:28]
314+
Pexp_ident DefineSomeFields.:[106:11->106:28]
315315
Completable: Cpath Value[DefineSomeFields, ""]
316316
[{
317317
"label": "thisValue",

0 commit comments

Comments
 (0)