Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 66 additions & 3 deletions lang/golang/parser/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ func (p *GoParser) parseVar(ctx *fileContext, vspec *ast.ValueSpec, isConst bool

// collect func value dependencies, in case of var a = func() {...}
if val != nil && !isConst {
collects := collectInfos{}
collects := collectInfos{
directCalls: map[FileLine]bool{},
}
ast.Inspect(*val, func(n ast.Node) bool {
return p.parseASTNode(ctx, n, &collects)
})
Expand All @@ -137,6 +139,20 @@ func (p *GoParser) parseVar(ctx *fileContext, vspec *ast.ValueSpec, isConst bool
for _, dep := range collects.tys {
v.Dependencies = InsertDependency(v.Dependencies, dep)
}
if len(collects.directCalls) > 0 {
for i, dep := range v.Dependencies {
if collects.directCalls[dep.FileLine] {
if v.Dependencies[i].Extra == nil {
v.Dependencies[i].Extra = map[string]any{}
}
v.Dependencies[i].Extra["FunctionIsCall"] = true
}
}
}
if len(collects.anonymousFunctions) > 0 {
v.Extra = map[string]any{}
v.Extra["AnonymousFunctions"] = collects.anonymousFunctions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在初始化的时候把 Extra初始化? 不然以后其他人使用 Extra 的时候都得记得判空了

}
}

if vspec.Type != nil {
Expand Down Expand Up @@ -392,12 +408,19 @@ func (p *GoParser) parseSelector(ctx *fileContext, expr *ast.SelectorExpr, infos
type collectInfos struct {
functionCalls, methodCalls []Dependency
tys, globalVars []Dependency

directCalls map[FileLine]bool
anonymousFunctions []FileLine // record anonymous function
}

func (p *GoParser) parseASTNode(ctx *fileContext, node ast.Node, collect *collectInfos) bool {
switch expr := node.(type) {
case *ast.SelectorExpr:
return p.parseSelector(ctx, expr, collect)
case *ast.CallExpr:
p.parseCall(ctx, expr, collect)
case *ast.FuncLit:
collect.anonymousFunctions = append(collect.anonymousFunctions, ctx.FileLine(expr))
case *ast.Ident:
callName := expr.Name
// println("[parseFunc] ast.Ident:", callName)
Expand Down Expand Up @@ -462,6 +485,22 @@ func (p *GoParser) parseASTNode(ctx *fileContext, node ast.Node, collect *collec
return true
}

// parseCall collect direct call info
func (p *GoParser) parseCall(ctx *fileContext, expr *ast.CallExpr, collect *collectInfos) {
var ident *ast.Ident

switch idt := expr.Fun.(type) {
case *ast.Ident:
ident = idt
case *ast.SelectorExpr:
ident = idt.Sel
}

if ident != nil {
collect.directCalls[ctx.FileLine(ident)] = true
}
}

// parseFunc parses all function declaration in one file
func (p *GoParser) parseFunc(ctx *fileContext, funcDecl *ast.FuncDecl) (*Function, bool) {
// method receiver
Expand Down Expand Up @@ -511,7 +550,9 @@ func (p *GoParser) parseFunc(ctx *fileContext, funcDecl *ast.FuncDecl) (*Functio
// collect content
content := string(ctx.GetRawContent(funcDecl))

collects := collectInfos{}
collects := collectInfos{
directCalls: map[FileLine]bool{},
}
if funcDecl.Body == nil {
goto set_func
}
Expand All @@ -521,7 +562,6 @@ func (p *GoParser) parseFunc(ctx *fileContext, funcDecl *ast.FuncDecl) (*Functio
})

set_func:

if fname == "init" && p.repo.GetFunction(NewIdentity(ctx.module.Name, ctx.pkgPath, fname)) != nil {
// according to https://go.dev/ref/spec#Program_initialization_and_execution,
// duplicated init() is allowed and never be referenced, thus add a subfix
Expand All @@ -544,6 +584,29 @@ set_func:
f.Types = InsertDependency(f.Types, t)
}
f.Signature = string(sig)

if len(collects.directCalls) > 0 {
for i, dep := range f.FunctionCalls {
if collects.directCalls[dep.FileLine] {
if f.FunctionCalls[i].Extra == nil {
f.FunctionCalls[i].Extra = map[string]any{}
}
f.FunctionCalls[i].Extra["FunctionIsCall"] = true
}
}
for i, dep := range f.MethodCalls {
if collects.directCalls[dep.FileLine] {
if f.MethodCalls[i].Extra == nil {
f.MethodCalls[i].Extra = map[string]any{}
}
f.MethodCalls[i].Extra["FunctionIsCall"] = true
}
}
}
if len(collects.anonymousFunctions) > 0 {
f.Extra = map[string]any{}
f.Extra["AnonymousFunctions"] = collects.anonymousFunctions
}
return f, false
}

Expand Down
9 changes: 9 additions & 0 deletions lang/uniast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,14 @@ type Function struct {

// func llm compress result
CompressData *string `json:"compress_data,omitempty"`

Extra map[string]any `json:",omitempty"`
}

type Dependency struct {
Identity
FileLine `json:",omitempty"`
Extra map[string]any `json:",omitempty"`
}

func (d Dependency) Id() Identity {
Expand Down Expand Up @@ -607,6 +610,9 @@ type Type struct {
// FieldFunctions map[string]string

CompressData *string `json:"compress_data,omitempty"` // struct llm compress result

// extra data
Extra map[string]any `json:",omitempty"`
}

type Var struct {
Expand All @@ -623,4 +629,7 @@ type Var struct {
Groups []Identity `json:",omitempty"`

CompressData *string `json:"compress_data,omitempty"`

// extra data
Extra map[string]any `json:",omitempty"`
}
Loading