6
6
*/
7
7
8
8
private import codeql.yaml.Yaml as LibYaml
9
+ private import codeql.files.FileSystem
9
10
10
11
private module YamlSig implements LibYaml:: InputSig {
11
12
import codeql.Locations
@@ -49,6 +50,58 @@ private module YamlSig implements LibYaml::InputSig {
49
50
50
51
import LibYaml:: Make< YamlSig >
51
52
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
+
52
105
/** A `.qlref` YAML document. */
53
106
class QlRefDocument extends YamlDocument {
54
107
QlRefDocument ( ) { this .getFile ( ) .getExtension ( ) = "qlref" }
@@ -65,6 +118,24 @@ class QlRefDocument extends YamlDocument {
65
118
)
66
119
}
67
120
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
+
68
139
predicate isPrintAst ( ) {
69
140
this .getFile ( ) .getStem ( ) = "PrintAst"
70
141
or
0 commit comments