@@ -121,7 +121,9 @@ func (p *GoParser) parseVar(ctx *fileContext, vspec *ast.ValueSpec, isConst bool
121121
122122 // collect func value dependencies, in case of var a = func() {...}
123123 if val != nil && ! isConst {
124- collects := collectInfos {}
124+ collects := collectInfos {
125+ directCalls : map [FileLine ]bool {},
126+ }
125127 ast .Inspect (* val , func (n ast.Node ) bool {
126128 return p .parseASTNode (ctx , n , & collects )
127129 })
@@ -137,6 +139,20 @@ func (p *GoParser) parseVar(ctx *fileContext, vspec *ast.ValueSpec, isConst bool
137139 for _ , dep := range collects .tys {
138140 v .Dependencies = InsertDependency (v .Dependencies , dep )
139141 }
142+ if len (collects .directCalls ) > 0 {
143+ for i , dep := range v .Dependencies {
144+ if collects .directCalls [dep .FileLine ] {
145+ if v .Dependencies [i ].Extra == nil {
146+ v .Dependencies [i ].Extra = map [string ]any {}
147+ }
148+ v .Dependencies [i ].Extra ["FunctionIsCall" ] = true
149+ }
150+ }
151+ }
152+ if len (collects .anonymousFunctions ) > 0 {
153+ v .Extra = map [string ]any {}
154+ v .Extra ["AnonymousFunctions" ] = collects .anonymousFunctions
155+ }
140156 }
141157
142158 if vspec .Type != nil {
@@ -392,12 +408,19 @@ func (p *GoParser) parseSelector(ctx *fileContext, expr *ast.SelectorExpr, infos
392408type collectInfos struct {
393409 functionCalls , methodCalls []Dependency
394410 tys , globalVars []Dependency
411+
412+ directCalls map [FileLine ]bool
413+ anonymousFunctions []FileLine // record anonymous function
395414}
396415
397416func (p * GoParser ) parseASTNode (ctx * fileContext , node ast.Node , collect * collectInfos ) bool {
398417 switch expr := node .(type ) {
399418 case * ast.SelectorExpr :
400419 return p .parseSelector (ctx , expr , collect )
420+ case * ast.CallExpr :
421+ p .parseCall (ctx , expr , collect )
422+ case * ast.FuncLit :
423+ collect .anonymousFunctions = append (collect .anonymousFunctions , ctx .FileLine (expr ))
401424 case * ast.Ident :
402425 callName := expr .Name
403426 // println("[parseFunc] ast.Ident:", callName)
@@ -462,6 +485,22 @@ func (p *GoParser) parseASTNode(ctx *fileContext, node ast.Node, collect *collec
462485 return true
463486}
464487
488+ // parseCall collect direct call info
489+ func (p * GoParser ) parseCall (ctx * fileContext , expr * ast.CallExpr , collect * collectInfos ) {
490+ var ident * ast.Ident
491+
492+ switch idt := expr .Fun .(type ) {
493+ case * ast.Ident :
494+ ident = idt
495+ case * ast.SelectorExpr :
496+ ident = idt .Sel
497+ }
498+
499+ if ident != nil {
500+ collect .directCalls [ctx .FileLine (ident )] = true
501+ }
502+ }
503+
465504// parseFunc parses all function declaration in one file
466505func (p * GoParser ) parseFunc (ctx * fileContext , funcDecl * ast.FuncDecl ) (* Function , bool ) {
467506 // method receiver
@@ -511,7 +550,9 @@ func (p *GoParser) parseFunc(ctx *fileContext, funcDecl *ast.FuncDecl) (*Functio
511550 // collect content
512551 content := string (ctx .GetRawContent (funcDecl ))
513552
514- collects := collectInfos {}
553+ collects := collectInfos {
554+ directCalls : map [FileLine ]bool {},
555+ }
515556 if funcDecl .Body == nil {
516557 goto set_func
517558 }
@@ -521,7 +562,6 @@ func (p *GoParser) parseFunc(ctx *fileContext, funcDecl *ast.FuncDecl) (*Functio
521562 })
522563
523564set_func:
524-
525565 if fname == "init" && p .repo .GetFunction (NewIdentity (ctx .module .Name , ctx .pkgPath , fname )) != nil {
526566 // according to https://go.dev/ref/spec#Program_initialization_and_execution,
527567 // duplicated init() is allowed and never be referenced, thus add a subfix
@@ -544,6 +584,29 @@ set_func:
544584 f .Types = InsertDependency (f .Types , t )
545585 }
546586 f .Signature = string (sig )
587+
588+ if len (collects .directCalls ) > 0 {
589+ for i , dep := range f .FunctionCalls {
590+ if collects .directCalls [dep .FileLine ] {
591+ if f .FunctionCalls [i ].Extra == nil {
592+ f .FunctionCalls [i ].Extra = map [string ]any {}
593+ }
594+ f .FunctionCalls [i ].Extra ["FunctionIsCall" ] = true
595+ }
596+ }
597+ for i , dep := range f .MethodCalls {
598+ if collects .directCalls [dep .FileLine ] {
599+ if f .MethodCalls [i ].Extra == nil {
600+ f .MethodCalls [i ].Extra = map [string ]any {}
601+ }
602+ f .MethodCalls [i ].Extra ["FunctionIsCall" ] = true
603+ }
604+ }
605+ }
606+ if len (collects .anonymousFunctions ) > 0 {
607+ f .Extra = map [string ]any {}
608+ f .Extra ["AnonymousFunctions" ] = collects .anonymousFunctions
609+ }
547610 return f , false
548611}
549612
0 commit comments