66 */
77
88private import codeql.yaml.Yaml as LibYaml
9+ private import codeql.files.FileSystem
910
1011private module YamlSig implements LibYaml:: InputSig {
1112 import codeql.Locations
@@ -49,6 +50,58 @@ private module YamlSig implements LibYaml::InputSig {
4950
5051import LibYaml:: Make< YamlSig >
5152
53+ /** A `qlpack.yml` document. */
54+ class QlPackDocument extends YamlDocument {
55+ QlPackDocument ( ) { this .getFile ( ) .getBaseName ( ) = "qlpack.yml" }
56+
57+ /** Gets the name of this QL pack. */
58+ string getPackName ( ) {
59+ exists ( YamlMapping n |
60+ n .getDocument ( ) = this and
61+ result = n .lookup ( "name" ) .( YamlScalar ) .getValue ( )
62+ )
63+ }
64+
65+ private string getADependencyName ( ) {
66+ exists ( YamlMapping n , YamlScalar key |
67+ n .getDocument ( ) = this and
68+ n .lookup ( "dependencies" ) .( YamlMapping ) .maps ( key , _) and
69+ result = key .getValue ( )
70+ )
71+ }
72+
73+ /** Gets a dependency of this QL pack. */
74+ QlPackDocument getADependency ( ) { result .getPackName ( ) = this .getADependencyName ( ) }
75+
76+ private Folder getRootFolder ( ) { result = this .getFile ( ) .getParentContainer ( ) }
77+
78+ /** Gets a folder inside this QL pack. */
79+ pragma [ nomagic]
80+ Folder getAFolder ( ) {
81+ result = this .getRootFolder ( )
82+ or
83+ exists ( Folder mid |
84+ mid = this .getAFolder ( ) and
85+ result .getParentContainer ( ) = mid and
86+ not result = any ( QlPackDocument other ) .getRootFolder ( )
87+ )
88+ }
89+ }
90+
91+ private predicate shouldAppend ( QlRefDocument qlref , Folder f , string relativePath ) {
92+ relativePath = qlref .getRelativeQueryPath ( ) and
93+ (
94+ exists ( QlPackDocument pack |
95+ pack .getAFolder ( ) = qlref .getFile ( ) .getParentContainer ( ) and
96+ f = [ pack , pack .getADependency ( ) ] .getFile ( ) .getParentContainer ( )
97+ )
98+ or
99+ f = qlref .getFile ( ) .getParentContainer ( )
100+ )
101+ }
102+
103+ private predicate shouldAppend ( Folder f , string relativePath ) { shouldAppend ( _, f , relativePath ) }
104+
52105/** A `.qlref` YAML document. */
53106class QlRefDocument extends YamlDocument {
54107 QlRefDocument ( ) { this .getFile ( ) .getExtension ( ) = "qlref" }
@@ -65,6 +118,24 @@ class QlRefDocument extends YamlDocument {
65118 )
66119 }
67120
121+ /** Gets the relative path of the query in this `.qlref` file. */
122+ string getRelativeQueryPath ( ) {
123+ exists ( YamlMapping n | n .getDocument ( ) = this |
124+ result = n .lookup ( "query" ) .( YamlScalar ) .getValue ( )
125+ )
126+ or
127+ not exists ( YamlMapping n | n .getDocument ( ) = this ) and
128+ result = this .eval ( ) .( YamlScalar ) .getValue ( )
129+ }
130+
131+ /** Gets the query file referenced in this `.qlref` file. */
132+ File getQueryFile ( ) {
133+ exists ( Folder f , string relativePath |
134+ shouldAppend ( this , f , relativePath ) and
135+ result = Folder:: Append< shouldAppend / 2 > :: append ( f , relativePath )
136+ )
137+ }
138+
68139 predicate isPrintAst ( ) {
69140 this .getFile ( ) .getStem ( ) = "PrintAst"
70141 or
0 commit comments