@@ -73,7 +73,7 @@ final class Namespace extends TNamespace {
7373 * - https://doc.rust-lang.org/reference/visibility-and-privacy.html
7474 * - https://doc.rust-lang.org/reference/names/namespaces.html
7575 */
76- abstract class ItemNode extends AstNode {
76+ abstract class ItemNode extends Locatable {
7777 /** Gets the (original) name of this item. */
7878 abstract string getName ( ) ;
7979
@@ -122,6 +122,10 @@ abstract class ItemNode extends AstNode {
122122 or
123123 useImportEdge ( this , name , result )
124124 or
125+ crateDefEdge ( this , name , result )
126+ or
127+ crateDependencyEdge ( this , name , result )
128+ or
125129 // items made available through `use` are available to nodes that contain the `use`
126130 exists ( UseItemNode use |
127131 use = this .getASuccessorRec ( _) and
@@ -180,7 +184,7 @@ abstract class ItemNode extends AstNode {
180184 this = result .( ImplOrTraitItemNode ) .getAnItemInSelfScope ( )
181185 or
182186 name = "crate" and
183- result .( SourceFileItemNode ) . getFile ( ) = this . getFile ( )
187+ this = result .( Crate ) . getASourceFile ( )
184188 }
185189
186190 /** Gets the location of this item. */
@@ -214,6 +218,46 @@ private class SourceFileItemNode extends ModuleLikeNode, SourceFile {
214218 override TypeParam getTypeParam ( int i ) { none ( ) }
215219}
216220
221+ class CrateItemNode extends ItemNode instanceof Crate {
222+ /** Gets the module node that defines this crate. */
223+ pragma [ nomagic]
224+ ModuleLikeNode getModuleNode ( ) {
225+ result = super .getSourceFile ( )
226+ or
227+ not exists ( super .getSourceFile ( ) ) and
228+ result = super .getModule ( )
229+ }
230+
231+ /**
232+ * Gets a source file that belongs to this crate, if any.
233+ *
234+ * This is calculated as those source files that can be reached from the entry
235+ * file of this crate using zero or more `mod` imports, without going through
236+ * the entry point of some other crate.
237+ */
238+ pragma [ nomagic]
239+ SourceFileItemNode getASourceFile ( ) {
240+ result = super .getSourceFile ( )
241+ or
242+ exists ( SourceFileItemNode mid , Module mod |
243+ mid = this .getASourceFile ( ) and
244+ mod .getFile ( ) = mid .getFile ( ) and
245+ fileImport ( mod , result ) and
246+ not result = any ( Crate other ) .getSourceFile ( )
247+ )
248+ }
249+
250+ override string getName ( ) { result = "(crate)" }
251+
252+ override Namespace getNamespace ( ) {
253+ result .isType ( ) // can be referenced with `crate`
254+ }
255+
256+ override Visibility getVisibility ( ) { none ( ) }
257+
258+ override TypeParam getTypeParam ( int i ) { none ( ) }
259+ }
260+
217261/** An item that can occur in a trait or an `impl` block. */
218262abstract private class AssocItemNode extends ItemNode , AssocItem {
219263 /** Holds if this associated item has an implementation. */
@@ -600,6 +644,31 @@ private predicate fileImportEdge(Module mod, string name, ItemNode item) {
600644 )
601645}
602646
647+ /**
648+ * Holds if crate `c` defines the item `i` named `name`.
649+ */
650+ pragma [ nomagic]
651+ private predicate crateDefEdge ( CrateItemNode c , string name , ItemNode i ) {
652+ i = c .getModuleNode ( ) .getASuccessor ( name )
653+ }
654+
655+ /**
656+ * Holds if `source` depends on crate `dep` named `name`.
657+ *
658+ * Does not yet take dependency renaming into account.
659+ */
660+ pragma [ nomagic]
661+ private predicate crateDependencyEdge ( ModuleLikeNode source , string name , Crate dep ) {
662+ exists ( CrateItemNode c |
663+ dep = c .( Crate ) .getADependency ( ) and
664+ dep .getName ( ) = name
665+ |
666+ source = c .getModuleNode ( )
667+ or
668+ source = c .( Crate ) .getASourceFile ( )
669+ )
670+ }
671+
603672private predicate useTreeDeclares ( UseTree tree , string name ) {
604673 not tree .isGlob ( ) and
605674 not exists ( tree .getUseTreeList ( ) ) and
@@ -837,3 +906,44 @@ private predicate useImportEdge(Use use, string name, ItemNode item) {
837906 name != "_"
838907 )
839908}
909+
910+ /** Provides predicates for debugging the path resolution implementation. */
911+ private module Debug {
912+ private Locatable getRelevantLocatable ( ) {
913+ exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
914+ result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
915+ filepath .matches ( "%/build_steps/mod.rs" ) and
916+ startline = 17
917+ )
918+ }
919+
920+ ItemNode debugResolvePath ( RelevantPath path ) {
921+ path = getRelevantLocatable ( ) and
922+ result = resolvePath ( path )
923+ }
924+
925+ predicate debugCrateDependencyEdge ( ModuleLikeNode source , string name , Crate dep ) {
926+ source = getRelevantLocatable ( ) and
927+ crateDependencyEdge ( source , name , dep )
928+ }
929+
930+ predicate debugUseImportEdge ( Use use , string name , ItemNode item ) {
931+ use = getRelevantLocatable ( ) and
932+ useImportEdge ( use , name , item )
933+ }
934+
935+ ItemNode debugGetASuccessorRec ( ItemNode i , string name ) {
936+ i = getRelevantLocatable ( ) and
937+ result = i .getASuccessor ( name )
938+ }
939+
940+ predicate debugFileImportEdge ( Module mod , string name , ItemNode item ) {
941+ mod = getRelevantLocatable ( ) and
942+ fileImportEdge ( mod , name , item )
943+ }
944+
945+ predicate debugFileImport ( Module m , SourceFile f ) {
946+ m = getRelevantLocatable ( ) and
947+ fileImport ( m , f )
948+ }
949+ }
0 commit comments