@@ -211,6 +211,22 @@ abstract class ItemNode extends Locatable {
211211 ) .( Crate ) .getADependency * ( )
212212 }
213213
214+ /** Holds if this item has a canonical path belonging to the crate `c`. */
215+ abstract predicate hasCanonicalPath ( Crate c ) ;
216+
217+ /** Holds if this node provides a canonical path prefix for `child` in crate `c`. */
218+ pragma [ nomagic]
219+ predicate providesCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
220+ child .getImmediateParent ( ) = this and
221+ this .hasCanonicalPath ( c )
222+ }
223+
224+ /** Holds if this node has a canonical path prefix in crate `c`. */
225+ pragma [ nomagic]
226+ final predicate hasCanonicalPathPrefix ( Crate c ) {
227+ any ( ItemNode parent ) .providesCanonicalPathPrefixFor ( c , this )
228+ }
229+
214230 /**
215231 * Gets the canonical path of this item, if any.
216232 *
@@ -224,7 +240,7 @@ abstract class ItemNode extends Locatable {
224240 /** Gets the canonical path prefix that this node provides for `child`. */
225241 pragma [ nomagic]
226242 string getCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
227- child . getImmediateParent ( ) = this and
243+ this . providesCanonicalPathPrefixFor ( c , child ) and
228244 result = this .getCanonicalPath ( c )
229245 }
230246
@@ -234,10 +250,6 @@ abstract class ItemNode extends Locatable {
234250 result = any ( ItemNode parent ) .getCanonicalPathPrefixFor ( c , this )
235251 }
236252
237- /** Gets the canonical path prefix of this node, if any. */
238- pragma [ nomagic]
239- final Crate getACanonicalPathCrate ( ) { exists ( this .getCanonicalPathPrefix ( result ) ) }
240-
241253 /** Gets the location of this item. */
242254 Location getLocation ( ) { result = super .getLocation ( ) }
243255}
@@ -285,6 +297,8 @@ private class SourceFileItemNode extends ModuleLikeNode, SourceFile {
285297
286298 override TypeParam getTypeParam ( int i ) { none ( ) }
287299
300+ override predicate hasCanonicalPath ( Crate c ) { none ( ) }
301+
288302 override string getCanonicalPath ( Crate c ) { none ( ) }
289303}
290304
@@ -334,33 +348,28 @@ class CrateItemNode extends ItemNode instanceof Crate {
334348
335349 override TypeParam getTypeParam ( int i ) { none ( ) }
336350
337- override string getCanonicalPath ( Crate c ) {
338- c = this and
339- result = Crate .super .getName ( ) and
340- not exists ( FunctionItemNode main |
341- main .getImmediateParent ( ) = this .getModuleNode ( ) and
342- main .getName ( ) = "main"
343- )
344- }
351+ override predicate hasCanonicalPath ( Crate c ) { c = this }
345352
346- override string getCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
347- exists ( ModuleLikeNode m |
348- result = this .getCanonicalPath ( c ) and
349- m = this .getModuleNode ( )
350- |
353+ override predicate providesCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
354+ this .hasCanonicalPath ( c ) and
355+ exists ( ModuleLikeNode m | m = this .getModuleNode ( ) |
351356 child = m
352357 or
353358 child .getImmediateParent ( ) = m .( SourceFile ) and
354359 not m = child .( SourceFileItemNode ) .getSuper ( )
355360 )
356361 }
362+
363+ override string getCanonicalPath ( Crate c ) { c = this and result = Crate .super .getName ( ) }
357364}
358365
359366/** An item that can occur in a trait or an `impl` block. */
360367abstract private class AssocItemNode extends ItemNode , AssocItem {
361368 /** Holds if this associated item has an implementation. */
362369 abstract predicate hasImplementation ( ) ;
363370
371+ override predicate hasCanonicalPath ( Crate c ) { this .hasCanonicalPathPrefix ( c ) }
372+
364373 bindingset [ c]
365374 private string getCanonicalPathPart ( Crate c , int i ) {
366375 i = 0 and
@@ -375,7 +384,7 @@ abstract private class AssocItemNode extends ItemNode, AssocItem {
375384
376385 language [ monotonicAggregates]
377386 override string getCanonicalPath ( Crate c ) {
378- c = this .getACanonicalPathCrate ( ) and
387+ this .hasCanonicalPath ( c ) and
379388 result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
380389 }
381390}
@@ -401,6 +410,8 @@ private class EnumItemNode extends ItemNode instanceof Enum {
401410
402411 override TypeParam getTypeParam ( int i ) { result = super .getGenericParamList ( ) .getTypeParam ( i ) }
403412
413+ override predicate hasCanonicalPath ( Crate c ) { this .hasCanonicalPathPrefix ( c ) }
414+
404415 bindingset [ c]
405416 private string getCanonicalPathPart ( Crate c , int i ) {
406417 i = 0 and
@@ -415,7 +426,7 @@ private class EnumItemNode extends ItemNode instanceof Enum {
415426
416427 language [ monotonicAggregates]
417428 override string getCanonicalPath ( Crate c ) {
418- c = this .getACanonicalPathCrate ( ) and
429+ this .hasCanonicalPath ( c ) and
419430 result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
420431 }
421432}
@@ -433,6 +444,8 @@ private class VariantItemNode extends ItemNode instanceof Variant {
433444
434445 override Visibility getVisibility ( ) { result = super .getEnum ( ) .getVisibility ( ) }
435446
447+ override predicate hasCanonicalPath ( Crate c ) { this .hasCanonicalPathPrefix ( c ) }
448+
436449 bindingset [ c]
437450 private string getCanonicalPathPart ( Crate c , int i ) {
438451 i = 0 and
@@ -447,7 +460,7 @@ private class VariantItemNode extends ItemNode instanceof Variant {
447460
448461 language [ monotonicAggregates]
449462 override string getCanonicalPath ( Crate c ) {
450- c = this .getACanonicalPathCrate ( ) and
463+ this .hasCanonicalPath ( c ) and
451464 result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
452465 }
453466}
@@ -572,12 +585,14 @@ class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
572585
573586 override Visibility getVisibility ( ) { result = Impl .super .getVisibility ( ) }
574587
588+ override predicate hasCanonicalPath ( Crate c ) { this .resolveSelfTy ( ) .hasCanonicalPathPrefix ( c ) }
589+
575590 pragma [ nomagic]
576591 private string getCanonicalPathTraitPart ( Crate c ) {
577- exists ( Crate c2 | result = this . resolveTraitTy ( ) . getCanonicalPath ( c2 ) |
578- c = c2
579- or
580- c2 = c .getADependency ( )
592+ exists ( Crate c2 , TraitItemNode trait |
593+ trait = this . resolveTraitTy ( ) and
594+ result = trait . getCanonicalPath ( c2 ) and
595+ if this . hasCanonicalPath ( c2 ) then c = c2 else c2 = c .getADependency ( )
581596 )
582597 }
583598
@@ -607,7 +622,7 @@ class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
607622
608623 language [ monotonicAggregates]
609624 override string getCanonicalPath ( Crate c ) {
610- c = this .getACanonicalPathCrate ( ) and
625+ this .hasCanonicalPath ( c ) and
611626 exists ( int m | if exists ( this .getTraitPath ( ) ) then m = 4 else m = 2 |
612627 result = strictconcat ( int i | i in [ 0 .. m ] | this .getCanonicalPathPart ( c , i ) order by i )
613628 )
@@ -625,6 +640,8 @@ private class MacroCallItemNode extends AssocItemNode instanceof MacroCall {
625640
626641 override Visibility getVisibility ( ) { none ( ) }
627642
643+ override predicate hasCanonicalPath ( Crate c ) { none ( ) }
644+
628645 override string getCanonicalPath ( Crate c ) { none ( ) }
629646}
630647
@@ -637,6 +654,25 @@ private class ModuleItemNode extends ModuleLikeNode instanceof Module {
637654
638655 override TypeParam getTypeParam ( int i ) { none ( ) }
639656
657+ override predicate hasCanonicalPath ( Crate c ) { this .hasCanonicalPathPrefix ( c ) }
658+
659+ override predicate providesCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
660+ this .hasCanonicalPath ( c ) and
661+ (
662+ exists ( SourceFile f |
663+ fileImport ( this , f ) and
664+ sourceFileEdge ( f , _, child )
665+ )
666+ or
667+ this = child .getImmediateParent ( )
668+ or
669+ exists ( ItemNode mid |
670+ this .providesCanonicalPathPrefixFor ( c , mid ) and
671+ mid .( MacroCallItemNode ) = child .getImmediateParent ( )
672+ )
673+ )
674+ }
675+
640676 bindingset [ c]
641677 private string getCanonicalPathPart ( Crate c , int i ) {
642678 i = 0 and
@@ -651,29 +687,9 @@ private class ModuleItemNode extends ModuleLikeNode instanceof Module {
651687
652688 language [ monotonicAggregates]
653689 override string getCanonicalPath ( Crate c ) {
654- c = this .getACanonicalPathCrate ( ) and
690+ this .hasCanonicalPath ( c ) and
655691 result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
656692 }
657-
658- pragma [ nomagic]
659- private ItemNode getACanonicalPathChild ( ) {
660- exists ( SourceFile f |
661- fileImport ( this , f ) and
662- sourceFileEdge ( f , _, result )
663- )
664- or
665- this = result .getImmediateParent ( )
666- or
667- exists ( ItemNode mid |
668- mid = this .getACanonicalPathChild ( ) and
669- mid .( MacroCallItemNode ) = result .getImmediateParent ( )
670- )
671- }
672-
673- override string getCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
674- child = this .getACanonicalPathChild ( ) and
675- result = this .getCanonicalPath ( c )
676- }
677693}
678694
679695private class StructItemNode extends ItemNode instanceof Struct {
@@ -690,6 +706,8 @@ private class StructItemNode extends ItemNode instanceof Struct {
690706
691707 override TypeParam getTypeParam ( int i ) { result = super .getGenericParamList ( ) .getTypeParam ( i ) }
692708
709+ override predicate hasCanonicalPath ( Crate c ) { this .hasCanonicalPathPrefix ( c ) }
710+
693711 bindingset [ c]
694712 private string getCanonicalPathPart ( Crate c , int i ) {
695713 i = 0 and
@@ -704,7 +722,7 @@ private class StructItemNode extends ItemNode instanceof Struct {
704722
705723 language [ monotonicAggregates]
706724 override string getCanonicalPath ( Crate c ) {
707- c = this .getACanonicalPathCrate ( ) and
725+ this .hasCanonicalPath ( c ) and
708726 result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
709727 }
710728}
@@ -728,6 +746,13 @@ class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
728746
729747 override TypeParam getTypeParam ( int i ) { result = super .getGenericParamList ( ) .getTypeParam ( i ) }
730748
749+ override predicate hasCanonicalPath ( Crate c ) { this .hasCanonicalPathPrefix ( c ) }
750+
751+ override predicate providesCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
752+ this .hasCanonicalPath ( c ) and
753+ child = this .getAnAssocItem ( )
754+ }
755+
731756 bindingset [ c]
732757 private string getCanonicalPathPart ( Crate c , int i ) {
733758 i = 0 and
@@ -748,14 +773,14 @@ class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
748773
749774 language [ monotonicAggregates]
750775 override string getCanonicalPath ( Crate c ) {
751- c = this .getACanonicalPathCrate ( ) and
776+ this .hasCanonicalPath ( c ) and
752777 result = strictconcat ( int i | i in [ 1 .. 3 ] | this .getCanonicalPathPart ( c , i ) order by i )
753778 }
754779
755780 language [ monotonicAggregates]
756781 override string getCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
757- result = strictconcat ( int i | i in [ 0 .. 4 ] | this .getCanonicalPathPart ( c , i ) order by i ) and
758- child = this .getAnAssocItem ( )
782+ this .providesCanonicalPathPrefixFor ( c , child ) and
783+ result = strictconcat ( int i | i in [ 0 .. 4 ] | this .getCanonicalPathPart ( c , i ) order by i )
759784 }
760785}
761786
@@ -780,6 +805,8 @@ private class UnionItemNode extends ItemNode instanceof Union {
780805
781806 override TypeParam getTypeParam ( int i ) { result = super .getGenericParamList ( ) .getTypeParam ( i ) }
782807
808+ override predicate hasCanonicalPath ( Crate c ) { this .hasCanonicalPathPrefix ( c ) }
809+
783810 bindingset [ c]
784811 private string getCanonicalPathPart ( Crate c , int i ) {
785812 i = 0 and
@@ -794,7 +821,7 @@ private class UnionItemNode extends ItemNode instanceof Union {
794821
795822 language [ monotonicAggregates]
796823 override string getCanonicalPath ( Crate c ) {
797- c = this .getACanonicalPathCrate ( ) and
824+ this .hasCanonicalPath ( c ) and
798825 result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
799826 }
800827}
@@ -808,6 +835,8 @@ private class UseItemNode extends ItemNode instanceof Use {
808835
809836 override TypeParam getTypeParam ( int i ) { none ( ) }
810837
838+ override predicate hasCanonicalPath ( Crate c ) { none ( ) }
839+
811840 override string getCanonicalPath ( Crate c ) { none ( ) }
812841}
813842
@@ -820,6 +849,8 @@ private class BlockExprItemNode extends ItemNode instanceof BlockExpr {
820849
821850 override TypeParam getTypeParam ( int i ) { none ( ) }
822851
852+ override predicate hasCanonicalPath ( Crate c ) { none ( ) }
853+
823854 override string getCanonicalPath ( Crate c ) { none ( ) }
824855}
825856
@@ -878,6 +909,8 @@ private class TypeParamItemNode extends ItemNode instanceof TypeParam {
878909
879910 override Location getLocation ( ) { result = TypeParam .super .getName ( ) .getLocation ( ) }
880911
912+ override predicate hasCanonicalPath ( Crate c ) { none ( ) }
913+
881914 override string getCanonicalPath ( Crate c ) { none ( ) }
882915}
883916
0 commit comments