Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
ef2f7bf
Experiment with using the parser for autocomplete.
cristianoc Apr 9, 2022
b04e013
Find the location of prop labels in JSX.
cristianoc Apr 11, 2022
def4820
Show completable in tests.
cristianoc Apr 12, 2022
74e67d3
Print the component name.
cristianoc Apr 12, 2022
5e7d735
Print loc of component name and children.
cristianoc Apr 12, 2022
e854c46
Check if children exist.
cristianoc Apr 12, 2022
c9e5bda
refactor
cristianoc Apr 12, 2022
d1ea3ae
Debug.
cristianoc Apr 12, 2022
c86f7d1
Print prop range.
cristianoc Apr 12, 2022
1a0ebf2
Check differences on JSX behaviour.
cristianoc Apr 12, 2022
334b8c9
Take out code for backwards parsing jsx.
cristianoc Apr 12, 2022
80ea375
Tweak case with children.
cristianoc Apr 12, 2022
d973ad6
Don't fire unless after component name.
cristianoc Apr 12, 2022
9ec656b
Extract locations of labels in function application.
cristianoc Apr 13, 2022
2a19fc3
Tweak debug printing of positions and locations.
cristianoc Apr 13, 2022
4bb1c4b
refactor
cristianoc Apr 13, 2022
dd4cf1f
Refactor pos out of Utils.
cristianoc Apr 13, 2022
acf5344
Take label completion from the parser.
cristianoc Apr 13, 2022
f8b5b48
Remove backward parser for function calls.
cristianoc Apr 13, 2022
e423bbe
Add parser-base autocompletion for pipe.
cristianoc Apr 13, 2022
d8c45ea
Remove backwards parser for pipe.
cristianoc Apr 13, 2022
7229e85
Parser: fix location of foo["abc"]
cristianoc Apr 13, 2022
1299439
Use the parser for object completion.
cristianoc Apr 13, 2022
76269e5
Remove backwards parser for objects.
cristianoc Apr 13, 2022
27cb4a2
Use parser for common paths.
cristianoc Apr 14, 2022
49b85ae
Remove backwards parsing of common paths.
cristianoc Apr 14, 2022
88bf40b
Don't suggest a prop name if it's already used after the cursor.
cristianoc Apr 14, 2022
214ba80
Add example of toplevel module completion.
cristianoc Apr 14, 2022
4fefc26
Handle toplevel module completion.
cristianoc Apr 14, 2022
273334e
Add example of component with children.
cristianoc Apr 14, 2022
bef6e0e
Don't suggest. "children" as prop autocompletion.
cristianoc Apr 14, 2022
46efb43
Example of prop completion in the presence of children.
cristianoc Apr 14, 2022
dc337bf
Fix case where children is not the last prop.
cristianoc Apr 14, 2022
6a81b38
Add another test that triggers the last children fix.
cristianoc Apr 14, 2022
2926430
Add example that tests local opens.
cristianoc Apr 14, 2022
dfb0ca3
Example with nested opens.
cristianoc Apr 14, 2022
b566052
Compute the open's in scope using the AST iterator.
cristianoc Apr 14, 2022
314e770
Remove code that parses backwards to find open's.
cristianoc Apr 14, 2022
27cef12
cleanup
cristianoc Apr 14, 2022
a1c5bf6
Get attributes from the parser.
cristianoc Apr 14, 2022
21c5984
Remove backwards parser for attributes.
cristianoc Apr 14, 2022
bfb7808
Autocomplete for types.
cristianoc Apr 15, 2022
c1e2be5
refactor
cristianoc Apr 15, 2022
4a01260
Support interface files.
cristianoc Apr 15, 2022
e4d93c7
Types in value declarations.
cristianoc Apr 15, 2022
3665736
Complete module prefix of type path.
cristianoc Apr 15, 2022
b2377ec
Filter completion by kind: Type or Value.
cristianoc Apr 15, 2022
2d19437
In jsx, only complete with modules.
cristianoc Apr 15, 2022
6fa3bd5
Contextual completion of fields.
cristianoc Apr 15, 2022
78587a7
Refactor.
cristianoc Apr 15, 2022
f490954
Add support for module ids.
cristianoc Apr 16, 2022
13119da
Refactor
cristianoc Apr 16, 2022
fc2593d
Clean up extensions.
cristianoc Apr 17, 2022
4473d27
cleanup
cristianoc Apr 17, 2022
2470fe6
id shadowing from opens
cristianoc Apr 17, 2022
478f0d1
More examples of shadowing.
cristianoc Apr 17, 2022
4f96549
Example of qualified record access.
cristianoc Apr 17, 2022
cdca516
Introduce generalized completable Cpath
cristianoc Apr 17, 2022
ed84a7d
Fix qualified field access.
cristianoc Apr 17, 2022
70a6635
Tweak Cpath: completion context on the id.
cristianoc Apr 17, 2022
b9a3d08
rename
cristianoc Apr 17, 2022
3869bca
cleanup
cristianoc Apr 17, 2022
1f4ffeb
refactor
cristianoc Apr 17, 2022
b7ec8ac
No QualifiedRecordAccess required.
cristianoc Apr 17, 2022
7010442
refactor
cristianoc Apr 17, 2022
67bcf27
rename
cristianoc Apr 17, 2022
bcc594c
refactor
cristianoc Apr 17, 2022
810c168
refactor
cristianoc Apr 17, 2022
7c78581
rename and fix lowecase ascii
cristianoc Apr 17, 2022
8cecc55
move
cristianoc Apr 17, 2022
5d703b1
refactor
cristianoc Apr 17, 2022
32dbfcf
cleanup
cristianoc Apr 17, 2022
161f692
cleanup
cristianoc Apr 17, 2022
c84f364
refactor
cristianoc Apr 17, 2022
e04bbb7
no dedup
cristianoc Apr 17, 2022
d18ca4d
refactor
cristianoc Apr 17, 2022
6c960d7
refactor
cristianoc Apr 17, 2022
1757507
refactor
cristianoc Apr 17, 2022
e5aab9f
refactor
cristianoc Apr 17, 2022
0eaca9b
refactor
cristianoc Apr 17, 2022
204eda7
refactor
cristianoc Apr 18, 2022
a2fdc1c
Add env to completions.
cristianoc Apr 18, 2022
5377b91
refactor
cristianoc Apr 18, 2022
faf7a1a
Use new backend for CPId.
cristianoc Apr 18, 2022
7e45bcc
Compile field accesses to the new bakend.
cristianoc Apr 18, 2022
18283ea
Remove Cdotpath and associated dead code.
cristianoc Apr 18, 2022
49544fa
Handle object access with the new back-end.
cristianoc Apr 18, 2022
f039fd3
Remove now unused Cobj.
cristianoc Apr 18, 2022
6957ac1
Add pipe to the new back-end.
cristianoc Apr 18, 2022
bdf9526
Remove pipe from old backend.
cristianoc Apr 18, 2022
37e2d1b
Generalize front-end to match new back-end.
cristianoc Apr 18, 2022
a8c2313
Add example combining all the forms of completion, nested.
cristianoc Apr 18, 2022
3076bb8
clean up output
cristianoc Apr 18, 2022
ec52f8c
labels on Win newlines
cristianoc Apr 18, 2022
0882ded
First step towards scope.
cristianoc Apr 19, 2022
69f7e8a
Populate scope with values.
cristianoc Apr 20, 2022
03c5f27
rename
cristianoc Apr 20, 2022
67479f1
prepare insertion point for new local value completion.
cristianoc Apr 20, 2022
aadd9e1
local constructor infra
cristianoc Apr 20, 2022
dc4c16e
There's no local completion for fields.
cristianoc Apr 20, 2022
bb5d6e2
rename
cristianoc Apr 20, 2022
d7c402e
tweak debug print
cristianoc Apr 20, 2022
1d9dab9
rename
cristianoc Apr 20, 2022
f1210f3
Add type declarations and constructors to the scope.
cristianoc Apr 20, 2022
02e671b
refactor
cristianoc Apr 20, 2022
d55a95f
Start to push duplicate name check everywhere.
cristianoc Apr 20, 2022
c250cb8
Add example that shows repeated results with shadowed ids.
cristianoc Apr 20, 2022
9c6fb25
Use scope-based autocomplete for values and constructors.
cristianoc Apr 20, 2022
39425f6
log
cristianoc Apr 20, 2022
ace661a
push filtering inside findAllCompletions
cristianoc Apr 20, 2022
f2c95da
remove dead filtering code
cristianoc Apr 20, 2022
7307fa8
Not need to prioritize/postprocess anymore.
cristianoc Apr 20, 2022
2ca8151
No need to extentLoc in completion.
cristianoc Apr 20, 2022
ecf4e15
Handle scope for modules.
cristianoc Apr 20, 2022
c75b2c5
remove dead code
cristianoc Apr 20, 2022
b3dbab6
rename
cristianoc Apr 20, 2022
96c8263
rename
cristianoc Apr 20, 2022
5718ef9
refactor
cristianoc Apr 20, 2022
26094c0
top-level logic for getEnvWithOpens
cristianoc Apr 20, 2022
2c8df45
Use scope to find local module in path resolution.
cristianoc Apr 20, 2022
cce0d22
Remove old code to approximate scope.
cristianoc Apr 20, 2022
a457188
Remove code to process extent.
cristianoc Apr 20, 2022
6e856a8
Add example showing how parser recovery could build id too eagerly.
cristianoc Apr 20, 2022
5cbdcfa
Fix issue with "." and parser recovery.
cristianoc Apr 20, 2022
69927e4
Allow autocomplete on blank.
cristianoc Apr 20, 2022
224f4b7
Fix local completions for types and modules.
cristianoc Apr 20, 2022
511faa8
Fix issue whith completing x= in JSX.
cristianoc Apr 21, 2022
39c3cef
Clean up parser recovery.
cristianoc Apr 22, 2022
c342b8e
restore normal formatting logic
cristianoc Apr 22, 2022
20f9c3d
Move completion code to separate file.
cristianoc Apr 22, 2022
64ec49a
rename
cristianoc Apr 22, 2022
62c2183
restore check on formatting
cristianoc Apr 22, 2022
c927bbf
Move completable to own module.
cristianoc Apr 22, 2022
882b862
tweak order of fields
cristianoc Apr 23, 2022
6526a62
rename
cristianoc Apr 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Check if children exist.
  • Loading branch information
cristianoc committed Apr 12, 2022
commit e854c4625a87c5a2bc3dc55084fdc5ec4557cf5f
92 changes: 45 additions & 47 deletions analysis/src/Commands.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ let posInLoc ~pos ~loc =
Utils.tupleOfLexing loc.Location.loc_start <= pos
&& pos < Utils.tupleOfLexing loc.loc_end

let extractJsxProps ~text (expr : Parsetree.expression) =
let extractJsxProps ~text ~(eComp : Parsetree.expression) ~args =
let rec extractLabelPos ~pos ~i str =
if i < String.length str then
match str.[i] with
Expand All @@ -15,48 +15,41 @@ let extractJsxProps ~text (expr : Parsetree.expression) =
| _ -> None
else None
in
match expr.pexp_desc with
| Pexp_apply (eComp, args) ->
(* To check if tha prop is punned, take the string between the last prop
(or the end of e) and the expr in the arg.
If it's whitespace only, then it's a punned <C prop />.
If it's "?" then it's a punned optional <C ?prop />.
Otherwise it should be "id =" perhaps followed by "?".
*)
let rec processProps ~lastOffset ~lastPos ~acc args =
match args with
| (Asttypes.Labelled "children", {Parsetree.pexp_loc}) :: _ ->
(List.rev acc, pexp_loc)
| ((Labelled s | Optional s), (eProp : Parsetree.expression)) :: rest -> (
let ePosStart = Utils.tupleOfLexing eProp.pexp_loc.loc_start in
let ePosEnd = Utils.tupleOfLexing eProp.pexp_loc.loc_end in
match
( PartialParser.positionToOffset text ePosStart,
PartialParser.positionToOffset text ePosEnd )
with
| Some offsetStart, Some offsetEnd ->
let label = String.sub text lastOffset (offsetStart - lastOffset) in
let labelPos =
match extractLabelPos ~pos:lastPos ~i:0 label with
| Some pos -> pos
| None -> (* Must be punned *) ePosStart
in
processProps
~acc:((s, labelPos, eProp) :: acc)
~lastOffset:offsetEnd ~lastPos:ePosEnd rest
| _ -> assert false)
| _ -> (* should not happen *) ([], Location.none)
in
let posAfterCompName = Utils.tupleOfLexing eComp.pexp_loc.loc_end in
let offsetAfterCompName =
match PartialParser.positionToOffset text posAfterCompName with
| None -> assert false
| Some offset -> offset
in
args
|> processProps ~lastOffset:offsetAfterCompName ~lastPos:posAfterCompName
~acc:[]
| _ -> (* should not happen *) ([], Location.none)
let rec processProps ~lastOffset ~lastPos ~acc args =
match args with
| (Asttypes.Labelled "children", {Parsetree.pexp_loc}) :: _ ->
( List.rev acc,
if pexp_loc.loc_ghost then None
else Some (Utils.tupleOfLexing pexp_loc.loc_start) )
| ((Labelled s | Optional s), (eProp : Parsetree.expression)) :: rest -> (
let ePosStart = Utils.tupleOfLexing eProp.pexp_loc.loc_start in
let ePosEnd = Utils.tupleOfLexing eProp.pexp_loc.loc_end in
match
( PartialParser.positionToOffset text ePosStart,
PartialParser.positionToOffset text ePosEnd )
with
| Some offsetStart, Some offsetEnd ->
let label = String.sub text lastOffset (offsetStart - lastOffset) in
let labelPos =
match extractLabelPos ~pos:lastPos ~i:0 label with
| Some pos -> pos
| None -> (* Must be punned *) ePosStart
in
processProps
~acc:((s, labelPos, eProp) :: acc)
~lastOffset:offsetEnd ~lastPos:ePosEnd rest
| _ -> assert false)
| _ -> (* should not happen *) ([], None)
in
let posAfterCompName = Utils.tupleOfLexing eComp.pexp_loc.loc_end in
let offsetAfterCompName =
match PartialParser.positionToOffset text posAfterCompName with
| None -> assert false
| Some offset -> offset
in
args
|> processProps ~lastOffset:offsetAfterCompName ~lastPos:posAfterCompName
~acc:[]

let completionWithParser ~debug ~path ~posCursor ~currentFile ~textOpt =
let text = match textOpt with Some text -> text | None -> assert false in
Expand Down Expand Up @@ -99,13 +92,18 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~textOpt =

match expr.pexp_desc with
| Pexp_apply
({pexp_desc = Pexp_ident {txt = compName; loc = compNameLoc}}, _)
( ({pexp_desc = Pexp_ident {txt = compName; loc = compNameLoc}} as
eComp),
args )
when Res_parsetree_viewer.isJsxExpression expr ->
let props, childrenLoc = extractJsxProps ~text expr in
Printf.printf "JSX %s:%s children:%s %s\n"
let props, childrenPosStartOpt = extractJsxProps ~text ~eComp ~args in
Printf.printf "JSX %s:%s childrenStart:%s %s\n"
(compName |> flattenComponentName |> String.concat ",")
(SemanticTokens.locToString compNameLoc)
(SemanticTokens.locToString childrenLoc)
(match childrenPosStartOpt with
| None -> "None"
| Some childrenPosStart ->
SemanticTokens.posToString childrenPosStart)
(props
|> List.map (fun (lbl, lblPos, (eProp : Parsetree.expression)) ->
Printf.sprintf "(%s:%s e:%s)" lbl
Expand Down
4 changes: 2 additions & 2 deletions analysis/tests/src/expected/Completion.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ Completable: Cdotpath([Js, Dict, u])

Complete tests/src/Completion.res 50:2
posCursor:(51,28) posNoWhite:(51,27) Found expr:(51,13)->(51,28)
JSX O,Comp:(51,13)->(51,19) children:(0,-1)->(0,-1) (second:(51,20) e:(51,27)->(51,28))
JSX O,Comp:(51,13)->(51,19) childrenStart:None (second:(51,20) e:(51,27)->(51,28))
posCursor:(51,28) posNoWhite:(51,27) Found expr:(51,27)->(51,28)
Completable: Cdotpath([z])
[{
Expand All @@ -471,7 +471,7 @@ Completable: Cdotpath([z])

Complete tests/src/Completion.res 52:2
posCursor:(53,21) posNoWhite:(53,20) Found expr:(53,13)->(53,21)
JSX O,Comp:(53,13)->(53,19) children:(0,-1)->(0,-1) (z:(53,20) e:(53,20)->(53,21))
JSX O,Comp:(53,13)->(53,19) childrenStart:None (z:(53,20) e:(53,20)->(53,21))
posCursor:(53,21) posNoWhite:(53,20) Found expr:(53,20)->(53,21)
Completable: Cjsx([O, Comp], z, [])
[{
Expand Down
2 changes: 1 addition & 1 deletion analysis/tests/src/expected/Div.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Hover tests/src/Div.res 1:10

Complete tests/src/Div.res 3:3
posCursor:(4,15) posNoWhite:(4,14) Found expr:(4,2)->(4,15)
JSX div:(4,2)->(4,5) children:(0,-1)->(0,-1) (dangerous:(4,6) e:(4,6)->(4,15))
JSX div:(4,2)->(4,5) childrenStart:None (dangerous:(4,6) e:(4,6)->(4,15))
posCursor:(4,15) posNoWhite:(4,14) Found expr:(4,6)->(4,15)
Completable: Cjsx([div], dangerous, [])
[{
Expand Down
38 changes: 19 additions & 19 deletions analysis/tests/src/expected/Jsx.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Definition tests/src/Jsx.res 5:9

Complete tests/src/Jsx.res 7:2
posCursor:(8,14) posNoWhite:(8,12) Found expr:(8,2)->(8,13)
JSX M:(8,2)->(8,3) children:(0,-1)->(0,-1) (second:(8,4) e:(8,11)->(8,13))
JSX M:(8,2)->(8,3) childrenStart:None (second:(8,4) e:(8,11)->(8,13))
posCursor:(8,14) posNoWhite:(8,12) Found expr:(8,11)->(8,13)
Completable: Cjsx([M], "", [second])
[{
Expand All @@ -28,7 +28,7 @@ Completable: Cjsx([M], "", [second])

Complete tests/src/Jsx.res 9:2
posCursor:(10,18) posNoWhite:(10,17) Found expr:(10,2)->(10,18)
JSX M:(10,2)->(10,3) children:(0,-1)->(0,-1) (second:(10,4) e:(10,11)->(10,16)), (f:(10,17) e:(10,17)->(10,18))
JSX M:(10,2)->(10,3) childrenStart:None (second:(10,4) e:(10,11)->(10,16)), (f:(10,17) e:(10,17)->(10,18))
posCursor:(10,18) posNoWhite:(10,17) Found expr:(10,17)->(10,18)
Completable: Cjsx([M], f, [second])
[{
Expand All @@ -47,7 +47,7 @@ Completable: Cjsx([M], f, [second])

Complete tests/src/Jsx.res 11:2
posCursor:(12,12) posNoWhite:(12,10) Found expr:(12,10)->(12,11)
JSX M:(12,10)->(12,11) children:(0,-1)->(0,-1)
JSX M:(12,10)->(12,11) childrenStart:None
posCursor:(12,12) posNoWhite:(12,10) Found expr:(12,10)->(12,11)
Completable: Cjsx([M], "", [])
[{
Expand Down Expand Up @@ -78,7 +78,7 @@ Completable: Cjsx([M], "", [])

Complete tests/src/Jsx.res 18:2
posCursor:(19,17) posNoWhite:(19,16) Found expr:(19,2)->(19,17)
JSX M:(19,2)->(19,3) children:(0,-1)->(0,-1) (prop:(19,4) e:(19,10)->(19,14)), (k:(19,16) e:(19,16)->(19,17))
JSX M:(19,2)->(19,3) childrenStart:None (prop:(19,4) e:(19,10)->(19,14)), (k:(19,16) e:(19,16)->(19,17))
posCursor:(19,17) posNoWhite:(19,16) Found expr:(19,16)->(19,17)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -91,7 +91,7 @@ Completable: Cjsx([M], k, [prop])

Complete tests/src/Jsx.res 20:2
posCursor:(21,15) posNoWhite:(21,14) Found expr:(21,2)->(21,15)
JSX M:(21,2)->(21,3) children:(0,-1)->(0,-1) (prop:(21,4) e:(21,9)->(21,13)), (k:(21,14) e:(21,14)->(21,15))
JSX M:(21,2)->(21,3) childrenStart:None (prop:(21,4) e:(21,9)->(21,13)), (k:(21,14) e:(21,14)->(21,15))
posCursor:(21,15) posNoWhite:(21,14) Found expr:(21,14)->(21,15)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -104,7 +104,7 @@ Completable: Cjsx([M], k, [prop])

Complete tests/src/Jsx.res 22:2
posCursor:(23,19) posNoWhite:(23,18) Found expr:(23,2)->(23,19)
JSX M:(23,2)->(23,3) children:(0,-1)->(0,-1) (prop:(23,4) e:(23,9)->(23,17)), (k:(23,18) e:(23,18)->(23,19))
JSX M:(23,2)->(23,3) childrenStart:None (prop:(23,4) e:(23,9)->(23,17)), (k:(23,18) e:(23,18)->(23,19))
posCursor:(23,19) posNoWhite:(23,18) Found expr:(23,18)->(23,19)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -117,7 +117,7 @@ Completable: Cjsx([M], k, [prop])

Complete tests/src/Jsx.res 24:2
posCursor:(25,22) posNoWhite:(25,21) Found expr:(25,2)->(25,22)
JSX M:(25,2)->(25,3) children:(0,-1)->(0,-1) (prop:(25,4) e:(25,9)->(25,20)), (k:(25,21) e:(25,21)->(25,22))
JSX M:(25,2)->(25,3) childrenStart:None (prop:(25,4) e:(25,9)->(25,20)), (k:(25,21) e:(25,21)->(25,22))
posCursor:(25,22) posNoWhite:(25,21) Found expr:(25,21)->(25,22)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -130,7 +130,7 @@ Completable: Cjsx([M], k, [prop])

Complete tests/src/Jsx.res 26:2
posCursor:(27,16) posNoWhite:(27,15) Found expr:(27,2)->(27,16)
JSX M:(27,2)->(27,3) children:(0,-1)->(0,-1) (prop:(27,4) e:(27,10)->(27,14)), (k:(27,15) e:(27,15)->(27,16))
JSX M:(27,2)->(27,3) childrenStart:None (prop:(27,4) e:(27,10)->(27,14)), (k:(27,15) e:(27,15)->(27,16))
posCursor:(27,16) posNoWhite:(27,15) Found expr:(27,15)->(27,16)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -143,7 +143,7 @@ Completable: Cjsx([M], k, [prop])

Complete tests/src/Jsx.res 28:2
posCursor:(29,14) posNoWhite:(29,13) Found expr:(29,2)->(29,14)
JSX M:(29,2)->(29,3) children:(0,-1)->(0,-1) (prop:(29,4) e:(29,9)->(29,12)), (k:(29,13) e:(29,13)->(29,14))
JSX M:(29,2)->(29,3) childrenStart:None (prop:(29,4) e:(29,9)->(29,12)), (k:(29,13) e:(29,13)->(29,14))
posCursor:(29,14) posNoWhite:(29,13) Found expr:(29,13)->(29,14)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -156,7 +156,7 @@ Completable: Cjsx([M], k, [prop])

Complete tests/src/Jsx.res 30:2
posCursor:(31,15) posNoWhite:(31,14) Found expr:(31,2)->(31,15)
JSX M:(31,2)->(31,3) children:(0,-1)->(0,-1) (prop:(31,4) e:(31,9)->(31,13)), (k:(31,14) e:(31,14)->(31,15))
JSX M:(31,2)->(31,3) childrenStart:None (prop:(31,4) e:(31,9)->(31,13)), (k:(31,14) e:(31,14)->(31,15))
posCursor:(31,15) posNoWhite:(31,14) Found expr:(31,14)->(31,15)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -169,14 +169,14 @@ Completable: Cjsx([M], k, [prop])

Complete tests/src/Jsx.res 32:2
posCursor:(33,16) posNoWhite:(33,15) Found expr:(33,2)->(33,16)
JSX M:(33,2)->(33,3) children:(0,-1)->(0,-1) (prop:(33,4) e:(33,9)->(33,14)), (k:(33,15) e:(33,15)->(33,16))
JSX M:(33,2)->(33,3) childrenStart:None (prop:(33,4) e:(33,9)->(33,14)), (k:(33,15) e:(33,15)->(33,16))
posCursor:(33,16) posNoWhite:(33,15) Found expr:(33,15)->(33,16)
Completable: Cdotpath([k])
[]

Complete tests/src/Jsx.res 34:2
posCursor:(35,14) posNoWhite:(35,13) Found expr:(35,2)->(35,14)
JSX M:(35,2)->(35,3) children:(0,-1)->(0,-1) (prop:(35,4) e:(35,9)->(35,12)), (k:(35,13) e:(35,13)->(35,14))
JSX M:(35,2)->(35,3) childrenStart:None (prop:(35,4) e:(35,9)->(35,12)), (k:(35,13) e:(35,13)->(35,14))
posCursor:(35,14) posNoWhite:(35,13) Found expr:(35,13)->(35,14)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -189,7 +189,7 @@ Completable: Cjsx([M], k, [prop])

Complete tests/src/Jsx.res 36:2
posCursor:(37,25) posNoWhite:(37,24) Found expr:(37,2)->(37,25)
JSX M:(37,2)->(37,3) children:(0,-1)->(0,-1) (prop:(37,4) e:(37,9)->(37,23)), (k:(37,24) e:(37,24)->(37,25))
JSX M:(37,2)->(37,3) childrenStart:None (prop:(37,4) e:(37,9)->(37,23)), (k:(37,24) e:(37,24)->(37,25))
posCursor:(37,25) posNoWhite:(37,24) Found expr:(37,24)->(37,25)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -202,7 +202,7 @@ Completable: Cjsx([M], k, [prop])

Complete tests/src/Jsx.res 38:2
posCursor:(39,36) posNoWhite:(39,35) Found expr:(39,2)->(39,36)
JSX M:(39,2)->(39,3) children:(0,-1)->(0,-1) (prop:(39,4) e:(39,9)->(39,34)), (k:(39,35) e:(39,35)->(39,36))
JSX M:(39,2)->(39,3) childrenStart:None (prop:(39,4) e:(39,9)->(39,34)), (k:(39,35) e:(39,35)->(39,36))
posCursor:(39,36) posNoWhite:(39,35) Found expr:(39,35)->(39,36)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -215,7 +215,7 @@ Completable: Cjsx([M], k, [prop])

Complete tests/src/Jsx.res 40:2
posCursor:(41,23) posNoWhite:(41,22) Found expr:(41,2)->(41,23)
JSX M:(41,2)->(41,3) children:(0,-1)->(0,-1) (prop:(41,4) e:(41,9)->(41,21)), (k:(41,22) e:(41,22)->(41,23))
JSX M:(41,2)->(41,3) childrenStart:None (prop:(41,4) e:(41,9)->(41,21)), (k:(41,22) e:(41,22)->(41,23))
posCursor:(41,23) posNoWhite:(41,22) Found expr:(41,22)->(41,23)
Completable: Cjsx([M], k, [prop])
[{
Expand All @@ -231,7 +231,7 @@ Definition tests/src/Jsx.res 43:11

Complete tests/src/Jsx.res 52:2
posCursor:(53,8) posNoWhite:(53,7) Found expr:(53,2)->(53,8)
JSX Ext:(53,2)->(53,5) children:(0,-1)->(0,-1) (al:(53,6) e:(53,6)->(53,8))
JSX Ext:(53,2)->(53,5) childrenStart:None (al:(53,6) e:(53,6)->(53,8))
posCursor:(53,8) posNoWhite:(53,7) Found expr:(53,6)->(53,8)
Completable: Cjsx([Ext], al, [])
[{
Expand All @@ -244,7 +244,7 @@ Completable: Cjsx([Ext], al, [])

Complete tests/src/Jsx.res 54:2
posCursor:(55,10) posNoWhite:(55,8) Found expr:(55,2)->(55,9)
JSX M:(55,2)->(55,3) children:(0,-1)->(0,-1) (first:(55,4) e:(55,4)->(55,9))
JSX M:(55,2)->(55,3) childrenStart:None (first:(55,4) e:(55,4)->(55,9))
posCursor:(55,10) posNoWhite:(55,8) Found expr:(55,4)->(55,9)
Completable: Cjsx([M], "", [first])
[{
Expand All @@ -269,7 +269,7 @@ Completable: Cjsx([M], "", [first])

Complete tests/src/Jsx.res 56:2
posCursor:(57,14) posNoWhite:(57,13) Found expr:(57,2)->(57,14)
JSX M:(57,2)->(57,3) children:(0,-1)->(0,-1) (first:(57,4) e:(57,10)->(57,12)), (k:(57,13) e:(57,13)->(57,14))
JSX M:(57,2)->(57,3) childrenStart:None (first:(57,4) e:(57,10)->(57,12)), (k:(57,13) e:(57,13)->(57,14))
posCursor:(57,14) posNoWhite:(57,13) Found expr:(57,13)->(57,14)
Completable: Cjsx([M], k, [first])
[{
Expand All @@ -282,7 +282,7 @@ Completable: Cjsx([M], k, [first])

Complete tests/src/Jsx.res 58:2
posCursor:(59,21) posNoWhite:(59,20) Found expr:(59,2)->(59,21)
JSX M:(59,2)->(59,3) children:(0,-1)->(0,-1) (first:(59,4) e:(59,17)->(59,19)), (k:(59,20) e:(59,20)->(59,21))
JSX M:(59,2)->(59,3) childrenStart:None (first:(59,4) e:(59,17)->(59,19)), (k:(59,20) e:(59,20)->(59,21))
posCursor:(59,21) posNoWhite:(59,20) Found expr:(59,20)->(59,21)
Completable: Cjsx([M], k, [first])
[{
Expand Down