-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathGoMod.qll
More file actions
233 lines (186 loc) · 6.92 KB
/
GoMod.qll
File metadata and controls
233 lines (186 loc) · 6.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/**
* Provides classes for working with go.mod files.
*/
overlay[local]
module;
import go
/** A go.mod file. */
class GoModFile extends File {
GoModFile() { this.getBaseName() = "go.mod" }
/**
* Gets the module declaration of this file, that is, the line declaring the path of this module.
*/
GoModModuleLine getModuleDeclaration() { result.getFile() = this }
override string getAPrimaryQlClass() { result = "GoModFile" }
}
/**
* An expression in a go.mod file, which is used to declare dependencies.
*/
class GoModExpr extends @modexpr, GoModExprParent {
/**
* Gets the kind of this expression, which is an integer value representing the expression's
* node type.
*
* Note that the mapping from node types to integer kinds is considered an implementation detail
* and subject to change without notice.
*/
int getKind() { modexprs(this, result, _, _) }
/**
* Get the comment group associated with this expression.
*/
DocComment getComments() { result.getDocumentedElement() = this }
override GoModFile getFile() { result = GoModExprParent.super.getFile() }
/** Gets path of the module of this go.mod expression. */
string getModulePath() { result = this.getFile().getModuleDeclaration().getPath() }
override string toString() { result = "go.mod expression" }
override string getAPrimaryQlClass() { result = "GoModExpr" }
}
/**
* A top-level block of comments separate from any rule.
*/
class GoModCommentBlock extends @modcommentblock, GoModExpr {
override string getAPrimaryQlClass() { result = "GoModCommentBlock" }
}
/**
* A single line of tokens.
*/
class GoModLine extends @modline, GoModExpr {
/**
* Gets the `i`th token on this line, 0-based.
*
* Generally, one should use `getToken`, as that accounts for lines inside of line blocks.
*/
string getRawToken(int i) { modtokens(result, this, i) }
/**
* Gets the `i`th token of `line`, including the token in the line block declaration, if it there is
* one, 0-based.
*
* This compensates for the fact that lines in line blocks have their 0th token in the line block
* declaration, and makes dealing with lines more uniform.
*
* For example, `.getToken(1)` will result in the dependency path (`github.com/github/codeql-go`)
* for both lines for normal require lines like `require "github.com/github/codeql-go" v1.2.3` and
* in a line block like
*
* ```
* require (
* "github.com/github/codeql-go" v1.2.3
* ...
* )
* ```
*
* As a special case, when `i` is `0` and the line is in a line block, the result will be the
* token from the line block.
*/
string getToken(int i) {
i = 0 and result = this.getParent().(GoModLineBlock).getRawToken(0)
or
if this.getParent() instanceof GoModLineBlock
then result = this.getRawToken(i - 1)
else result = this.getRawToken(i)
}
override string toString() { result = "go.mod line" }
override string getAPrimaryQlClass() { result = "GoModLine" }
}
/**
* A factored block of lines, for example:
* ```
* require (
* "github.com/github/codeql-go" v1.2.3
* "golang.org/x/tools" v3.2.1
* )
* ```
*/
class GoModLineBlock extends @modlineblock, GoModExpr {
/**
* Gets the `i`th token of this line block, 0-based.
*
* Usually one should not have to use this, as `GoModLine.getToken(0)` will get the token from its
* parent line block, if any.
*/
string getRawToken(int i) { modtokens(result, this, i) }
override string toString() { result = "go.mod line block" }
override string getAPrimaryQlClass() { result = "GoModLineBlock" }
}
/**
* A line that contains the module's package path, for example `module github.com/github/codeql-go`.
*/
class GoModModuleLine extends GoModLine {
GoModModuleLine() { this.getToken(0) = "module" }
/**
* Get the path of the module being declared.
*/
string getPath() { result = this.getToken(1) }
override string toString() { result = "go.mod module line" }
override string getAPrimaryQlClass() { result = "GoModModuleLine" }
}
/**
* A line that declares the Go version to be used, for example `go 1.14`.
*/
class GoModGoLine extends GoModLine {
GoModGoLine() { this.getToken(0) = "go" }
/** Gets the Go version declared. */
string getVersion() { result = this.getToken(1) }
override string toString() { result = "go.mod go line" }
override string getAPrimaryQlClass() { result = "GoModGoLine" }
}
/**
* A line that declares a requirement, for example `require "github.com/github/codeql-go" v1.2.3`.
*/
class GoModRequireLine extends GoModLine {
GoModRequireLine() { this.getToken(0) = "require" }
/** Gets the path of the dependency. */
string getPath() { result = this.getToken(1) }
/** Gets the version of the dependency. */
string getVersion() { result = this.getToken(2) }
override string toString() { result = "go.mod require line" }
override string getAPrimaryQlClass() { result = "GoModRequireLine" }
}
/**
* A line that declares a dependency version to exclude, for example
* `exclude "github.com/github/codeql-go" v1.2.3`.
*/
class GoModExcludeLine extends GoModLine {
GoModExcludeLine() { this.getToken(0) = "exclude" }
/** Gets the path of the dependency to exclude a version of. */
string getPath() { result = this.getToken(1) }
/** Gets the excluded version. */
string getVersion() { result = this.getToken(2) }
override string toString() { result = "go.mod exclude line" }
override string getAPrimaryQlClass() { result = "GoModExcludeLine" }
}
/**
* A line that specifies a dependency to use instead of another one, for example
* `replace "golang.org/x/tools" => "github.com/golang/tools" v1.2.3`.
*/
class GoModReplaceLine extends GoModLine {
GoModReplaceLine() { this.getToken(0) = "replace" }
/** Gets the path of the dependency to be replaced. */
string getOriginalPath() { result = this.getToken(1) }
/** Gets the path of the dependency to be replaced, if any. */
string getOriginalVersion() { result = this.getToken(2) and not result = "=>" }
/** Gets the path of the replacement dependency. */
string getReplacementPath() {
if exists(this.getOriginalVersion())
then result = this.getToken(4)
else result = this.getToken(3)
}
/** Gets the version of the replacement dependency. */
string getReplacementVersion() {
if exists(this.getOriginalVersion())
then result = this.getToken(5)
else result = this.getToken(4)
}
override string toString() { result = "go.mod replace line" }
override string getAPrimaryQlClass() { result = "GoModReplaceLine" }
}
/** A left parenthesis for a line block. */
class GoModLParen extends @modlparen, GoModExpr {
override string toString() { result = "go.mod (" }
override string getAPrimaryQlClass() { result = "GoModLParen" }
}
/** A right parenthesis for a line block. */
class GoModRParen extends @modrparen, GoModExpr {
override string toString() { result = "go.mod )" }
override string getAPrimaryQlClass() { result = "GoModRParen" }
}