@@ -99,6 +99,20 @@ let rec ctxPathToString (ctxPath : ctxPath) =
99
99
| None -> " "
100
100
| Some ctxPath -> " [" ^ ctxPathToString ctxPath ^ " ]" )
101
101
102
+ module CompletionInstruction = struct
103
+ (* * This is the completion instruction, that's responsible for resolving something at
104
+ context path X *)
105
+ type t = CtxPath of ctxPath list
106
+
107
+ let ctxPath ctxPath = CtxPath ctxPath
108
+
109
+ let toString (c : t ) =
110
+ match c with
111
+ | CtxPath ctxPath ->
112
+ Printf. sprintf " CtxPath: %s"
113
+ (ctxPath |> List. map ctxPathToString |> String. concat " ->" )
114
+ end
115
+
102
116
type currentlyExpecting =
103
117
| Unit
104
118
| Type of ctxPath
@@ -141,9 +155,22 @@ module CompletionContext = struct
141
155
142
156
let withResetCurrentlyExpecting completionContext =
143
157
{completionContext with currentlyExpecting = [Unit ]}
158
+
159
+ let addCtxPathItem ctxPath completionContext =
160
+ {completionContext with ctxPath = ctxPath :: completionContext .ctxPath}
144
161
end
145
162
146
- type completionResult = (ctxPath list * CompletionContext .t ) option
163
+ module CompletionResult = struct
164
+ type t = (CompletionInstruction .t * CompletionContext .t ) option
165
+
166
+ let ctxPath (ctxPath : ctxPath ) (completionContext : CompletionContext.t ) =
167
+ let completionContext =
168
+ completionContext |> CompletionContext. addCtxPathItem ctxPath
169
+ in
170
+ Some
171
+ ( CompletionInstruction. ctxPath completionContext.ctxPath,
172
+ completionContext )
173
+ end
147
174
148
175
let flattenLidCheckDot ?(jsx = true ) ~(completionContext : CompletionContext.t )
149
176
(lid : Longident.t Location.loc ) =
@@ -292,14 +319,14 @@ let scopeModuleDeclaration ~scope (md : Parsetree.module_declaration) =
292
319
scope |> Scope. addModule ~name: md.pmd_name.txt ~loc: md.pmd_name.loc
293
320
294
321
let rec completeFromStructure ~completionContext
295
- (structure : Parsetree.structure ) : completionResult =
322
+ (structure : Parsetree.structure ) : CompletionResult.t =
296
323
(* TODO: Scope? *)
297
324
structure
298
325
|> Utils. findMap (fun (item : Parsetree.structure_item ) ->
299
326
completeStructureItem ~completion Context item)
300
327
301
328
and completeStructureItem ~(completionContext : CompletionContext.t )
302
- (item : Parsetree.structure_item ) : completionResult =
329
+ (item : Parsetree.structure_item ) : CompletionResult.t =
303
330
match item.pstr_desc with
304
331
| Pstr_value (recFlag , valueBindings ) ->
305
332
let scopeFromBindings =
@@ -334,7 +361,7 @@ and completeStructureItem ~(completionContext : CompletionContext.t)
334
361
(* These aren't relevant for ReScript *) None
335
362
336
363
and completeValueBinding ~completionContext (vb : Parsetree.value_binding ) :
337
- completionResult =
364
+ CompletionResult. t =
338
365
let scopeWithPattern =
339
366
scopePattern ~scope: completionContext.scope vb.pvb_pat
340
367
in
@@ -368,7 +395,7 @@ and completeValueBinding ~completionContext (vb : Parsetree.value_binding) :
368
395
else None
369
396
370
397
and completeExpr ~completionContext (expr : Parsetree.expression ) :
371
- completionResult =
398
+ CompletionResult. t =
372
399
let locHasPos loc =
373
400
loc
374
401
|> CursorPosition. locHasCursor
@@ -399,30 +426,27 @@ and completeExpr ~completionContext (expr : Parsetree.expression) :
399
426
ctxPath = CVariantPayload {itemNum = 0 } :: completionContext.ctxPath;
400
427
}
401
428
payloadExpr
402
- | Pexp_construct ({txt = Lident txt ; loc} , _ ) when loc |> locHasPos -> (
429
+ | Pexp_construct ({txt = Lident txt ; loc} , _ ) when loc |> locHasPos ->
403
430
(* A constructor, like: `Co` *)
404
- match completionContext.currentlyExpecting with
405
- | _ ->
406
- Some (CId ([txt], Module ) :: completionContext.ctxPath, completionContext)
407
- )
431
+ CompletionResult. ctxPath (CId ([txt], Module )) completionContext
408
432
| Pexp_construct (id , _ ) when id.loc |> locHasPos ->
409
433
(* A path, like: `Something.Co` *)
410
434
let lid = flattenLidCheckDot ~completion Context id in
411
- Some (CId (lid, Module ) :: completionContext.ctxPath, completionContext)
435
+ CompletionResult. ctxPath (CId (lid, Module )) completionContext
412
436
(* == RECORDS == *)
413
437
| Pexp_ident {txt = Lident prefix} when Utils. hasBraces expr.pexp_attributes
414
438
->
415
439
(* An ident with braces attribute corresponds to for example `{n}`.
416
440
Looks like a record but is parsed as an ident with braces. *)
417
441
let prefix = if prefix = " ()" then " " else prefix in
418
- Some
419
- ( CRecordField {prefix; seenFields = [] } :: completionContext.ctxPath,
420
- completionContext (* TODO: This isn't correct *) )
442
+ CompletionResult. ctxPath
443
+ (CRecordField {prefix; seenFields = [] })
444
+ completionContext
421
445
| Pexp_record ([] , _ ) when expr.pexp_loc |> locHasPos ->
422
446
(* No fields means we're in a record body `{}` *)
423
- Some
424
- ( CRecordField {prefix = " " ; seenFields = [] } :: completionContext.ctxPath,
425
- completionContext (* TODO: This isn't correct *) )
447
+ CompletionResult. ctxPath
448
+ (CRecordField {prefix = " " ; seenFields = [] })
449
+ completionContext
426
450
| Pexp_record (fields , _ ) when expr.pexp_loc |> locHasPos -> (
427
451
(* A record with fields *)
428
452
let seenFields =
@@ -441,25 +465,20 @@ and completeExpr ~completionContext (expr : Parsetree.expression) :
441
465
(* Cursor in field name, complete here *)
442
466
match fieldName with
443
467
| {txt = Lident prefix } ->
444
- Some
445
- ( CRecordField {prefix; seenFields}
446
- :: completionContext.ctxPath,
447
- completionContext (* TODO: This isn't correct *) )
468
+ CompletionResult. ctxPath
469
+ (CRecordField {prefix; seenFields})
470
+ completionContext
448
471
| fieldName ->
449
- Some
450
- ( CId (flattenLidCheckDot ~completion Context fieldName, Value )
451
- :: completionContext.ctxPath,
452
- completionContext )
472
+ CompletionResult. ctxPath
473
+ (CId (flattenLidCheckDot ~completion Context fieldName, Value ))
474
+ completionContext
453
475
else if locHasPos fieldExpr.pexp_loc then
454
476
completeExpr
455
477
~completion Context:
456
- {
457
- completionContext with
458
- ctxPath =
459
- CRecordField
460
- {prefix = fieldName.txt |> Longident. last; seenFields}
461
- :: completionContext.ctxPath;
462
- }
478
+ (CompletionContext. addCtxPathItem
479
+ (CRecordField
480
+ {prefix = fieldName.txt |> Longident. last; seenFields})
481
+ completionContext)
463
482
fieldExpr
464
483
else None )
465
484
in
@@ -485,22 +504,21 @@ and completeExpr ~completionContext (expr : Parsetree.expression) :
485
504
completionContext.positionContext.charBeforeNoWhitespace )
486
505
with
487
506
| Some fieldName , _ ->
488
- Some
489
- ( CRecordField {prefix = fieldName; seenFields}
490
- :: completionContext.ctxPath,
491
- completionContext (* TODO: This isn't correct *) )
507
+ CompletionResult. ctxPath
508
+ (CRecordField {prefix = fieldName; seenFields})
509
+ completionContext
492
510
| None , Some ',' ->
493
- Some
494
- ( CRecordField {prefix = " " ; seenFields} :: completionContext.ctxPath,
495
- completionContext (* TODO: This isn't correct *) )
511
+ CompletionResult. ctxPath
512
+ (CRecordField {prefix = " " ; seenFields})
513
+ completionContext
496
514
| _ -> None )
497
515
| fieldToComplete -> fieldToComplete)
498
516
(* == IDENTS == *)
499
517
| Pexp_ident lid ->
500
518
(* An identifier, like `aaa` *)
501
519
let lidPath = flattenLidCheckDot lid ~completion Context in
502
520
if lid.loc |> locHasPos then
503
- Some (CId (lidPath, Value ) :: completionContext.ctxPath, completionContext)
521
+ CompletionResult. ctxPath (CId (lidPath, Value )) completionContext
504
522
else None
505
523
| Pexp_let (_recFlag , _valueBindings , nextExpr ) ->
506
524
(* A let binding. `let a = b` *)
@@ -519,12 +537,12 @@ and completeExpr ~completionContext (expr : Parsetree.expression) :
519
537
| Some else_ ->
520
538
if locHasPos else_.pexp_loc then completeExpr ~completion Context else_
521
539
else if checkIfExprHoleEmptyCursor ~completion Context else_ then
522
- Some (CId ([] , Value ) :: completionContext.ctxPath, completionContext)
540
+ CompletionResult. ctxPath (CId ([] , Value )) completionContext
523
541
else None
524
542
| _ ->
525
543
(* Check then_ too *)
526
544
if checkIfExprHoleEmptyCursor ~completion Context then_ then
527
- Some (CId ([] , Value ) :: completionContext.ctxPath, completionContext)
545
+ CompletionResult. ctxPath (CId ([] , Value )) completionContext
528
546
else None )
529
547
| Pexp_sequence (evalExpr , nextExpr ) ->
530
548
if locHasPos evalExpr.pexp_loc then
@@ -578,7 +596,7 @@ and completeExpr ~completionContext (expr : Parsetree.expression) :
578
596
in
579
597
if locHasPos expr.pexp_loc then completeExpr ~completion Context expr
580
598
else if checkIfExprHoleEmptyCursor ~completion Context expr then
581
- Some (CId ([] , Value ) :: completionContext.ctxPath, completionContext)
599
+ CompletionResult. ctxPath (CId ([] , Value )) completionContext
582
600
else None
583
601
| Pexp_match _ | Pexp_unreachable | Pexp_constant _ | Pexp_function _
584
602
| Pexp_try (_, _)
0 commit comments