@@ -30,7 +30,9 @@ private AstNode publicApi() {
30
30
*/
31
31
private AstNode queryPredicate ( ) {
32
32
// result = query relation that is "transitively" imported by a .ql file.
33
- PathProblemQuery:: importsQueryRelation ( result ) .asFile ( ) .getExtension ( ) = "ql"
33
+ // PathProblemQuery::importsQueryRelation(result).asFile().getExtension() = "ql"
34
+ // any query predicate. Query predicates are usually meant to be used.
35
+ result .( Predicate ) .hasAnnotation ( "query" )
34
36
or
35
37
// the from-where-select
36
38
result instanceof Select
@@ -200,7 +202,8 @@ private AstNode benign() {
200
202
result instanceof BlockComment or
201
203
not exists ( result .toString ( ) ) or // <- invalid code
202
204
// cached-stages pattern
203
- result .( Module ) .getAMember ( ) .( ClasslessPredicate ) .getName ( ) = "forceStage" or
205
+ result .( Module ) .getAMember ( ) .( ClasslessPredicate ) .getName ( ) =
206
+ [ "forceStage" , "forceCachingInSameStage" ] or
204
207
result .( ClasslessPredicate ) .getName ( ) = "forceStage" or
205
208
result .getLocation ( ) .getFile ( ) .getBaseName ( ) = "Caching.qll" or
206
209
// sometimes contains dead code - ignore
@@ -239,16 +242,39 @@ private AstNode queryable() {
239
242
result = aliveStep ( queryable ( ) )
240
243
}
241
244
245
+ // The benign cases are mostly
246
+ private AstNode benignUnqueryable ( ) {
247
+ result = benign ( ) or
248
+ // cached-stages pattern
249
+ // sometimes contains dead code - ignore
250
+ result .( Module ) .getName ( ) = "Debugging" or
251
+ result .getLocation ( ) .getFile ( ) = benignUnqueryableFile ( )
252
+ }
253
+
254
+ pragma [ noinline]
255
+ private File benignUnqueryableFile ( ) {
256
+ result .getAbsolutePath ( ) .matches ( "%/explore/%" ) or
257
+ result .getRelativePath ( ) .matches ( "%/tutorials/%" ) or
258
+ result .getBaseName ( ) =
259
+ [
260
+ "Expr.qll" , "TypeScript.qll" , "YAML.qll" , "Tokens.qll" , "Instruction.qll" , "Persistence.qll" ,
261
+ "ES2015Modules.qll"
262
+ ] or // lots of classes that exist for completeness
263
+ result .getBaseName ( ) = [ "CachedStages.qll" , "Caching.qll" , "tutorial.qll" ] or
264
+ result .getBaseName ( ) .matches ( "DataFlowImpl%" ) or // DataFlow has 1578 unqueryable things.
265
+ result .getBaseName ( ) .matches ( "SsaImplCommon%" ) or
266
+ result .getBaseName ( ) .matches ( "FlowSummary%" ) or // Lots of unused FlowSummary stuff in ruby.
267
+ not result .getExtension ( ) = [ "ql" , "qll" ] // ignore dbscheme files
268
+ }
269
+
242
270
/**
243
271
* Gets an AstNode that does not affect any query result.
244
272
* Is interresting as an quick-eval target to investigate dead code.
245
273
* (It is intentional that this predicate is a result of this predicate).
246
274
*/
247
- AstNode unQueryable ( string msg ) {
275
+ AstNode unQueryable ( ) {
248
276
not result = queryable ( ) and
249
277
not result = deprecated ( ) and
250
- not result = benign ( ) and
251
- not result .getParent ( ) = any ( AstNode node | not node = queryable ( ) ) and
252
- msg = result .getLocation ( ) .getFile ( ) .getBaseName ( ) and
253
- result .getLocation ( ) .getFile ( ) .getAbsolutePath ( ) .matches ( "%/javascript/%" )
278
+ not result = benignUnqueryable ( ) and
279
+ not result .getParent ( ) = any ( AstNode node | not node = queryable ( ) )
254
280
}
0 commit comments