@@ -98,9 +98,18 @@ impl TypeInfo {
9898 }
9999 }
100100
101+ pub fn record_key_completion ( & mut self , facets : & Vec1 < FacetKind > , ty : Option < Type > ) {
102+ if let Some ( ( facet, rest) ) = facets. as_slice ( ) . split_first ( ) {
103+ let narrowed = self
104+ . facets
105+ . get_or_insert_with ( || Box :: new ( NarrowedFacets :: default ( ) ) ) ;
106+ narrowed. ensure_completion_path ( facet, rest, ty) ;
107+ }
108+ }
109+
101110 pub fn type_at_facet ( & self , facet : & FacetKind ) -> Option < & Type > {
102111 match self . get_at_facet ( facet) {
103- None | Some ( NarrowedFacet :: WithoutRoot ( .. ) ) => None ,
112+ None | Some ( NarrowedFacet :: WithoutRoot { .. } ) => None ,
104113 Some ( NarrowedFacet :: Leaf ( ty) ) | Some ( NarrowedFacet :: WithRoot ( ty, _) ) => Some ( ty) ,
105114 }
106115 }
@@ -109,9 +118,9 @@ impl TypeInfo {
109118 match self . get_at_facet ( facet) {
110119 None => TypeInfo :: of_ty ( fallback ( ) ) ,
111120 Some ( NarrowedFacet :: Leaf ( ty) ) => Self :: of_ty ( ty. clone ( ) ) ,
112- Some ( NarrowedFacet :: WithoutRoot ( narrowed_facets ) ) => Self {
121+ Some ( NarrowedFacet :: WithoutRoot { facets , .. } ) => Self {
113122 ty : fallback ( ) ,
114- facets : Some ( Box :: new ( narrowed_facets . clone ( ) ) ) ,
123+ facets : Some ( Box :: new ( facets . clone ( ) ) ) ,
115124 } ,
116125 Some ( NarrowedFacet :: WithRoot ( ty, narrowed_facets) ) => Self {
117126 ty : ty. clone ( ) ,
@@ -228,6 +237,66 @@ impl TypeInfo {
228237 }
229238 }
230239
240+ /// Return the known narrowings for dictionary-style key facets at the provided prefix.
241+ ///
242+ /// The `prefix` is the sequence of facets (attributes, indexes, and keys) that identify the
243+ /// container whose keys we are interested in. When the prefix is empty, this inspects the
244+ /// top-level facets on the `TypeInfo` itself.
245+ pub fn key_facets_at ( & self , prefix : & [ FacetKind ] ) -> Vec < ( String , Option < Type > ) > {
246+ fn collect_keys ( facets : & NarrowedFacets ) -> Vec < ( String , Option < Type > ) > {
247+ facets
248+ . 0
249+ . iter ( )
250+ . filter_map ( |( facet, narrowed) | {
251+ if let FacetKind :: Key ( key) = facet {
252+ let ty = match narrowed {
253+ NarrowedFacet :: Leaf ( ty) => Some ( ty. clone ( ) ) ,
254+ NarrowedFacet :: WithRoot ( ty, _) => Some ( ty. clone ( ) ) ,
255+ NarrowedFacet :: WithoutRoot { completion_ty, .. } => {
256+ completion_ty. clone ( )
257+ }
258+ } ;
259+ Some ( ( key. clone ( ) , ty) )
260+ } else {
261+ None
262+ }
263+ } )
264+ . collect ( )
265+ }
266+
267+ fn descend < ' a > (
268+ mut current : & ' a NarrowedFacets ,
269+ prefix : & [ FacetKind ] ,
270+ ) -> Option < & ' a NarrowedFacets > {
271+ for facet in prefix {
272+ let narrowed = current. 0 . get ( facet) ?;
273+ match narrowed {
274+ NarrowedFacet :: Leaf ( _) => return None ,
275+ NarrowedFacet :: WithRoot ( _, nested) => {
276+ current = nested;
277+ }
278+ NarrowedFacet :: WithoutRoot { facets, .. } => {
279+ current = facets;
280+ }
281+ }
282+ }
283+ Some ( current)
284+ }
285+
286+ match & self . facets {
287+ Some ( facets) => {
288+ if prefix. is_empty ( ) {
289+ collect_keys ( facets. as_ref ( ) )
290+ } else if let Some ( target) = descend ( facets. as_ref ( ) , prefix) {
291+ collect_keys ( target)
292+ } else {
293+ Vec :: new ( )
294+ }
295+ }
296+ None => Vec :: new ( ) ,
297+ }
298+ }
299+
231300 pub fn ty ( & self ) -> & Type {
232301 & self . ty
233302 }
@@ -276,6 +345,12 @@ const NARROWED_FACETS_LIMIT: usize = 50;
276345#[ derive( Debug , Clone , PartialEq , Eq , TypeEq ) ]
277346struct NarrowedFacets ( SmallMap < FacetKind , NarrowedFacet > ) ;
278347
348+ impl Default for NarrowedFacets {
349+ fn default ( ) -> Self {
350+ Self ( SmallMap :: new ( ) )
351+ }
352+ }
353+
279354impl NarrowedFacets {
280355 fn insert ( & mut self , facet : FacetKind , value : NarrowedFacet ) {
281356 // Only insert if there is space, or if the key is already present (so we overwrite)
@@ -328,9 +403,9 @@ impl NarrowedFacets {
328403 narrowed_facet. add_narrow ( more_facets, ty) ;
329404 }
330405 NarrowedFacet :: Leaf ( ..) => { }
331- NarrowedFacet :: WithoutRoot ( narrowed_facets )
332- | NarrowedFacet :: WithRoot ( _, narrowed_facets ) => {
333- narrowed_facets . update_for_assignment ( next_facet, remaining_facets, ty) ;
406+ NarrowedFacet :: WithoutRoot { facets , .. }
407+ | NarrowedFacet :: WithRoot ( _, facets ) => {
408+ facets . update_for_assignment ( next_facet, remaining_facets, ty) ;
334409 }
335410 }
336411 } else if let Some ( ty) = ty {
@@ -349,6 +424,35 @@ impl NarrowedFacets {
349424 Self ( smallmap ! { facet => NarrowedFacet :: new( more_facets, ty) } )
350425 }
351426
427+ fn ensure_completion_path (
428+ & mut self ,
429+ facet : & FacetKind ,
430+ rest : & [ FacetKind ] ,
431+ completion_ty : Option < Type > ,
432+ ) {
433+ let entry = self . 0 . entry ( facet. clone ( ) ) . or_insert_with ( || {
434+ if rest. is_empty ( ) {
435+ NarrowedFacet :: WithoutRoot {
436+ completion_ty : None ,
437+ facets : NarrowedFacets :: default ( ) ,
438+ }
439+ } else {
440+ let mut nested = NarrowedFacets :: default ( ) ;
441+ nested. ensure_completion_path ( & rest[ 0 ] , & rest[ 1 ..] , completion_ty. clone ( ) ) ;
442+ NarrowedFacet :: WithoutRoot {
443+ completion_ty : None ,
444+ facets : nested,
445+ }
446+ }
447+ } ) ;
448+
449+ if let Some ( ( next, tail) ) = rest. split_first ( ) {
450+ entry. ensure_completion_child ( next, tail, completion_ty) ;
451+ } else {
452+ entry. set_completion_ty ( completion_ty) ;
453+ }
454+ }
455+
352456 fn join (
353457 mut branches : Vec < Self > ,
354458 union_types : & impl Fn ( Vec < Type > ) -> Type ,
@@ -413,7 +517,7 @@ impl NarrowedFacets {
413517 write ! ( f, ", " ) ?;
414518 facets. fmt_with_prefix_and_facet ( prefix, facet, f)
415519 }
416- NarrowedFacet :: WithoutRoot ( facets) => {
520+ NarrowedFacet :: WithoutRoot { facets, .. } => {
417521 facets. fmt_with_prefix_and_facet ( prefix, facet, f)
418522 }
419523 } ?;
@@ -478,16 +582,20 @@ enum NarrowedFacet {
478582 /// This facet is narrowed, and has one or more narrowed sub-facet (WithRoot)
479583 WithRoot ( Type , NarrowedFacets ) ,
480584 /// This facet is not narrowed, and has one or more narrowed sub-facet (WithoutRoot)
481- WithoutRoot ( NarrowedFacets ) ,
585+ WithoutRoot {
586+ completion_ty : Option < Type > ,
587+ facets : NarrowedFacets ,
588+ } ,
482589}
483590
484591impl NarrowedFacet {
485592 fn new ( facets : & [ FacetKind ] , ty : Type ) -> Self {
486593 match facets {
487594 [ ] => Self :: Leaf ( ty) ,
488- [ facet, more_facets @ ..] => {
489- Self :: WithoutRoot ( NarrowedFacets :: of_narrow ( ( * facet) . clone ( ) , more_facets, ty) )
490- }
595+ [ facet, more_facets @ ..] => Self :: WithoutRoot {
596+ completion_ty : None ,
597+ facets : NarrowedFacets :: of_narrow ( ( * facet) . clone ( ) , more_facets, ty) ,
598+ } ,
491599 }
492600 }
493601
@@ -501,41 +609,68 @@ impl NarrowedFacet {
501609 fn clear_index_narrows ( & mut self , facets : & [ FacetKind ] ) {
502610 match self {
503611 Self :: Leaf ( _) => { }
504- Self :: WithRoot ( _, narrowed_facets) | Self :: WithoutRoot ( narrowed_facets) => {
505- narrowed_facets. clear_index_narrows ( facets)
506- }
612+ Self :: WithRoot ( _, narrowed_facets)
613+ | Self :: WithoutRoot {
614+ facets : narrowed_facets,
615+ ..
616+ } => narrowed_facets. clear_index_narrows ( facets) ,
507617 }
508618 }
509619
510620 fn with_narrow ( self , facets : & [ FacetKind ] , narrowed_ty : Type ) -> Self {
511621 match facets {
512- [ ] => {
513- // We are setting a narrow at the current node (potentially overriding an existing narrow; it is
514- // up to callers to make sure this works correctly, we just take what was given).
515- match self {
516- Self :: Leaf ( _) => Self :: Leaf ( narrowed_ty) ,
517- Self :: WithRoot ( _, narrowed_facets) | Self :: WithoutRoot ( narrowed_facets) => {
518- Self :: WithRoot ( narrowed_ty, narrowed_facets)
519- }
622+ [ ] => match self {
623+ Self :: Leaf ( _) => Self :: Leaf ( narrowed_ty) ,
624+ Self :: WithRoot ( _, narrowed_facets)
625+ | Self :: WithoutRoot {
626+ facets : narrowed_facets,
627+ ..
628+ } => Self :: WithRoot ( narrowed_ty, narrowed_facets) ,
629+ } ,
630+ [ facet, more_facets @ ..] => match self {
631+ Self :: Leaf ( root_ty) => {
632+ let narrowed_facets =
633+ NarrowedFacets :: of_narrow ( ( * facet) . clone ( ) , more_facets, narrowed_ty) ;
634+ Self :: WithRoot ( root_ty, narrowed_facets)
520635 }
521- }
522- [ facet, more_facets @ ..] => {
523- // We are setting a narrow in a subtree. We need to preserve any existing tree.
524- match self {
525- Self :: Leaf ( root_ty) => {
526- let narrowed_facets =
527- NarrowedFacets :: of_narrow ( ( * facet) . clone ( ) , more_facets, narrowed_ty) ;
528- Self :: WithRoot ( root_ty, narrowed_facets)
529- }
530- Self :: WithoutRoot ( mut narrowed_facets) => {
531- narrowed_facets. add_narrow ( facet, more_facets, narrowed_ty) ;
532- Self :: WithoutRoot ( narrowed_facets)
533- }
534- Self :: WithRoot ( root_ty, mut narrowed_facets) => {
535- narrowed_facets. add_narrow ( facet, more_facets, narrowed_ty) ;
536- Self :: WithRoot ( root_ty, narrowed_facets)
636+ Self :: WithoutRoot { mut facets, .. } => {
637+ facets. add_narrow ( facet, more_facets, narrowed_ty) ;
638+ Self :: WithoutRoot {
639+ completion_ty : None ,
640+ facets,
537641 }
538642 }
643+ Self :: WithRoot ( root_ty, mut narrowed_facets) => {
644+ narrowed_facets. add_narrow ( facet, more_facets, narrowed_ty) ;
645+ Self :: WithRoot ( root_ty, narrowed_facets)
646+ }
647+ } ,
648+ }
649+ }
650+
651+ fn set_completion_ty ( & mut self , ty : Option < Type > ) {
652+ if let NarrowedFacet :: WithoutRoot { completion_ty, .. } = self {
653+ * completion_ty = ty;
654+ }
655+ }
656+
657+ fn ensure_completion_child (
658+ & mut self ,
659+ facet : & FacetKind ,
660+ rest : & [ FacetKind ] ,
661+ completion_ty : Option < Type > ,
662+ ) {
663+ match self {
664+ Self :: Leaf ( root_ty) => {
665+ let mut nested = NarrowedFacets :: default ( ) ;
666+ nested. ensure_completion_path ( facet, rest, completion_ty) ;
667+ * self = Self :: WithRoot ( root_ty. clone ( ) , nested) ;
668+ }
669+ Self :: WithRoot ( _, nested) => {
670+ nested. ensure_completion_path ( facet, rest, completion_ty) ;
671+ }
672+ Self :: WithoutRoot { facets, .. } => {
673+ facets. ensure_completion_path ( facet, rest, completion_ty) ;
539674 }
540675 }
541676 }
@@ -554,20 +689,19 @@ impl NarrowedFacet {
554689 acc. push ( item)
555690 }
556691 }
557- } ;
692+ }
558693 }
559694 let mut ty_branches = Some ( Vec :: with_capacity ( branches. len ( ) ) ) ;
560695 let mut facets_branches = Some ( Vec :: with_capacity ( branches. len ( ) ) ) ;
561- for facet in branches {
562- let ( ty, facets) = match facet {
696+ for branch in branches {
697+ let ( ty, facets) = match branch {
563698 Self :: WithRoot ( ty, facets) => ( Some ( ty) , Some ( facets) ) ,
564699 Self :: Leaf ( ty) => ( Some ( ty) , None ) ,
565- Self :: WithoutRoot ( facets) => ( None , Some ( facets) ) ,
700+ Self :: WithoutRoot { facets, .. } => ( None , Some ( facets) ) ,
566701 } ;
567702 monadic_push_option ( & mut ty_branches, ty) ;
568703 monadic_push_option ( & mut facets_branches, facets) ;
569704 if let ( None , None ) = ( & ty_branches, & facets_branches) {
570- // Not needed for correctness, but saves some work.
571705 return None ;
572706 }
573707 }
@@ -577,25 +711,24 @@ impl NarrowedFacet {
577711 union_types,
578712 is_subset_eq,
579713 join_style. flat_map ( |base_facet| {
580- base_facet. as_ref ( ) . and_then ( |f | match f {
714+ base_facet. as_ref ( ) . and_then ( |facet | match facet {
581715 NarrowedFacet :: WithRoot ( ty, _) | NarrowedFacet :: Leaf ( ty) => {
582716 Some ( ty. clone ( ) )
583717 }
584- NarrowedFacet :: WithoutRoot ( _ ) => None ,
718+ NarrowedFacet :: WithoutRoot { .. } => None ,
585719 } )
586720 } ) ,
587721 )
588722 } ) ;
589- let facets = facets_branches. and_then ( |facets_branches | {
723+ let facets = facets_branches. and_then ( |branches | {
590724 NarrowedFacets :: join (
591- facets_branches ,
725+ branches ,
592726 union_types,
593727 is_subset_eq,
594728 join_style. map ( |base_facet| {
595- base_facet. as_ref ( ) . and_then ( |f| match f {
596- NarrowedFacet :: WithRoot ( _, facets) | NarrowedFacet :: WithoutRoot ( facets) => {
597- Some ( facets. clone ( ) )
598- }
729+ base_facet. as_ref ( ) . and_then ( |facet| match facet {
730+ NarrowedFacet :: WithRoot ( _, facets)
731+ | NarrowedFacet :: WithoutRoot { facets, .. } => Some ( facets. clone ( ) ) ,
599732 NarrowedFacet :: Leaf ( _) => None ,
600733 } )
601734 } ) ,
@@ -605,7 +738,10 @@ impl NarrowedFacet {
605738 ( None , None ) => None ,
606739 ( Some ( ty) , None ) => Some ( Self :: Leaf ( ty) ) ,
607740 ( Some ( ty) , Some ( facets) ) => Some ( Self :: WithRoot ( ty, facets) ) ,
608- ( None , Some ( facets) ) => Some ( Self :: WithoutRoot ( facets) ) ,
741+ ( None , Some ( facets) ) => Some ( Self :: WithoutRoot {
742+ completion_ty : None ,
743+ facets,
744+ } ) ,
609745 }
610746 }
611747}
0 commit comments