Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit e0aa59c

Browse files
committed
PrintAst: improve support for restricting subsets of the AST to print
* Exclude function definitions, not just their children, when excluded by configuration * Allow excluding files * Test both features
1 parent a625a4c commit e0aa59c

9 files changed

Lines changed: 165 additions & 3 deletions

File tree

ql/src/semmle/go/PrintAst.ql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,6 @@ import PrintAst
1313
*/
1414
class Cfg extends PrintAstConfiguration {
1515
override predicate shouldPrintFunction(FuncDef func) { any() }
16+
17+
override predicate shouldPrintFile(File file) { any() }
1618
}

ql/src/semmle/go/PrintAst.qll

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
import go
66

77
/**
8-
* Hook to customize the functions printed by this module.
8+
* Hook to customize the files and functions printed by this module.
9+
*
10+
* For an AstNode to be printed, it always requires `shouldPrintFile(f)` to hold
11+
* for its containing file `f`, and additionally requires `shouldPrintFunction(fun)`
12+
* if it is, or falls within, function `fun`.
913
*/
1014
class PrintAstConfiguration extends string {
1115
/**
@@ -18,19 +22,34 @@ class PrintAstConfiguration extends string {
1822
* functions.
1923
*/
2024
predicate shouldPrintFunction(FuncDef func) { any() }
25+
26+
/**
27+
* Holds if the AST for `file` should be printed. By default, holds for all
28+
* files.
29+
*/
30+
predicate shouldPrintFile(File file) { any() }
2131
}
2232

2333
private predicate shouldPrintFunction(FuncDef func) {
2434
exists(PrintAstConfiguration config | config.shouldPrintFunction(func))
2535
}
2636

37+
private predicate shouldPrintFile(File file) {
38+
exists(PrintAstConfiguration config | config.shouldPrintFile(file))
39+
}
40+
41+
private FuncDef getEnclosingFunction(AstNode n) {
42+
result = n or
43+
result = n.getEnclosingFunction()
44+
}
45+
2746
/**
2847
* An AST node that should be printed.
2948
*/
3049
private newtype TPrintAstNode =
3150
TAstNode(AstNode ast) {
32-
// Do print ast nodes without an enclosing function, e.g. file headers
33-
forall(FuncDef f | f = ast.getEnclosingFunction() | shouldPrintFunction(f))
51+
shouldPrintFile(ast.getFile()) and
52+
forall(FuncDef f | f = getEnclosingFunction(ast) | shouldPrintFunction(f))
3453
}
3554

3655
/**

ql/test/library-tests/semmle/go/PrintAst/PrintAst.expected

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,34 @@
1+
other.go:
2+
# 0| [File] library-tests/semmle/go/PrintAst/other.go
3+
# 3| 0: [FuncDecl] function declaration
4+
# 3| 0: [FunctionName, Ident] main
5+
# 3| Type = func()
6+
# 3| 1: [FuncTypeExpr] function type
7+
# 3| 2: [BlockStmt] block statement
8+
# 5| 1: [FuncDecl] function declaration
9+
# 5| 0: [FunctionName, Ident] f
10+
# 5| Type = func()
11+
# 5| 1: [FuncTypeExpr] function type
12+
# 5| 2: [BlockStmt] block statement
13+
# 6| 2: [FuncDecl] function declaration
14+
# 6| 0: [FunctionName, Ident] g
15+
# 6| Type = func()
16+
# 6| 1: [FuncTypeExpr] function type
17+
# 6| 2: [BlockStmt] block statement
18+
# 8| 3: [VarDecl] variable declaration
19+
# 8| 0: [ValueSpec] value declaration specifier
20+
# 8| 0: [Ident, VariableName] x
21+
# 8| Type = int
22+
# 8| 1: [Ident, TypeName] int
23+
# 8| Type = int
24+
# 8| 2: [IntLit] 0
25+
# 8| Type = int
26+
# 8| Value = [IntLit] 0
27+
# 1| 4: [Ident] main
28+
go.mod:
29+
# 0| [GoModFile] library-tests/semmle/go/PrintAst/go.mod
30+
# 1| 0: [GoModModuleLine] go.mod module line
31+
# 3| 1: [GoModGoLine] go.mod go line
132
input.go:
233
# 0| [File] library-tests/semmle/go/PrintAst/input.go
334
# 5| 0: [CommentGroup] comment group
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
other.go:
2+
# 0| [File] library-tests/semmle/go/PrintAst/other.go
3+
# 3| 0: [FuncDecl] function declaration
4+
# 3| 0: [FunctionName, Ident] main
5+
# 3| Type = func()
6+
# 3| 1: [FuncTypeExpr] function type
7+
# 3| 2: [BlockStmt] block statement
8+
# 5| 1: [FuncDecl] function declaration
9+
# 5| 0: [FunctionName, Ident] f
10+
# 5| Type = func()
11+
# 5| 1: [FuncTypeExpr] function type
12+
# 5| 2: [BlockStmt] block statement
13+
# 6| 2: [FuncDecl] function declaration
14+
# 6| 0: [FunctionName, Ident] g
15+
# 6| Type = func()
16+
# 6| 1: [FuncTypeExpr] function type
17+
# 6| 2: [BlockStmt] block statement
18+
# 8| 3: [VarDecl] variable declaration
19+
# 8| 0: [ValueSpec] value declaration specifier
20+
# 8| 0: [Ident, VariableName] x
21+
# 8| Type = int
22+
# 8| 1: [Ident, TypeName] int
23+
# 8| Type = int
24+
# 8| 2: [IntLit] 0
25+
# 8| Type = int
26+
# 8| Value = [IntLit] 0
27+
# 1| 4: [Ident] main
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* @kind graph
3+
*/
4+
5+
import go
6+
import semmle.go.PrintAst
7+
8+
class Cfg extends PrintAstConfiguration {
9+
override predicate shouldPrintFunction(FuncDef func) { any() }
10+
11+
override predicate shouldPrintFile(File file) { file.getBaseName() = "other.go" }
12+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
other.go:
2+
# 0| [File] library-tests/semmle/go/PrintAst/other.go
3+
# 6| 2: [FuncDecl] function declaration
4+
# 6| 0: [FunctionName, Ident] g
5+
# 6| Type = func()
6+
# 6| 1: [FuncTypeExpr] function type
7+
# 6| 2: [BlockStmt] block statement
8+
# 8| 3: [VarDecl] variable declaration
9+
# 8| 0: [ValueSpec] value declaration specifier
10+
# 8| 0: [Ident, VariableName] x
11+
# 8| Type = int
12+
# 8| 1: [Ident, TypeName] int
13+
# 8| Type = int
14+
# 8| 2: [IntLit] 0
15+
# 8| Type = int
16+
# 8| Value = [IntLit] 0
17+
# 1| 4: [Ident] main
18+
go.mod:
19+
# 0| [GoModFile] library-tests/semmle/go/PrintAst/go.mod
20+
# 1| 0: [GoModModuleLine] go.mod module line
21+
# 3| 1: [GoModGoLine] go.mod go line
22+
input.go:
23+
# 0| [File] library-tests/semmle/go/PrintAst/input.go
24+
# 5| 0: [CommentGroup] comment group
25+
# 5| 0: [SlashSlashComment] comment
26+
# 7| 1: [CommentGroup] comment group
27+
# 7| 0: [SlashSlashComment] comment
28+
# 9| 2: [DocComment] comment group
29+
# 9| 0: [SlashSlashComment] comment
30+
# 17| 3: [CommentGroup] comment group
31+
# 17| 0: [SlashSlashComment] comment
32+
# 45| 4: [DocComment] comment group
33+
# 45| 0: [SlashSlashComment] comment
34+
# 64| 5: [DocComment] comment group
35+
# 64| 0: [SlashSlashComment] comment
36+
# 74| 6: [DocComment] comment group
37+
# 74| 0: [SlashSlashComment] comment
38+
# 111| 7: [DocComment] comment group
39+
# 111| 0: [SlashSlashComment] comment
40+
# 127| 8: [DocComment] comment group
41+
# 127| 0: [SlashSlashComment] comment
42+
# 132| 9: [DocComment] comment group
43+
# 132| 0: [SlashSlashComment] comment
44+
# 3| 10: [ImportDecl] import declaration
45+
# 3| 0: [ImportSpec] import specifier
46+
# 3| 0: [StringLit] "fmt"
47+
# 1| 18: [Ident] main
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* @kind graph
3+
*/
4+
5+
import go
6+
import semmle.go.PrintAst
7+
8+
class Cfg extends PrintAstConfiguration {
9+
override predicate shouldPrintFunction(FuncDef func) { func.getName() = "g" }
10+
11+
override predicate shouldPrintFile(File file) { any() }
12+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module codeql-go-tests/printast
2+
3+
go 1.14
4+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package main
2+
3+
func main() {}
4+
5+
func f() {}
6+
func g() {}
7+
8+
var x int = 0

0 commit comments

Comments
 (0)