Skip to content

Commit e672a5e

Browse files
committed
feat(go): add support for go block call
1 parent 6c6ed71 commit e672a5e

3 files changed

Lines changed: 54 additions & 11 deletions

File tree

chapi-ast-go/src/main/kotlin/chapi/ast/goast/GoFullIdentListener.kt

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package chapi.ast.goast
22

33
import chapi.ast.antlr.GoParser
44
import chapi.domain.core.*
5+
import chapi.infra.Stack
56
import org.antlr.v4.runtime.tree.TerminalNodeImpl
67

78
/**
@@ -57,6 +58,28 @@ class GoFullIdentListener(var fileName: String) : GoAstListener() {
5758
currentFunction = CodeFunction()
5859
}
5960

61+
62+
private var blockStack = Stack<CodeFunction>()
63+
private var lastBlock = CodeFunction(Type = FunctionType.Block, Name = "chapi_block")
64+
65+
override fun enterBlock(ctx: GoParser.BlockContext?) {
66+
if (ctx?.parent is GoParser.StatementContext) {
67+
lastBlock = CodeFunction(Type = FunctionType.Block, Name = "chapi_block" + "${blockStack.count()}")
68+
blockStack.push(lastBlock)
69+
}
70+
}
71+
72+
override fun exitBlock(ctx: GoParser.BlockContext?) {
73+
if (ctx?.parent is GoParser.StatementContext) {
74+
val popBlock = blockStack.pop()!!
75+
if (blockStack.count() > 0) {
76+
blockStack.peek()!!.InnerFunctions += popBlock
77+
} else {
78+
currentFunction.InnerFunctions += popBlock
79+
}
80+
}
81+
}
82+
6083
override fun enterTypeDecl(ctx: GoParser.TypeDeclContext?) {
6184
ctx?.typeSpec()?.forEach {
6285
buildTypeSpec(it)
@@ -126,7 +149,7 @@ class GoFullIdentListener(var fileName: String) : GoAstListener() {
126149
}
127150

128151
private fun buildTypeSpec(typeSpec: GoParser.TypeSpecContext) {
129-
val identifyName = typeSpec.IDENTIFIER().text
152+
val identifyName = typeSpec.IDENTIFIER()?.text ?: ""
130153
typeSpec.type_().typeLit()?.let {
131154
when (val typeChild = it.getChild(0)) {
132155
is GoParser.StructTypeContext -> {
@@ -190,7 +213,11 @@ class GoFullIdentListener(var fileName: String) : GoAstListener() {
190213
codeCall.Parameters = parseArguments(child)
191214
codeCall.Package = wrapTarget(codeCall.NodeName)
192215

193-
currentFunction.FunctionCalls += codeCall
216+
if (blockStack.count() > 0) {
217+
lastBlock.FunctionCalls += codeCall
218+
} else {
219+
currentFunction.FunctionCalls += codeCall
220+
}
194221
}
195222

196223
else -> {

chapi-ast-go/src/test/kotlin/chapi/ast/goast/GoAnalyserTest.kt

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,19 +99,28 @@ func installController(g *gin.Engine) *gin.Engine {
9999
}"""
100100

101101
val codeContainer = GoAnalyser().analysis(code, "")
102-
val value = codeContainer.DataStructures[0]
103-
val secondCall = value.Functions[0].FunctionCalls[1]
102+
val container = codeContainer.DataStructures[0]
103+
104+
val mainCall = container.Functions[0].FunctionCalls[1]
105+
106+
assertEquals(container.Functions.size, 1)
107+
assertEquals(mainCall.FunctionName, "Group")
108+
assertEquals(mainCall.Parameters[0].TypeValue, "/v1")
109+
110+
val firstBlock = container.Functions[0].InnerFunctions[0]
111+
val innelCall = firstBlock.FunctionCalls[0]
104112

105-
assertEquals(secondCall.FunctionName, "Group")
106-
assertEquals(secondCall.Parameters[0].TypeValue, "/v1")
113+
assertEquals(innelCall.FunctionName, "Group")
114+
assertEquals(innelCall.NodeName, "*gin.Engine")
115+
assertEquals(innelCall.Parameters[0].TypeValue, "/users")
107116

108-
val thirdCall = value.Functions[0].FunctionCalls[2]
117+
val secondBlock = container.Functions[0].InnerFunctions[0].InnerFunctions[0]
118+
val innerInnerCall = secondBlock.FunctionCalls[0]
109119

110-
assertEquals(thirdCall.FunctionName, "Group")
111-
assertEquals(thirdCall.NodeName, "*gin.Engine")
112-
assertEquals(thirdCall.Parameters[0].TypeValue, "/users")
120+
assertEquals(innerInnerCall.FunctionName, "NewUserController")
113121

114-
println(Json.encodeToString(value))
122+
val innerInnerSecondCall = secondBlock.FunctionCalls[1]
123+
assertEquals(innerInnerSecondCall.FunctionName, "GET")
115124
}
116125

117126
@Test

chapi-domain/src/main/kotlin/chapi/domain/core/CodeFunction.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import kotlinx.serialization.json.JsonObject
77
import kotlinx.serialization.json.JsonPrimitive
88
import kotlinx.serialization.json.jsonObject
99

10+
enum class FunctionType {
11+
Function,
12+
// for Golang block
13+
Block,
14+
}
15+
1016
@Serializable
1117
open class CodeFunction(
1218
var Name: String = "",
@@ -29,6 +35,7 @@ open class CodeFunction(
2935
var IsConstructor: Boolean = false, // todo: move to extension
3036
var IsReturnHtml: Boolean = false,
3137
var BodyHash: Int = 0,
38+
var Type: FunctionType = FunctionType.Function,
3239
// a experimental api for code analysis, please carefully use it.
3340
// @property:ExperimentalStdlibApi val expression: Expression? = null,
3441
) {

0 commit comments

Comments
 (0)