diff --git a/analysis/src/Completion.ml b/analysis/src/Completion.ml index 7cc0c9176..ddcf29e7a 100644 --- a/analysis/src/Completion.ml +++ b/analysis/src/Completion.ml @@ -31,7 +31,7 @@ type prop = { } type jsxProps = { - componentPath : string list; + compName : Longident.t Location.loc; props : prop list; childrenStart : (int * int) option; } @@ -47,7 +47,11 @@ let findJsxPropsCompletable ~jsxProps ~endPos ~posBeforeCursor ~posAfterCompName match props with | prop :: rest -> if prop.posStart <= posBeforeCursor && posBeforeCursor < prop.posEnd then - Some (Completable.Cjsx (jsxProps.componentPath, prop.name, allLabels)) + Some + (Completable.Cjsx + ( Utils.flattenLongIdent ~jsx:true jsxProps.compName.txt, + prop.name, + allLabels )) else if prop.posEnd <= posBeforeCursor && posBeforeCursor < Loc.start prop.exp.pexp_loc @@ -62,7 +66,11 @@ let findJsxPropsCompletable ~jsxProps ~endPos ~posBeforeCursor ~posAfterCompName in let afterCompName = posBeforeCursor >= posAfterCompName in if afterCompName && beforeChildrenStart then - Some (Cjsx (jsxProps.componentPath, "", allLabels)) + Some + (Cjsx + ( Utils.flattenLongIdent ~jsx:true jsxProps.compName.txt, + "", + allLabels )) else None in loop jsxProps.props @@ -91,13 +99,17 @@ let rec skipComment ~pos ~i ~depth str = let extractJsxProps ~(compName : Longident.t Location.loc) ~args = let thisCaseShouldNotHappen = - {componentPath = []; props = []; childrenStart = None} + { + compName = Location.mknoloc (Longident.Lident ""); + props = []; + childrenStart = None; + } in let rec processProps ~acc args = match args with | (Asttypes.Labelled "children", {Parsetree.pexp_loc}) :: _ -> { - componentPath = Utils.flattenLongIdent ~jsx:true compName.txt; + compName; props = List.rev acc; childrenStart = (if pexp_loc.loc_ghost then None else Some (Loc.start pexp_loc)); @@ -235,6 +247,21 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text = | _ -> None) | _ -> None in + let flattenLidCheckDot ?(jsx = true) (lid : Longident.t Location.loc) = + (* Flatten an identifier keeping track of whether the current cursor + is after a "." in the id followed by a blank character. + In that case, cut the path after ".". *) + let cutAtOffset = + let idStart = Loc.start lid.loc in + match blankAfterCursor with + | Some '.' -> + if fst posBeforeCursor = fst idStart then + Some (snd posBeforeCursor - snd idStart) + else None + | _ -> None + in + Utils.flattenLongIdent ~cutAtOffset ~jsx lid.txt + in let found = ref false in let result = ref None in @@ -449,46 +476,31 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text = so the apply expression does not include the cursor *) if setPipeResult ~lhs ~id:"" then setFound () | _ -> - if expr.pexp_loc |> Loc.hasPos ~pos:posNoWhite then ( + if expr.pexp_loc |> Loc.hasPos ~pos:posNoWhite && !result = None then ( setFound (); match expr.pexp_desc with | Pexp_constant _ -> setResult Cnone - | Pexp_ident id -> + | Pexp_ident lid -> + let lidPath = flattenLidCheckDot lid in if debug then Printf.printf "Pexp_ident %s:%s\n" - (Utils.flattenLongIdent id.txt |> String.concat ".") - (Loc.toString id.loc); - if id.loc |> Loc.hasPos ~pos:posBeforeCursor then - let path_ = id.txt |> Utils.flattenLongIdent in - let path = - if blankAfterCursor = Some '.' then ( - (* Sometimes "Foo. " is followed by "bar" and the parser's - behaviour is to parse as "Foo.bar". - This gets back the intended path "Foo." *) - let path = - match path_ |> List.rev with - | _last :: pathRev -> List.rev ("" :: pathRev) - | path -> path - in - if debug then - Printf.printf "Id breaks up. New path:%s\n" - (path |> String.concat "."); - path) - else path_ - in - setResult (Cpath (CPId (path, Value))) - | Pexp_construct (id, eOpt) -> + (lidPath |> String.concat ".") + (Loc.toString lid.loc); + if lid.loc |> Loc.hasPos ~pos:posBeforeCursor then + setResult (Cpath (CPId (lidPath, Value))) + | Pexp_construct (lid, eOpt) -> + let lidPath = flattenLidCheckDot lid in if debug then Printf.printf "Pexp_construct %s:%s %s\n" - (Utils.flattenLongIdent id.txt |> String.concat "\n") - (Loc.toString id.loc) + (lidPath |> String.concat "\n") + (Loc.toString lid.loc) (match eOpt with | None -> "None" | Some e -> Loc.toString e.pexp_loc); if - eOpt = None && (not id.loc.loc_ghost) - && id.loc |> Loc.hasPos ~pos:posBeforeCursor - then setResult (Cpath (CPId (Utils.flattenLongIdent id.txt, Value))) + eOpt = None && (not lid.loc.loc_ghost) + && lid.loc |> Loc.hasPos ~pos:posBeforeCursor + then setResult (Cpath (CPId (lidPath, Value))) | Pexp_field (e, fieldName) -> ( if debug then Printf.printf "Pexp_field %s %s:%s\n" (Loc.toString e.pexp_loc) @@ -507,7 +519,10 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text = let contextPath = Completable.CPField ( CPId (Utils.flattenLongIdent id, Module), - if name = "_" then "" else name ) + if blankAfterCursor = Some '.' then + (* x.M. field ---> M. *) "" + else if name = "_" then "" + else name ) in setResult (Cpath contextPath) | Lapply _ -> () @@ -518,9 +533,10 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text = | Pexp_apply ({pexp_desc = Pexp_ident compName}, args) when Res_parsetree_viewer.isJsxExpression expr -> let jsxProps = extractJsxProps ~compName ~args in + let compNamePath = flattenLidCheckDot ~jsx:true compName in if debug then Printf.printf "JSX <%s:%s %s> _children:%s\n" - (jsxProps.componentPath |> String.concat ",") + (compNamePath |> String.concat ".") (Loc.toString compName.loc) (jsxProps.props |> List.map (fun {name; posStart; posEnd; exp} -> @@ -537,9 +553,7 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text = in if jsxCompletable <> None then setResultOpt jsxCompletable else if compName.loc |> Loc.hasPos ~pos:posBeforeCursor then - setResult - (Cpath - (CPId (Utils.flattenLongIdent ~jsx:true compName.txt, Module))) + setResult (Cpath (CPId (compNamePath, Module))) | Pexp_apply ( {pexp_desc = Pexp_ident {txt = Lident "|."}}, [ @@ -630,39 +644,42 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text = (Pos.toString posCursor) (Pos.toString posNoWhite) (Loc.toString core_type.ptyp_loc); match core_type.ptyp_desc with - | Ptyp_constr (id, _args) -> + | Ptyp_constr (lid, _args) -> + let lidPath = flattenLidCheckDot lid in if debug then Printf.printf "Ptyp_constr %s:%s\n" - (Utils.flattenLongIdent id.txt |> String.concat ".") - (Loc.toString id.loc); - if id.loc |> Loc.hasPos ~pos:posBeforeCursor then - setResult (Cpath (CPId (Utils.flattenLongIdent id.txt, Type))) + (lidPath |> String.concat ".") + (Loc.toString lid.loc); + if lid.loc |> Loc.hasPos ~pos:posBeforeCursor then + setResult (Cpath (CPId (lidPath, Type))) | _ -> ()); Ast_iterator.default_iterator.typ iterator core_type in let module_expr (iterator : Ast_iterator.iterator) (me : Parsetree.module_expr) = (match me.pmod_desc with - | Pmod_ident id when id.loc |> Loc.hasPos ~pos:posBeforeCursor -> + | Pmod_ident lid when lid.loc |> Loc.hasPos ~pos:posBeforeCursor -> + let lidPath = flattenLidCheckDot lid in if debug then Printf.printf "Pmod_ident %s:%s\n" - (Utils.flattenLongIdent id.txt |> String.concat ".") - (Loc.toString id.loc); + (lidPath |> String.concat ".") + (Loc.toString lid.loc); found := true; - setResult (Cpath (CPId (Utils.flattenLongIdent id.txt, Module))) + setResult (Cpath (CPId (lidPath, Module))) | _ -> ()); Ast_iterator.default_iterator.module_expr iterator me in let module_type (iterator : Ast_iterator.iterator) (mt : Parsetree.module_type) = (match mt.pmty_desc with - | Pmty_ident id when id.loc |> Loc.hasPos ~pos:posBeforeCursor -> + | Pmty_ident lid when lid.loc |> Loc.hasPos ~pos:posBeforeCursor -> + let lidPath = flattenLidCheckDot lid in if debug then Printf.printf "Pmty_ident %s:%s\n" - (Utils.flattenLongIdent id.txt |> String.concat ".") - (Loc.toString id.loc); + (lidPath |> String.concat ".") + (Loc.toString lid.loc); found := true; - setResult (Cpath (CPId (Utils.flattenLongIdent id.txt, Module))) + setResult (Cpath (CPId (lidPath, Module))) | _ -> ()); Ast_iterator.default_iterator.module_type iterator mt in diff --git a/analysis/src/Utils.ml b/analysis/src/Utils.ml index cb053c523..e5072f21d 100644 --- a/analysis/src/Utils.ml +++ b/analysis/src/Utils.ml @@ -53,17 +53,17 @@ let filterMap f = let dumpPath path = Str.global_replace (Str.regexp_string "\\") "/" path let isUncurriedInternal path = startsWith (Path.name path) "Js.Fn.arity" -let flattenLongIdent ?(jsx = false) lid = - let rec loop acc lid = +let flattenLongIdent ?(jsx = false) ?(cutAtOffset = None) lid = + let rec loop lid = match lid with - | Longident.Lident txt -> txt :: acc + | Longident.Lident txt -> ([txt], String.length txt) | Ldot (lid, txt) -> - let acc = - if jsx && txt = "createElement" then acc - else if txt = "_" then "" :: acc - else txt :: acc - in - loop acc lid - | Lapply _ -> acc + let path, offset = loop lid in + if Some offset = cutAtOffset then ("" :: path, offset + 1) + else if jsx && txt = "createElement" then (path, offset) + else if txt = "_" then ("" :: path, offset + 1) + else (txt :: path, offset + 1 + String.length txt) + | Lapply _ -> ([], 0) in - loop [] lid + let path, _ = loop lid in + List.rev path diff --git a/analysis/tests/src/Completion.res b/analysis/tests/src/Completion.res index 2e2d462d6..795373b23 100644 --- a/analysis/tests/src/Completion.res +++ b/analysis/tests/src/Completion.res @@ -256,3 +256,10 @@ module SomeLocalModule = { // ^com // type zz = SomeLocalModule. // ^com + +type record = { + someProp: string, + // otherProp: SomeLocalModule. + // ^com + thirdProp: string, +} diff --git a/analysis/tests/src/Jsx.res b/analysis/tests/src/Jsx.res index e8c4c5608..f251ac40d 100644 --- a/analysis/tests/src/Jsx.res +++ b/analysis/tests/src/Jsx.res @@ -9,11 +9,9 @@ let _ = // + +module Nested = { + module Comp = { + @react.component + let make = (~name) => React.string(name) + } +} + +let _ = + +// let _ = +// ^com + +// let _ = +// ^com diff --git a/analysis/tests/src/RecordCompletion.res b/analysis/tests/src/RecordCompletion.res index 8a28cd31e..0ec0c6982 100644 --- a/analysis/tests/src/RecordCompletion.res +++ b/analysis/tests/src/RecordCompletion.res @@ -19,3 +19,6 @@ module R = { let n = {R.name: ""} // n.R. // ^com + +// n.R. xx +// ^com diff --git a/analysis/tests/src/expected/Completion.res.txt b/analysis/tests/src/expected/Completion.res.txt index 1088c0490..d75e44d13 100644 --- a/analysis/tests/src/expected/Completion.res.txt +++ b/analysis/tests/src/expected/Completion.res.txt @@ -73,7 +73,6 @@ 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] -Id breaks up. New path:Array. Completable: Cpath Value[Array, ""] [{ "label": "fold_left", @@ -379,8 +378,6 @@ Completable: Clabel([Lib, foo], "", []) Complete tests/src/Completion.res 26:13 posCursor:[26:13] posNoWhite:[26:12] Found expr:[26:3->26:13] -posCursor:[26:13] posNoWhite:[26:12] Found expr:[26:12->26:13] -Pexp_ident m:[26:12->26:13] Completable: Cpath array->m [{ "label": "Js.Array2.mapi", @@ -398,8 +395,6 @@ Completable: Cpath array->m Complete tests/src/Completion.res 29:13 posCursor:[29:13] posNoWhite:[29:12] Found expr:[29:3->29:13] -posCursor:[29:13] posNoWhite:[29:12] Found expr:[29:10->29:13] -Pexp_ident toU:[29:10->29:13] Completable: Cpath string->toU [{ "label": "Js.String2.toUpperCase", @@ -411,8 +406,6 @@ Completable: Cpath string->toU Complete tests/src/Completion.res 34:8 posCursor:[34:8] posNoWhite:[34:7] Found expr:[34:3->34:8] -posCursor:[34:8] posNoWhite:[34:7] Found expr:[34:7->34:8] -Pexp_ident e:[34:7->34:8] Completable: Cpath Value[op]->e [{ "label": "Belt.Option.eqU", @@ -432,8 +425,6 @@ Complete tests/src/Completion.res 44:7 posCursor:[44:7] posNoWhite:[44:6] Found expr:[44:3->54:3] Pexp_apply ...[50:9->50:10] (...[44:3->50:8], ...[51:2->54:3]) posCursor:[44:7] posNoWhite:[44:6] Found expr:[44:3->50:8] -posCursor:[44:7] posNoWhite:[44:6] Found expr:[44:5->44:7] -Pexp_ident |.:[44:5->44:7] Completable: Cpath Value[fa]-> [{ "label": "ForAuto.abc", @@ -470,7 +461,7 @@ Completable: Cpath Value[Js, Dict, u] Complete tests/src/Completion.res 59:30 posCursor:[59:30] posNoWhite:[59:29] Found expr:[59:15->59:30] -JSX 59:21] second[59:22->59:28]=...[59:29->59:30]> _children:None +JSX 59:21] second[59:22->59:28]=...[59:29->59:30]> _children:None posCursor:[59:30] posNoWhite:[59:29] Found expr:[59:29->59:30] Pexp_ident z:[59:29->59:30] Completable: Cpath Value[z] @@ -484,9 +475,7 @@ Completable: Cpath Value[z] Complete tests/src/Completion.res 62:23 posCursor:[62:23] posNoWhite:[62:22] Found expr:[62:15->62:23] -JSX 62:21] z[62:22->62:23]=...[62:22->62:23]> _children:None -posCursor:[62:23] posNoWhite:[62:22] Found expr:[62:22->62:23] -Pexp_ident z:[62:22->62:23] +JSX 62:21] z[62:22->62:23]=...[62:22->62:23]> _children:None Completable: Cjsx([O, Comp], z, [z]) [{ "label": "zoo", @@ -692,10 +681,7 @@ Completable: Cpath Value[Obj, object][""] Complete tests/src/Completion.res 151:6 posCursor:[151:6] posNoWhite:[151:5] Found expr:[151:4->151:6] -JSX 151:6] > _children:None -posCursor:[151:6] posNoWhite:[151:5] Found expr:[151:4->151:6] -Pexp_ident O..createElement:[151:4->151:6] -Id breaks up. New path:O.. +JSX 151:6] > _children:None Completable: Cpath Module[O, ""] [{ "label": "Comp", @@ -756,8 +742,6 @@ Completable: Cpath Value[Lis] Complete tests/src/Completion.res 169:16 posCursor:[169:16] posNoWhite:[169:15] Found expr:[169:4->169:16] JSX 169:16] > _children:None -posCursor:[169:16] posNoWhite:[169:15] Found expr:[169:4->169:16] -Pexp_ident WithChildren.createElement:[169:4->169:16] Completable: Cpath Module[WithChildren] [{ "label": "WithChildren", @@ -835,7 +819,6 @@ 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] -Id breaks up. New path:Private. Completable: Cpath Value[Private, ""] [{ "label": "b", @@ -1012,3 +995,15 @@ Completable: Cpath Type[SomeLocalModule, ""] "documentation": null }] +Complete tests/src/Completion.res 261:33 +posCursor:[261:33] posNoWhite:[261:32] Found type:[261:17->263:11] +Ptyp_constr SomeLocalModule.:[261:17->263:11] +Completable: Cpath Type[SomeLocalModule, ""] +[{ + "label": "zz", + "kind": 22, + "tags": [], + "detail": "type zz = int", + "documentation": null + }] + diff --git a/analysis/tests/src/expected/Div.res.txt b/analysis/tests/src/expected/Div.res.txt index 02d85074c..d79235bf9 100644 --- a/analysis/tests/src/expected/Div.res.txt +++ b/analysis/tests/src/expected/Div.res.txt @@ -4,8 +4,6 @@ Hover tests/src/Div.res 0:10 Complete tests/src/Div.res 3:17 posCursor:[3:17] posNoWhite:[3:16] Found expr:[3:4->3:17] JSX 3:7] dangerous[3:8->3:17]=...[3:8->3:17]> _children:None -posCursor:[3:17] posNoWhite:[3:16] Found expr:[3:8->3:17] -Pexp_ident dangerous:[3:8->3:17] Completable: Cjsx([div], dangerous, [dangerous]) [{ "label": "dangerouslySetInnerHTML", diff --git a/analysis/tests/src/expected/Jsx.res.txt b/analysis/tests/src/expected/Jsx.res.txt index f452983c9..f91078652 100644 --- a/analysis/tests/src/expected/Jsx.res.txt +++ b/analysis/tests/src/expected/Jsx.res.txt @@ -9,11 +9,9 @@ Pexp_ident fi:[8:13->8:15] Completable: Cpath Value[fi] [] -Complete tests/src/Jsx.res 12:20 -posCursor:[12:20] posNoWhite:[12:19] Found expr:[12:4->12:20] -JSX 12:5] second[12:6->12:12]=...[12:13->12:18] f[12:19->12:20]=...[12:19->12:20]> _children:None -posCursor:[12:20] posNoWhite:[12:19] Found expr:[12:19->12:20] -Pexp_ident f:[12:19->12:20] +Complete tests/src/Jsx.res 11:20 +posCursor:[11:20] posNoWhite:[11:19] Found expr:[11:4->11:20] +JSX 11:5] second[11:6->11:12]=...[11:13->11:18] f[11:19->11:20]=...[11:19->11:20]> _children:None Completable: Cjsx([M], f, [second, f]) [{ "label": "first", @@ -29,11 +27,9 @@ Completable: Cjsx([M], f, [second, f]) "documentation": null }] -Complete tests/src/Jsx.res 16:13 -posCursor:[16:13] posNoWhite:[16:12] Found expr:[16:12->16:13] -JSX 16:13] > _children:None -posCursor:[16:13] posNoWhite:[16:12] Found expr:[16:12->16:13] -Pexp_ident M.createElement:[16:12->16:13] +Complete tests/src/Jsx.res 14:13 +posCursor:[14:13] posNoWhite:[14:12] Found expr:[14:12->14:13] +JSX 14:13] > _children:None Completable: Cpath Module[M] [{ "label": "M", @@ -55,11 +51,9 @@ Completable: Cpath Module[M] "documentation": null }] -Complete tests/src/Jsx.res 24:19 -posCursor:[24:19] posNoWhite:[24:18] Found expr:[24:4->24:19] -JSX 24:5] prop[24:6->24:10]=...[24:12->24:16] k[24:18->24:19]=...[24:18->24:19]> _children:None -posCursor:[24:19] posNoWhite:[24:18] Found expr:[24:18->24:19] -Pexp_ident k:[24:18->24:19] +Complete tests/src/Jsx.res 22:19 +posCursor:[22:19] posNoWhite:[22:18] Found expr:[22:4->22:19] +JSX 22:5] prop[22:6->22:10]=...[22:12->22:16] k[22:18->22:19]=...[22:18->22:19]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -69,11 +63,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 27:17 -posCursor:[27:17] posNoWhite:[27:16] Found expr:[27:4->27:17] -JSX 27:5] prop[27:6->27:10]=...[27:11->27:15] k[27:16->27:17]=...[27:16->27:17]> _children:None -posCursor:[27:17] posNoWhite:[27:16] Found expr:[27:16->27:17] -Pexp_ident k:[27:16->27:17] +Complete tests/src/Jsx.res 25:17 +posCursor:[25:17] posNoWhite:[25:16] Found expr:[25:4->25:17] +JSX 25:5] prop[25:6->25:10]=...[25:11->25:15] k[25:16->25:17]=...[25:16->25:17]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -83,11 +75,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 30:21 -posCursor:[30:21] posNoWhite:[30:20] Found expr:[30:4->30:21] -JSX 30:5] prop[30:6->30:10]=...[30:11->30:19] k[30:20->30:21]=...[30:20->30:21]> _children:None -posCursor:[30:21] posNoWhite:[30:20] Found expr:[30:20->30:21] -Pexp_ident k:[30:20->30:21] +Complete tests/src/Jsx.res 28:21 +posCursor:[28:21] posNoWhite:[28:20] Found expr:[28:4->28:21] +JSX 28:5] prop[28:6->28:10]=...[28:11->28:19] k[28:20->28:21]=...[28:20->28:21]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -97,11 +87,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 33:24 -posCursor:[33:24] posNoWhite:[33:23] Found expr:[33:4->33:24] -JSX 33:5] prop[33:6->33:10]=...[33:11->33:22] k[33:23->33:24]=...[33:23->33:24]> _children:None -posCursor:[33:24] posNoWhite:[33:23] Found expr:[33:23->33:24] -Pexp_ident k:[33:23->33:24] +Complete tests/src/Jsx.res 31:24 +posCursor:[31:24] posNoWhite:[31:23] Found expr:[31:4->31:24] +JSX 31:5] prop[31:6->31:10]=...[31:11->31:22] k[31:23->31:24]=...[31:23->31:24]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -111,11 +99,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 36:18 -posCursor:[36:18] posNoWhite:[36:17] Found expr:[36:4->36:18] -JSX 36:5] prop[36:6->36:10]=...[36:12->36:16] k[36:17->36:18]=...[36:17->36:18]> _children:None -posCursor:[36:18] posNoWhite:[36:17] Found expr:[36:17->36:18] -Pexp_ident k:[36:17->36:18] +Complete tests/src/Jsx.res 34:18 +posCursor:[34:18] posNoWhite:[34:17] Found expr:[34:4->34:18] +JSX 34:5] prop[34:6->34:10]=...[34:12->34:16] k[34:17->34:18]=...[34:17->34:18]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -125,11 +111,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 39:16 -posCursor:[39:16] posNoWhite:[39:15] Found expr:[39:4->39:16] -JSX 39:5] prop[39:6->39:10]=...[39:11->39:14] k[39:15->39:16]=...[39:15->39:16]> _children:None -posCursor:[39:16] posNoWhite:[39:15] Found expr:[39:15->39:16] -Pexp_ident k:[39:15->39:16] +Complete tests/src/Jsx.res 37:16 +posCursor:[37:16] posNoWhite:[37:15] Found expr:[37:4->37:16] +JSX 37:5] prop[37:6->37:10]=...[37:11->37:14] k[37:15->37:16]=...[37:15->37:16]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -139,11 +123,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 42:17 -posCursor:[42:17] posNoWhite:[42:16] Found expr:[42:4->42:17] -JSX 42:5] prop[42:6->42:10]=...[42:11->42:15] k[42:16->42:17]=...[42:16->42:17]> _children:None -posCursor:[42:17] posNoWhite:[42:16] Found expr:[42:16->42:17] -Pexp_ident k:[42:16->42:17] +Complete tests/src/Jsx.res 40:17 +posCursor:[40:17] posNoWhite:[40:16] Found expr:[40:4->40:17] +JSX 40:5] prop[40:6->40:10]=...[40:11->40:15] k[40:16->40:17]=...[40:16->40:17]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -153,11 +135,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 45:18 -posCursor:[45:18] posNoWhite:[45:17] Found expr:[45:4->45:18] -JSX 45:5] prop[45:6->45:10]=...[45:11->45:16] k[45:17->45:18]=...[45:17->45:18]> _children:None -posCursor:[45:18] posNoWhite:[45:17] Found expr:[45:17->45:18] -Pexp_ident k:[45:17->45:18] +Complete tests/src/Jsx.res 43:18 +posCursor:[43:18] posNoWhite:[43:17] Found expr:[43:4->43:18] +JSX 43:5] prop[43:6->43:10]=...[43:11->43:16] k[43:17->43:18]=...[43:17->43:18]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -167,11 +147,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 48:16 -posCursor:[48:16] posNoWhite:[48:15] Found expr:[48:4->48:16] -JSX 48:5] prop[48:6->48:10]=...[48:11->48:14] k[48:15->48:16]=...[48:15->48:16]> _children:None -posCursor:[48:16] posNoWhite:[48:15] Found expr:[48:15->48:16] -Pexp_ident k:[48:15->48:16] +Complete tests/src/Jsx.res 46:16 +posCursor:[46:16] posNoWhite:[46:15] Found expr:[46:4->46:16] +JSX 46:5] prop[46:6->46:10]=...[46:11->46:14] k[46:15->46:16]=...[46:15->46:16]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -181,11 +159,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 51:27 -posCursor:[51:27] posNoWhite:[51:26] Found expr:[51:4->51:27] -JSX 51:5] prop[51:6->51:10]=...[51:11->51:25] k[51:26->51:27]=...[51:26->51:27]> _children:None -posCursor:[51:27] posNoWhite:[51:26] Found expr:[51:26->51:27] -Pexp_ident k:[51:26->51:27] +Complete tests/src/Jsx.res 49:27 +posCursor:[49:27] posNoWhite:[49:26] Found expr:[49:4->49:27] +JSX 49:5] prop[49:6->49:10]=...[49:11->49:25] k[49:26->49:27]=...[49:26->49:27]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -195,11 +171,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 54:38 -posCursor:[54:38] posNoWhite:[54:37] Found expr:[54:4->54:38] -JSX 54:5] prop[54:6->54:10]=...[54:11->54:36] k[54:37->54:38]=...[54:37->54:38]> _children:None -posCursor:[54:38] posNoWhite:[54:37] Found expr:[54:37->54:38] -Pexp_ident k:[54:37->54:38] +Complete tests/src/Jsx.res 52:38 +posCursor:[52:38] posNoWhite:[52:37] Found expr:[52:4->52:38] +JSX 52:5] prop[52:6->52:10]=...[52:11->52:36] k[52:37->52:38]=...[52:37->52:38]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -209,11 +183,9 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Complete tests/src/Jsx.res 57:25 -posCursor:[57:25] posNoWhite:[57:24] Found expr:[57:4->57:25] -JSX 57:5] prop[57:6->57:10]=...[57:11->57:23] k[57:24->57:25]=...[57:24->57:25]> _children:None -posCursor:[57:25] posNoWhite:[57:24] Found expr:[57:24->57:25] -Pexp_ident k:[57:24->57:25] +Complete tests/src/Jsx.res 55:25 +posCursor:[55:25] posNoWhite:[55:24] Found expr:[55:4->55:25] +JSX 55:5] prop[55:6->55:10]=...[55:11->55:23] k[55:24->55:25]=...[55:24->55:25]> _children:None Completable: Cjsx([M], k, [prop, k]) [{ "label": "key", @@ -223,14 +195,12 @@ Completable: Cjsx([M], k, [prop, k]) "documentation": null }] -Definition tests/src/Jsx.res 60:11 +Definition tests/src/Jsx.res 58:11 {"uri": "Component.res", "range": {"start": {"line": 1, "character": 4}, "end": {"line": 1, "character": 8}}} -Complete tests/src/Jsx.res 70:10 -posCursor:[70:10] posNoWhite:[70:9] Found expr:[70:4->70:10] -JSX 70:7] al[70:8->70:10]=...[70:8->70:10]> _children:None -posCursor:[70:10] posNoWhite:[70:9] Found expr:[70:8->70:10] -Pexp_ident al:[70:8->70:10] +Complete tests/src/Jsx.res 68:10 +posCursor:[68:10] posNoWhite:[68:9] Found expr:[68:4->68:10] +JSX 68:7] al[68:8->68:10]=...[68:8->68:10]> _children:None Completable: Cjsx([Ext], al, [al]) [{ "label": "align", @@ -240,19 +210,15 @@ Completable: Cjsx([Ext], al, [al]) "documentation": null }] -Complete tests/src/Jsx.res 73:11 -posCursor:[73:11] posNoWhite:[73:10] Found expr:[73:4->73:11] -JSX 73:5] first[73:6->73:11]=...[73:6->73:11]> _children:None -posCursor:[73:11] posNoWhite:[73:10] Found expr:[73:6->73:11] -Pexp_ident first:[73:6->73:11] +Complete tests/src/Jsx.res 71:11 +posCursor:[71:11] posNoWhite:[71:10] Found expr:[71:4->71:11] +JSX 71:5] first[71:6->71:11]=...[71:6->71:11]> _children:None Completable: Cjsx([M], first, [first]) [] -Complete tests/src/Jsx.res 76:16 -posCursor:[76:16] posNoWhite:[76:15] Found expr:[76:4->76:16] -JSX 76:5] first[76:6->76:11]=...[76:12->76:14] k[76:15->76:16]=...[76:15->76:16]> _children:None -posCursor:[76:16] posNoWhite:[76:15] Found expr:[76:15->76:16] -Pexp_ident k:[76:15->76:16] +Complete tests/src/Jsx.res 74:16 +posCursor:[74:16] posNoWhite:[74:15] Found expr:[74:4->74:16] +JSX 74:5] first[74:6->74:11]=...[74:12->74:14] k[74:15->74:16]=...[74:15->74:16]> _children:None Completable: Cjsx([M], k, [first, k]) [{ "label": "key", @@ -262,11 +228,9 @@ Completable: Cjsx([M], k, [first, k]) "documentation": null }] -Complete tests/src/Jsx.res 79:23 -posCursor:[79:23] posNoWhite:[79:22] Found expr:[79:4->79:23] -JSX 79:5] first[79:6->79:11]=...[79:19->79:21] k[79:22->79:23]=...[79:22->79:23]> _children:None -posCursor:[79:23] posNoWhite:[79:22] Found expr:[79:22->79:23] -Pexp_ident k:[79:22->79:23] +Complete tests/src/Jsx.res 77:23 +posCursor:[77:23] posNoWhite:[77:22] Found expr:[77:4->77:23] +JSX 77:5] first[77:6->77:11]=...[77:19->77:21] k[77:22->77:23]=...[77:22->77:23]> _children:None Completable: Cjsx([M], k, [first, k]) [{ "label": "key", @@ -276,22 +240,20 @@ Completable: Cjsx([M], k, [first, k]) "documentation": null }] -Complete tests/src/Jsx.res 82:6 -posCursor:[82:6] posNoWhite:[82:5] Found expr:[82:4->87:69] -Pexp_apply ...[85:20->85:21] (...[82:4->85:19], ...[86:2->87:69]) -posCursor:[82:6] posNoWhite:[82:5] Found expr:[82:4->85:19] -JSX 82:5] > _children:82:5 -posCursor:[82:6] posNoWhite:[82:5] Found expr:[82:5->85:20] -Pexp_construct :::[85:0->85:20] [85:0->85:20] -posCursor:[82:6] posNoWhite:[82:5] Found expr:__ghost__[82:5->85:20] -Pexp_construct []:__ghost__[82:5->85:20] None +Complete tests/src/Jsx.res 80:6 +posCursor:[80:6] posNoWhite:[80:5] Found expr:[80:4->85:69] +Pexp_apply ...[83:20->83:21] (...[80:4->83:19], ...[84:2->85:69]) +posCursor:[80:6] posNoWhite:[80:5] Found expr:[80:4->83:19] +JSX 80:5] > _children:80:5 +posCursor:[80:6] posNoWhite:[80:5] Found expr:[80:5->83:20] +Pexp_construct :::[83:0->83:20] [83:0->83:20] +posCursor:[80:6] posNoWhite:[80:5] Found expr:__ghost__[80:5->83:20] +Pexp_construct []:__ghost__[80:5->83:20] None [] -Complete tests/src/Jsx.res 91:16 -posCursor:[91:16] posNoWhite:[91:15] Found expr:[91:4->91:16] -JSX 91:16] > _children:None -posCursor:[91:16] posNoWhite:[91:15] Found expr:[91:4->91:16] -Pexp_ident WithChildren.createElement:[91:4->91:16] +Complete tests/src/Jsx.res 89:16 +posCursor:[89:16] posNoWhite:[89:15] Found expr:[89:4->89:16] +JSX 89:16] > _children:None Completable: Cpath Module[WithChildren] [{ "label": "WithChildren", @@ -301,11 +263,9 @@ Completable: Cpath Module[WithChildren] "documentation": null }] -Complete tests/src/Jsx.res 93:18 -posCursor:[93:18] posNoWhite:[93:17] Found expr:[93:4->93:18] -JSX 93:16] n[93:17->93:18]=...[93:17->93:18]> _children:None -posCursor:[93:18] posNoWhite:[93:17] Found expr:[93:17->93:18] -Pexp_ident n:[93:17->93:18] +Complete tests/src/Jsx.res 91:18 +posCursor:[91:18] posNoWhite:[91:17] Found expr:[91:4->91:18] +JSX 91:16] n[91:17->91:18]=...[91:17->91:18]> _children:None Completable: Cjsx([WithChildren], n, [n]) [{ "label": "name", @@ -315,9 +275,9 @@ Completable: Cjsx([WithChildren], n, [n]) "documentation": null }] -Complete tests/src/Jsx.res 96:18 -posCursor:[96:18] posNoWhite:[96:17] Found type:[96:11->96:18] -Ptyp_constr React.e:[96:11->96:18] +Complete tests/src/Jsx.res 94:18 +posCursor:[94:18] posNoWhite:[94:17] Found type:[94:11->94:18] +Ptyp_constr React.e:[94:11->94:18] Completable: Cpath Type[React, e] [{ "label": "element", @@ -327,9 +287,9 @@ Completable: Cpath Type[React, e] "documentation": null }] -Complete tests/src/Jsx.res 98:20 -posCursor:[98:20] posNoWhite:[98:19] Found type:[98:11->101:6] -Ptyp_constr ReactDOMR:[98:11->101:6] +Complete tests/src/Jsx.res 96:20 +posCursor:[96:20] posNoWhite:[96:19] Found type:[96:11->99:6] +Ptyp_constr ReactDOMR:[96:11->99:6] Completable: Cpath Type[ReactDOMR] [{ "label": "ReactDOMRe", @@ -339,20 +299,17 @@ Completable: Cpath Type[ReactDOMR] "documentation": null }] -Complete tests/src/Jsx.res 104:21 -posCursor:[104:21] posNoWhite:[104:20] Found expr:[104:13->104:21] -Pexp_apply ...[104:15->104:16] (...[104:13->104:14], ...[104:17->104:21]) -posCursor:[104:21] posNoWhite:[104:20] Found expr:[104:17->104:21] -Pexp_field [104:17->104:18] th:[104:19->104:21] +Complete tests/src/Jsx.res 102:21 +posCursor:[102:21] posNoWhite:[102:20] Found expr:[102:13->102:21] +Pexp_apply ...[102:15->102:16] (...[102:13->102:14], ...[102:17->102:21]) +posCursor:[102:21] posNoWhite:[102:20] Found expr:[102:17->102:21] +Pexp_field [102:17->102:18] th:[102:19->102:21] Completable: Cpath Value[x].th [] -Complete tests/src/Jsx.res 108:28 -posCursor:[108:28] posNoWhite:[108:27] Found expr:[108:11->113:3] -Pexp_ident DefineSomeFields.:[108:11->113:3] -Id breaks up. New path:DefineSomeFields. -posCursor:[108:28] posNoWhite:[108:27] Found expr:[0:-1->113:70] -Pexp_apply ...[113:6->113:7] (...[113:8->113:70]) +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] Completable: Cpath Value[DefineSomeFields, ""] [{ "label": "thisValue", @@ -362,11 +319,11 @@ Completable: Cpath Value[DefineSomeFields, ""] "documentation": null }] -Complete tests/src/Jsx.res 110:36 -posCursor:[110:36] posNoWhite:[110:35] Found expr:[110:11->110:36] -Pexp_apply ...[110:13->110:14] (...[110:11->110:12], ...[110:15->110:36]) -posCursor:[110:36] posNoWhite:[110:35] Found expr:[110:15->110:36] -Pexp_field [110:15->110:16] DefineSomeFields.th:[110:17->110:36] +Complete tests/src/Jsx.res 108:36 +posCursor:[108:36] posNoWhite:[108:35] Found expr:[108:11->108:36] +Pexp_apply ...[108:13->108:14] (...[108:11->108:12], ...[108:15->108:36]) +posCursor:[108:36] posNoWhite:[108:35] Found expr:[108:15->108:36] +Pexp_field [108:15->108:16] DefineSomeFields.th:[108:17->108:36] Completable: Cpath Module[DefineSomeFields].th [{ "label": "thisField", @@ -382,11 +339,11 @@ Completable: Cpath Module[DefineSomeFields].th "documentation": null }] -Complete tests/src/Jsx.res 124:20 -posCursor:[124:20] posNoWhite:[124:19] Found expr:[123:3->127:4] -JSX 123:6] x[124:5->124:6]=...[124:7->124:20] name[126:4->126:8]=...[126:9->126:11]> _children:127:2 -posCursor:[124:20] posNoWhite:[124:19] Found expr:[124:7->124:20] -Pexp_ident Outer.Inner.h:[124:7->124:20] +Complete tests/src/Jsx.res 122:20 +posCursor:[122:20] posNoWhite:[122:19] Found expr:[121:3->125:4] +JSX 121:6] x[122:5->122:6]=...[122:7->122:20] name[124:4->124:8]=...[124:9->124:11]> _children:125:2 +posCursor:[122:20] posNoWhite:[122:19] Found expr:[122:7->122:20] +Pexp_ident Outer.Inner.h:[122:7->122:20] Completable: Cpath Value[Outer, Inner, h] [{ "label": "hello", @@ -396,12 +353,11 @@ Completable: Cpath Value[Outer, Inner, h] "documentation": null }] -Complete tests/src/Jsx.res 131:19 -posCursor:[131:19] posNoWhite:[131:18] Found expr:[130:3->133:9] -JSX 130:6] x[131:5->131:6]=...[131:7->133:8]> _children:None -posCursor:[131:19] posNoWhite:[131:18] Found expr:[131:7->133:8] -Pexp_ident Outer.Inner.name:[131:7->133:8] -Id breaks up. New path:Outer.Inner. +Complete tests/src/Jsx.res 129:19 +posCursor:[129:19] posNoWhite:[129:18] Found expr:[128:3->131:9] +JSX 128:6] x[129:5->129:6]=...[129:7->131:8]> _children:None +posCursor:[129:19] posNoWhite:[129:18] Found expr:[129:7->131:8] +Pexp_ident Outer.Inner.:[129:7->131:8] Completable: Cpath Value[Outer, Inner, ""] [{ "label": "hello", @@ -411,8 +367,32 @@ Completable: Cpath Value[Outer, Inner, ""] "documentation": null }] -Complete tests/src/Jsx.res 138:7 -posCursor:[138:7] posNoWhite:[138:6] Found expr:[137:3->140:9] -JSX 137:6] x[138:5->138:6]=...[140:4->140:8]> _children:None +Complete tests/src/Jsx.res 136:7 +posCursor:[136:7] posNoWhite:[136:6] Found expr:[135:3->138:9] +JSX 135:6] x[136:5->136:6]=...[138:4->138:8]> _children:None [] +Complete tests/src/Jsx.res 150:21 +posCursor:[150:21] posNoWhite:[150:20] Found expr:[150:12->150:32] +JSX 150:21] name[150:22->150:26]=...[150:27->150:29]> _children:150:30 +Completable: Cpath Module[Nested, Co] +[{ + "label": "Comp", + "kind": 9, + "tags": [], + "detail": "module", + "documentation": null + }] + +Complete tests/src/Jsx.res 153:19 +posCursor:[153:19] posNoWhite:[153:18] Found expr:[153:12->153:25] +JSX 153:24] > _children:None +Completable: Cpath Module[Nested, ""] +[{ + "label": "Comp", + "kind": 9, + "tags": [], + "detail": "module", + "documentation": null + }] + diff --git a/analysis/tests/src/expected/RecordCompletion.res.txt b/analysis/tests/src/expected/RecordCompletion.res.txt index f38821afc..ea814ef52 100644 --- a/analysis/tests/src/expected/RecordCompletion.res.txt +++ b/analysis/tests/src/expected/RecordCompletion.res.txt @@ -1,7 +1,5 @@ Complete tests/src/RecordCompletion.res 8:9 posCursor:[8:9] posNoWhite:[8:8] Found expr:[8:3->8:9] -posCursor:[8:9] posNoWhite:[8:8] Found expr:[8:8->8:9] -Pexp_ident m:[8:8->8:9] Completable: Cpath Value[t].n->m [{ "label": "Js.Array2.mapi", @@ -19,8 +17,6 @@ Completable: Cpath Value[t].n->m Complete tests/src/RecordCompletion.res 11:13 posCursor:[11:13] posNoWhite:[11:12] Found expr:[11:3->11:13] -posCursor:[11:13] posNoWhite:[11:12] Found expr:[11:12->11:13] -Pexp_ident m:[11:12->11:13] Completable: Cpath Value[t2].n2.n->m [{ "label": "Js.Array2.mapi", @@ -37,8 +33,20 @@ Completable: Cpath Value[t2].n2.n->m }] Complete tests/src/RecordCompletion.res 19:7 -posCursor:[19:7] posNoWhite:[19:6] Found expr:[19:3->22:0] -Pexp_field [19:3->19:4] R.:[19:5->22:0] +posCursor:[19:7] posNoWhite:[19:6] Found expr:[19:3->25:0] +Pexp_field [19:3->19:4] R.:[19:5->25:0] +Completable: Cpath Module[R]."" +[{ + "label": "name", + "kind": 5, + "tags": [], + "detail": "name: string\n\ntype t = {name: string}", + "documentation": null + }] + +Complete tests/src/RecordCompletion.res 22:7 +posCursor:[22:7] posNoWhite:[22:6] Found expr:[22:3->22:10] +Pexp_field [22:3->22:4] R.xx:[22:5->22:10] Completable: Cpath Module[R]."" [{ "label": "name",