Skip to content

Commit

Permalink
built-in Go
Browse files Browse the repository at this point in the history
  • Loading branch information
oxisto committed Mar 4, 2023
1 parent f8edd1d commit 382cc00
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
21 changes: 21 additions & 0 deletions cpg-language-go/src/main/golang/frontend/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ func (this *GoLanguageFrontend) HandleFile(fset *token.FileSet, file *ast.File,
}
}

// create a built-in "go" function
goFunc := this.NewFunctionDeclaration(fset, nil, "go", "", true)
goFunc.AddParameter(this.NewParamVariableDeclaration(fset, nil, "call"))
scope.AddDeclaration((*cpg.Declaration)(goFunc))

// create a new namespace declaration, representing the package
p := this.NewNamespaceDeclaration(fset, nil, file.Name.Name)

Expand Down Expand Up @@ -658,6 +663,8 @@ func (this *GoLanguageFrontend) handleStmt(fset *token.FileSet, stmt ast.Stmt, p
s = (*cpg.Statement)(this.handleAssignStmt(fset, v))
case *ast.DeclStmt:
s = (*cpg.Statement)(this.handleDeclStmt(fset, v))
case *ast.GoStmt:
s = (*cpg.Statement)(this.handleGoStmt(fset, v))
case *ast.IfStmt:
s = (*cpg.Statement)(this.handleIfStmt(fset, v))
case *ast.SwitchStmt:
Expand Down Expand Up @@ -789,6 +796,20 @@ func (this *GoLanguageFrontend) handleDeclStmt(fset *token.FileSet, declStmt *as
return (*cpg.Expression)(stmt)
}

// handleGoStmt handles the `go` statement, which is a special keyword in go
// that starts the supplied call expression in a separate Go routine. We cannot
// model this 1:1, so we basically we create a call expression to a built-in call.
func (this *GoLanguageFrontend) handleGoStmt(fset *token.FileSet, goStmt *ast.GoStmt) (expr *cpg.Expression) {
this.LogTrace("Handling go statement: %+v", *goStmt)

ref := (*cpg.Expression)(this.NewDeclaredReferenceExpression(fset, nil, "go"))

call := this.NewCallExpression(fset, goStmt, ref, "go")
call.AddArgument(this.handleCallExpr(fset, goStmt.Call))

return (*cpg.Expression)(call)
}

func (this *GoLanguageFrontend) handleIfStmt(fset *token.FileSet, ifStmt *ast.IfStmt) (expr *cpg.Expression) {
this.LogTrace("Handling if statement: %+v", *ifStmt)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,9 @@ class GoLanguageFrontendTest : BaseTest() {
val base = call.base as? DeclaredReferenceExpression
assertNotNull(base)
assertEquals(c, base.refersTo)

val go = main.calls["go"]
assertNotNull(go)
}

@Test
Expand Down Expand Up @@ -650,6 +653,7 @@ class GoLanguageFrontendTest : BaseTest() {

val bytes = assertIs<DeclaredReferenceExpression>(each.iterable)
assertLocalName("bytes", bytes)
assertNotNull(bytes.refersTo)

val idx = assertIs<DeclarationStatement>(each.variable).variables["idx"]
assertNotNull(idx)
Expand Down
3 changes: 3 additions & 0 deletions cpg-language-go/src/test/resources/golang/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ import ("http")
func main() {
c := NewMyStruct()
c.myOtherFunc()

go c.MyFunc()
go c.MyFunc()
}

0 comments on commit 382cc00

Please sign in to comment.