Switch to using top-level function declarations to filter PrintAst

This means it's no longer possible to ask for the AST of a function literal, but this is hopefully a niche use-case that we can add if and when there is demand.
This commit is contained in:
Chris Smowton
2020-07-21 16:47:49 +01:00
parent 09990f9764
commit c30d198f3d
13 changed files with 211 additions and 51 deletions

View File

@@ -20,7 +20,7 @@ external string selectedSourceFile();
* Hook to customize the functions printed by this query.
*/
class Cfg extends PrintAstConfiguration {
override predicate shouldPrintFunction(FuncDef func) { shouldPrintFile(func.getFile()) }
override predicate shouldPrintFunction(FuncDecl func) { shouldPrintFile(func.getFile()) }
override predicate shouldPrintFile(File file) { file = getEncodedFile(selectedSourceFile()) }

View File

@@ -12,7 +12,7 @@ import PrintAst
* Hook to customize the functions printed by this query.
*/
class Cfg extends PrintAstConfiguration {
override predicate shouldPrintFunction(FuncDef func) { any() }
override predicate shouldPrintFunction(FuncDecl func) { any() }
override predicate shouldPrintFile(File file) { any() }

View File

@@ -21,7 +21,7 @@ class PrintAstConfiguration extends string {
* Holds if the AST for `func` should be printed. By default, holds for all
* functions.
*/
predicate shouldPrintFunction(FuncDef func) { any() }
predicate shouldPrintFunction(FuncDecl func) { any() }
/**
* Holds if the AST for `file` should be printed. By default, holds for all
@@ -48,10 +48,7 @@ private predicate shouldPrintComments(File file) {
exists(PrintAstConfiguration config | config.shouldPrintComments(file))
}
private FuncDef getEnclosingFunction(AstNode n) {
result = n or
result = n.getEnclosingFunction()
}
private FuncDecl getEnclosingFunctionDecl(AstNode n) { result = n.getParent*() }
/**
* An AST node that should be printed.
@@ -60,7 +57,7 @@ private newtype TPrintAstNode =
TAstNode(AstNode ast) {
shouldPrintFile(ast.getFile()) and
// Do print ast nodes without an enclosing function, e.g. file headers, that are not otherwise excluded
forall(FuncDef f | f = getEnclosingFunction(ast) | shouldPrintFunction(f)) and
forall(FuncDecl f | f = getEnclosingFunctionDecl(ast) | shouldPrintFunction(f)) and
(
shouldPrintComments(ast.getFile())
or

View File

@@ -15,16 +15,41 @@ other.go:
# 6| Type = func()
# 6| 1: [FuncTypeExpr] function type
# 6| 2: [BlockStmt] block statement
# 8| 3: [VarDecl] variable declaration
# 8| 0: [ValueSpec] value declaration specifier
# 8| 0: [Ident, VariableName] x
# 8| Type = int
# 8| 1: [Ident, TypeName] int
# 8| Type = int
# 8| 2: [IntLit] 0
# 8| Type = int
# 8| Value = [IntLit] 0
# 1| 4: [Ident] main
# 8| 3: [FuncDecl] function declaration
# 8| 0: [FunctionName, Ident] hasNested
# 8| Type = func()
# 8| 1: [FuncTypeExpr] function type
# 8| 2: [BlockStmt] block statement
# 10| 0: [DefineStmt] ... := ...
# 10| 0: [Ident, VariableName] myNested
# 10| Type = func() int
# 10| 1: [FuncLit] function literal
# 10| Type = func() int
# 10| 0: [FuncTypeExpr] function type
# 10| Type = func() int
# 10| 0: [ResultVariableDecl] result variable declaration
# 10| 0: [Ident, TypeName] int
# 10| Type = int
# 10| 1: [BlockStmt] block statement
# 10| 0: [ReturnStmt] return statement
# 10| 0: [IntLit] 1
# 10| Type = int
# 10| Value = [IntLit] 1
# 11| 1: [ExprStmt] expression statement
# 11| 0: [CallExpr] call to myNested
# 11| Type = int
# 11| 0: [Ident, VariableName] myNested
# 11| Type = func() int
# 15| 4: [VarDecl] variable declaration
# 15| 0: [ValueSpec] value declaration specifier
# 15| 0: [Ident, VariableName] x
# 15| Type = int
# 15| 1: [Ident, TypeName] int
# 15| Type = int
# 15| 2: [IntLit] 0
# 15| Type = int
# 15| Value = [IntLit] 0
# 1| 5: [Ident] main
go.mod:
# 0| [GoModFile] library-tests/semmle/go/PrintAst/go.mod
# 1| 0: [GoModModuleLine] go.mod module line

View File

@@ -15,16 +15,41 @@ other.go:
# 6| Type = func()
# 6| 1: [FuncTypeExpr] function type
# 6| 2: [BlockStmt] block statement
# 8| 3: [VarDecl] variable declaration
# 8| 0: [ValueSpec] value declaration specifier
# 8| 0: [Ident, VariableName] x
# 8| Type = int
# 8| 1: [Ident, TypeName] int
# 8| Type = int
# 8| 2: [IntLit] 0
# 8| Type = int
# 8| Value = [IntLit] 0
# 1| 4: [Ident] main
# 8| 3: [FuncDecl] function declaration
# 8| 0: [FunctionName, Ident] hasNested
# 8| Type = func()
# 8| 1: [FuncTypeExpr] function type
# 8| 2: [BlockStmt] block statement
# 10| 0: [DefineStmt] ... := ...
# 10| 0: [Ident, VariableName] myNested
# 10| Type = func() int
# 10| 1: [FuncLit] function literal
# 10| Type = func() int
# 10| 0: [FuncTypeExpr] function type
# 10| Type = func() int
# 10| 0: [ResultVariableDecl] result variable declaration
# 10| 0: [Ident, TypeName] int
# 10| Type = int
# 10| 1: [BlockStmt] block statement
# 10| 0: [ReturnStmt] return statement
# 10| 0: [IntLit] 1
# 10| Type = int
# 10| Value = [IntLit] 1
# 11| 1: [ExprStmt] expression statement
# 11| 0: [CallExpr] call to myNested
# 11| Type = int
# 11| 0: [Ident, VariableName] myNested
# 11| Type = func() int
# 15| 4: [VarDecl] variable declaration
# 15| 0: [ValueSpec] value declaration specifier
# 15| 0: [Ident, VariableName] x
# 15| Type = int
# 15| 1: [Ident, TypeName] int
# 15| Type = int
# 15| 2: [IntLit] 0
# 15| Type = int
# 15| Value = [IntLit] 0
# 1| 5: [Ident] main
go.mod:
# 0| [GoModFile] library-tests/semmle/go/PrintAst/go.mod
# 1| 0: [GoModModuleLine] go.mod module line

View File

@@ -6,7 +6,7 @@ import go
import semmle.go.PrintAst
class Cfg extends PrintAstConfiguration {
override predicate shouldPrintFunction(FuncDef func) { any() }
override predicate shouldPrintFunction(FuncDecl func) { any() }
override predicate shouldPrintFile(File file) { any() }

View File

@@ -0,0 +1,67 @@
other.go:
# 0| [File] library-tests/semmle/go/PrintAst/other.go
# 8| 3: [FuncDecl] function declaration
# 8| 0: [FunctionName, Ident] hasNested
# 8| Type = func()
# 8| 1: [FuncTypeExpr] function type
# 8| 2: [BlockStmt] block statement
# 10| 0: [DefineStmt] ... := ...
# 10| 0: [Ident, VariableName] myNested
# 10| Type = func() int
# 10| 1: [FuncLit] function literal
# 10| Type = func() int
# 10| 0: [FuncTypeExpr] function type
# 10| Type = func() int
# 10| 0: [ResultVariableDecl] result variable declaration
# 10| 0: [Ident, TypeName] int
# 10| Type = int
# 10| 1: [BlockStmt] block statement
# 10| 0: [ReturnStmt] return statement
# 10| 0: [IntLit] 1
# 10| Type = int
# 10| Value = [IntLit] 1
# 11| 1: [ExprStmt] expression statement
# 11| 0: [CallExpr] call to myNested
# 11| Type = int
# 11| 0: [Ident, VariableName] myNested
# 11| Type = func() int
# 15| 4: [VarDecl] variable declaration
# 15| 0: [ValueSpec] value declaration specifier
# 15| 0: [Ident, VariableName] x
# 15| Type = int
# 15| 1: [Ident, TypeName] int
# 15| Type = int
# 15| 2: [IntLit] 0
# 15| Type = int
# 15| Value = [IntLit] 0
# 1| 5: [Ident] main
go.mod:
# 0| [GoModFile] library-tests/semmle/go/PrintAst/go.mod
# 1| 0: [GoModModuleLine] go.mod module line
# 3| 1: [GoModGoLine] go.mod go line
input.go:
# 0| [File] library-tests/semmle/go/PrintAst/input.go
# 5| 0: [CommentGroup] comment group
# 5| 0: [SlashSlashComment] comment
# 7| 1: [CommentGroup] comment group
# 7| 0: [SlashSlashComment] comment
# 9| 2: [DocComment] comment group
# 9| 0: [SlashSlashComment] comment
# 17| 3: [CommentGroup] comment group
# 17| 0: [SlashSlashComment] comment
# 45| 4: [DocComment] comment group
# 45| 0: [SlashSlashComment] comment
# 64| 5: [DocComment] comment group
# 64| 0: [SlashSlashComment] comment
# 74| 6: [DocComment] comment group
# 74| 0: [SlashSlashComment] comment
# 111| 7: [DocComment] comment group
# 111| 0: [SlashSlashComment] comment
# 127| 8: [DocComment] comment group
# 127| 0: [SlashSlashComment] comment
# 132| 9: [DocComment] comment group
# 132| 0: [SlashSlashComment] comment
# 3| 10: [ImportDecl] import declaration
# 3| 0: [ImportSpec] import specifier
# 3| 0: [StringLit] "fmt"
# 1| 18: [Ident] main

View File

@@ -0,0 +1,14 @@
/**
* @kind graph
*/
import go
import semmle.go.PrintAst
class Cfg extends PrintAstConfiguration {
override predicate shouldPrintFunction(FuncDecl func) { func.getName() = "hasNested" }
override predicate shouldPrintFile(File file) { any() }
override predicate shouldPrintComments(File file) { any() }
}

View File

@@ -15,13 +15,38 @@ other.go:
# 6| Type = func()
# 6| 1: [FuncTypeExpr] function type
# 6| 2: [BlockStmt] block statement
# 8| 3: [VarDecl] variable declaration
# 8| 0: [ValueSpec] value declaration specifier
# 8| 0: [Ident, VariableName] x
# 8| Type = int
# 8| 1: [Ident, TypeName] int
# 8| Type = int
# 8| 2: [IntLit] 0
# 8| Type = int
# 8| Value = [IntLit] 0
# 1| 4: [Ident] main
# 8| 3: [FuncDecl] function declaration
# 8| 0: [FunctionName, Ident] hasNested
# 8| Type = func()
# 8| 1: [FuncTypeExpr] function type
# 8| 2: [BlockStmt] block statement
# 10| 0: [DefineStmt] ... := ...
# 10| 0: [Ident, VariableName] myNested
# 10| Type = func() int
# 10| 1: [FuncLit] function literal
# 10| Type = func() int
# 10| 0: [FuncTypeExpr] function type
# 10| Type = func() int
# 10| 0: [ResultVariableDecl] result variable declaration
# 10| 0: [Ident, TypeName] int
# 10| Type = int
# 10| 1: [BlockStmt] block statement
# 10| 0: [ReturnStmt] return statement
# 10| 0: [IntLit] 1
# 10| Type = int
# 10| Value = [IntLit] 1
# 11| 1: [ExprStmt] expression statement
# 11| 0: [CallExpr] call to myNested
# 11| Type = int
# 11| 0: [Ident, VariableName] myNested
# 11| Type = func() int
# 15| 4: [VarDecl] variable declaration
# 15| 0: [ValueSpec] value declaration specifier
# 15| 0: [Ident, VariableName] x
# 15| Type = int
# 15| 1: [Ident, TypeName] int
# 15| Type = int
# 15| 2: [IntLit] 0
# 15| Type = int
# 15| Value = [IntLit] 0
# 1| 5: [Ident] main

View File

@@ -6,7 +6,7 @@ import go
import semmle.go.PrintAst
class Cfg extends PrintAstConfiguration {
override predicate shouldPrintFunction(FuncDef func) { any() }
override predicate shouldPrintFunction(FuncDecl func) { any() }
override predicate shouldPrintFile(File file) { file.getBaseName() = "other.go" }
}

View File

@@ -5,16 +5,16 @@ other.go:
# 6| Type = func()
# 6| 1: [FuncTypeExpr] function type
# 6| 2: [BlockStmt] block statement
# 8| 3: [VarDecl] variable declaration
# 8| 0: [ValueSpec] value declaration specifier
# 8| 0: [Ident, VariableName] x
# 8| Type = int
# 8| 1: [Ident, TypeName] int
# 8| Type = int
# 8| 2: [IntLit] 0
# 8| Type = int
# 8| Value = [IntLit] 0
# 1| 4: [Ident] main
# 15| 4: [VarDecl] variable declaration
# 15| 0: [ValueSpec] value declaration specifier
# 15| 0: [Ident, VariableName] x
# 15| Type = int
# 15| 1: [Ident, TypeName] int
# 15| Type = int
# 15| 2: [IntLit] 0
# 15| Type = int
# 15| Value = [IntLit] 0
# 1| 5: [Ident] main
go.mod:
# 0| [GoModFile] library-tests/semmle/go/PrintAst/go.mod
# 1| 0: [GoModModuleLine] go.mod module line

View File

@@ -6,7 +6,7 @@ import go
import semmle.go.PrintAst
class Cfg extends PrintAstConfiguration {
override predicate shouldPrintFunction(FuncDef func) { func.getName() = "g" }
override predicate shouldPrintFunction(FuncDecl func) { func.getName() = "g" }
override predicate shouldPrintFile(File file) { any() }
}

View File

@@ -5,4 +5,11 @@ func main() {}
func f() {}
func g() {}
func hasNested() {
myNested := func() int { return 1 }
myNested()
}
var x int = 0