diff --git a/analysis/src/CompletionFrontEnd.ml b/analysis/src/CompletionFrontEnd.ml index 35c099463..c44ec69f0 100644 --- a/analysis/src/CompletionFrontEnd.ml +++ b/analysis/src/CompletionFrontEnd.ml @@ -583,7 +583,8 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text = ^ if opt then "?" else "") (Loc.toString exp.pexp_loc)) |> String.concat ", "); - let expApplyCompletable = + + let namedArgCompletable = match exprToContextPath funExpr with | Some contextPath -> findNamedArgCompletable ~contextPath ~args @@ -592,7 +593,7 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text = | None -> None in - setResultOpt expApplyCompletable + setResultOpt namedArgCompletable | Pexp_send (lhs, {txt; loc}) -> ( (* e["txt"] If the string for txt is not closed, it could go over several lines. diff --git a/analysis/src/vendor/res_outcome_printer/res_core.ml b/analysis/src/vendor/res_outcome_printer/res_core.ml index c400dc9e4..ea5bc14f0 100644 --- a/analysis/src/vendor/res_outcome_printer/res_core.ml +++ b/analysis/src/vendor/res_outcome_printer/res_core.ml @@ -680,6 +680,16 @@ let parseValuePath p = Parser.next p; Location.mkloc ident (mkLoc startPos p.prevEndPos) +let parseValuePathAfterDot p = + let startPos = p.Parser.startPos in + match p.Parser.token with + | Lident _ + | Uident _ -> + parseValuePath p + | token -> + Parser.err p (Diagnostics.unexpected token p.breadcrumbs); + Location.mkloc (Longident.Lident "_") (mkLoc startPos p.prevEndPos) + let parseValuePathTail p startPos ident = let rec loop p path = match p.Parser.token with @@ -1999,7 +2009,7 @@ and parsePrimaryExpr ~operand ?(noCall=false) p = match p.Parser.token with | Dot -> Parser.next p; - let lident = parseValuePath p in + let lident = parseValuePathAfterDot p in begin match p.Parser.token with | Equal when noCall = false -> Parser.leaveBreadcrumb p Grammar.ExprSetField; @@ -3536,11 +3546,16 @@ and parseValueOrConstructor p = let lident = buildLongident (ident::acc) in Ast_helper.Exp.ident ~loc (Location.mkloc lident loc) | token -> - Parser.next p; - let loc = mkLoc startPos p.prevEndPos in - Parser.err p (Diagnostics.unexpected token p.breadcrumbs); - let lident = buildLongident ("_"::acc) in - Ast_helper.Exp.ident ~loc (Location.mkloc lident loc) + if acc = [] then ( + Parser.next p; + Parser.err p (Diagnostics.unexpected token p.breadcrumbs); + Recover.defaultExpr() + ) else ( + let loc = mkLoc startPos p.prevEndPos in + Parser.err p (Diagnostics.unexpected token p.breadcrumbs); + let lident = buildLongident ("_"::acc) in + Ast_helper.Exp.ident ~loc (Location.mkloc lident loc) + ) in aux p [] diff --git a/analysis/tests/src/Completion.res b/analysis/tests/src/Completion.res index f364e964a..a832c262f 100644 --- a/analysis/tests/src/Completion.res +++ b/analysis/tests/src/Completion.res @@ -375,3 +375,12 @@ let _ = x => // ^com | _ => 4 } + +// let _ = ` ${ForAuto.}` +// ^com + +// let _ = `abc ${FAO.forAutoObject[""}` +// ^com + +// let _ = `${funRecord.}` +// ^com \ No newline at end of file diff --git a/analysis/tests/src/expected/Completion.res.txt b/analysis/tests/src/expected/Completion.res.txt index 5776927a6..a28026104 100644 --- a/analysis/tests/src/expected/Completion.res.txt +++ b/analysis/tests/src/expected/Completion.res.txt @@ -71,8 +71,8 @@ Completable: Cpath Value[MyList, m] }] Complete tests/src/Completion.res 3:9 -posCursor:[3:9] posNoWhite:[3:8] Found expr:[3:3->8:6] -Pexp_ident Array.:[3:3->8:6] +posCursor:[3:9] posNoWhite:[3:8] Found expr:[3:3->3:9] +Pexp_ident Array.:[3:3->3:9] Completable: Cpath Value[Array, ""] [{ "label": "fold_left", @@ -617,8 +617,8 @@ Completable: Cpath Value[no]["x"]["y"][""] }] Complete tests/src/Completion.res 110:5 -posCursor:[110:5] posNoWhite:[110:4] Found expr:[110:3->116:3] -Pexp_field [110:3->110:4] _:[116:0->116:3] +posCursor:[110:5] posNoWhite:[110:4] Found expr:[110:3->110:5] +Pexp_field [110:3->110:4] _:[116:0->110:5] Completable: Cpath Value[r]."" [{ "label": "x", @@ -635,8 +635,8 @@ Completable: Cpath Value[r]."" }] Complete tests/src/Completion.res 113:21 -posCursor:[113:21] posNoWhite:[113:20] Found expr:[113:3->116:3] -Pexp_field [113:3->113:20] _:[116:0->116:3] +posCursor:[113:21] posNoWhite:[113:20] Found expr:[113:3->113:21] +Pexp_field [113:3->113:20] _:[116:0->113:21] Completable: Cpath Value[Obj, Rec, recordVal]."" [{ "label": "xx", @@ -697,8 +697,8 @@ Completable: Cpath Module[O, ""] }] Complete tests/src/Completion.res 157:8 -posCursor:[157:8] posNoWhite:[157:7] Found expr:[157:3->165:6] -Pexp_field [157:3->157:7] _:[165:0->165:6] +posCursor:[157:8] posNoWhite:[157:7] Found expr:[157:3->157:8] +Pexp_field [157:3->157:7] _:[165:0->157:8] Completable: Cpath Value[q].aa."" [{ "label": "x", @@ -822,8 +822,8 @@ Completable: Cpath Module[For] }] Complete tests/src/Completion.res 190:11 -posCursor:[190:11] posNoWhite:[190:10] Found expr:[190:3->193:6] -Pexp_ident Private.:[190:3->193:6] +posCursor:[190:11] posNoWhite:[190:10] Found expr:[190:3->190:11] +Pexp_ident Private.:[190:3->190:11] Completable: Cpath Value[Private, ""] [{ "label": "b", @@ -882,8 +882,8 @@ Completable: Cpath Value[FAO, forAutoObject][""] }] Complete tests/src/Completion.res 224:37 -posCursor:[224:37] posNoWhite:[224:36] Found expr:[224:3->233:3] -Pexp_field [224:3->224:36] _:[233:0->233:3] +posCursor:[224:37] posNoWhite:[224:36] Found expr:[224:3->224:37] +Pexp_field [224:3->224:36] _:[233:0->224:37] Completable: Cpath Value[FAO, forAutoObject]["forAutoLabel"]."" [{ "label": "forAuto", @@ -956,11 +956,10 @@ Completable: Cnone Complete tests/src/Completion.res 243:8 posCursor:[243:8] posNoWhite:[243:7] Found expr:[241:8->246:1] -posCursor:[243:8] posNoWhite:[243:7] Found expr:[242:14->245:8] -posCursor:[243:8] posNoWhite:[243:7] Found expr:[242:14->245:1] -Pexp_apply ...[243:3->243:4] (...[242:14->242:15], ...[243:5->245:1]) -posCursor:[243:8] posNoWhite:[243:7] Found expr:[243:5->245:1] -Pexp_field [243:5->243:7] _:[245:0->245:1] +posCursor:[243:8] posNoWhite:[243:7] Found expr:[242:14->243:8] +Pexp_apply ...[243:3->243:4] (...[242:14->242:15], ...[243:5->243:8]) +posCursor:[243:8] posNoWhite:[243:7] Found expr:[243:5->243:8] +Pexp_field [243:5->243:7] _:[245:0->243:8] Completable: Cpath Value[_z]."" [{ "label": "x", @@ -1088,8 +1087,8 @@ Found type for function (~name: string) => unit }] Complete tests/src/Completion.res 296:11 -posCursor:[296:11] posNoWhite:[296:10] Found expr:[296:3->299:3] -Pexp_field [296:3->296:10] _:[299:0->299:3] +posCursor:[296:11] posNoWhite:[296:10] Found expr:[296:3->296:11] +Pexp_field [296:3->296:10] _:[299:0->296:11] Completable: Cpath Value[retAA](Nolabel)."" [{ "label": "x", @@ -1431,3 +1430,61 @@ Completable: Cpath Value[AndThatOther, T] "documentation": null }] +Complete tests/src/Completion.res 378:24 +posCursor:[378:24] posNoWhite:[378:23] Found expr:[378:12->378:26] +Pexp_apply ...__ghost__[0:-1->0:-1] (...[378:12->378:16], ...[378:16->378:24]) +posCursor:[378:24] posNoWhite:[378:23] Found expr:[378:16->378:24] +Pexp_ident ForAuto.:[378:16->378:24] +Completable: Cpath Value[ForAuto, ""] +[{ + "label": "abc", + "kind": 12, + "tags": [], + "detail": "(t, int) => t", + "documentation": null + }, { + "label": "abd", + "kind": 12, + "tags": [], + "detail": "(t, int) => t", + "documentation": null + }] + +Complete tests/src/Completion.res 381:38 +posCursor:[381:38] posNoWhite:[381:37] Found expr:[381:12->381:41] +Pexp_apply ...__ghost__[0:-1->0:-1] (...[381:12->381:19], ...[381:19->381:39]) +posCursor:[381:38] posNoWhite:[381:37] Found expr:[381:19->381:39] +Pexp_send [381:38->381:38] e:[381:19->381:36] +Completable: Cpath Value[FAO, forAutoObject][""] +[{ + "label": "age", + "kind": 4, + "tags": [], + "detail": "int", + "documentation": null + }, { + "label": "forAutoLabel", + "kind": 4, + "tags": [], + "detail": "FAR.forAutoRecord", + "documentation": null + }] + +Complete tests/src/Completion.res 384:24 +posCursor:[384:24] posNoWhite:[384:23] Found expr:[384:11->384:26] +Pexp_field [384:14->384:23] _:[384:24->384:24] +Completable: Cpath Value[funRecord]."" +[{ + "label": "someFun", + "kind": 5, + "tags": [], + "detail": "someFun: (~name: string) => unit\n\ntype funRecord = {\n someFun: (~name: string) => unit,\n stuff: string,\n}", + "documentation": null + }, { + "label": "stuff", + "kind": 5, + "tags": [], + "detail": "stuff: string\n\ntype funRecord = {\n someFun: (~name: string) => unit,\n stuff: string,\n}", + "documentation": null + }] + diff --git a/analysis/tests/src/expected/Jsx.res.txt b/analysis/tests/src/expected/Jsx.res.txt index d080052c6..5cb54a650 100644 --- a/analysis/tests/src/expected/Jsx.res.txt +++ b/analysis/tests/src/expected/Jsx.res.txt @@ -310,8 +310,8 @@ Completable: Cpath Value[x].th [] Complete tests/src/Jsx.res 106:28 -posCursor:[106:28] posNoWhite:[106:27] Found expr:[106:11->111:3] -Pexp_ident DefineSomeFields.:[106:11->111:3] +posCursor:[106:28] posNoWhite:[106:27] Found expr:[106:11->106:28] +Pexp_ident DefineSomeFields.:[106:11->106:28] Completable: Cpath Value[DefineSomeFields, ""] [{ "label": "thisValue",