Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion docs/uniast-en.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ Represents a dependency relationship, containing the dependent node Id, dependen
- Extra: Additional information for storing language-specific details or extra metadata


- IsInvoked: For function/method dependencies, whether it is invoked or just referenced (not executed).
- IsInvoked: For function/method dependencies, or for GlobalVars dependencies whose target is a func-typed global variable, whether it is invoked or just referenced (not executed). For example, given `var Foo = func() {...}`, if another function body contains `Foo()`, the corresponding dependency in that function's `GlobalVars` is marked `IsInvoked: true`; a plain reference such as `_ = Foo` is not marked.


##### Type
Expand Down
2 changes: 1 addition & 1 deletion docs/uniast-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ Universal Abstract-Syntax-Tree 是 ABCoder 建立的一种 LLM 亲和、语言
- Extra: 额外信息,用于存储一些语言特定的信息,或者是一些额外的元数据


- IsInvoked: 对于函数 / 方法调用类依赖,用于说明该函数是被调用(invoke),还是仅获取其引用而不执行。
- IsInvoked: 对于函数 / 方法调用类依赖,或函数型全局变量(GlobalVars)类依赖,用于说明该函数 / 全局变量是被调用(invoke),还是仅获取其引用而不执行。例如 `var Foo = func() {...}` 时,若另一函数体内出现 `Foo()`,则其在该函数 `GlobalVars` 中的依赖会被标记 `IsInvoked: true`;若仅出现 `_ = Foo` 等纯引用,则不会被标记


##### Type
Expand Down
5 changes: 5 additions & 0 deletions lang/golang/parser/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,11 @@ set_func:
f.MethodCalls[i].SetExtra(ExtraKey_IsInvoked, true)
}
}
for i, dep := range f.GlobalVars {
if collects.directCalls[dep.FileLine] {
f.GlobalVars[i].SetExtra(ExtraKey_IsInvoked, true)
}
}
}
if len(collects.anonymousFunctions) > 0 {
f.SetExtra(ExtraKey_AnonymousFunctions, collects.anonymousFunctions)
Expand Down
44 changes: 44 additions & 0 deletions lang/golang/parser/pkg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,50 @@ func Test_goParser_ParseDirs(t *testing.T) {
}
}

func Test_goParser_GlobalFuncVar_IsInvoked(t *testing.T) {
p := newGoParser("a.b/c", testutils.FirstTest("go"), Options{LoadByPackages: true})
pkgPath := "a.b/c/pkg"
if err := p.parsePackage(pkgPath); err != nil {
t.Fatalf("parsePackage failed: %v", err)
}
var6 := NewIdentity("a.b/c", pkgPath, "Var6")

// Case_Invoke_GlobalFuncVar() directly calls Var6() -> IsInvoked must be true.
invokeFn := p.repo.GetFunction(NewIdentity("a.b/c", pkgPath, "Case_Invoke_GlobalFuncVar"))
if invokeFn == nil {
t.Fatalf("function Case_Invoke_GlobalFuncVar not found")
}
dep := findDep(invokeFn.GlobalVars, var6)
if dep == nil {
t.Fatalf("Var6 not found in GlobalVars of Case_Invoke_GlobalFuncVar")
}
if v, _ := dep.GetExtra(ExtraKey_IsInvoked).(bool); !v {
t.Fatalf("expected Var6 to be marked IsInvoked=true in Case_Invoke_GlobalFuncVar, got Extra=%+v", dep.Extra)
}

// Case_Func_Global() only references Var6 (no call) -> IsInvoked must be unset.
refFn := p.repo.GetFunction(NewIdentity("a.b/c", pkgPath, "Case_Func_Global"))
if refFn == nil {
t.Fatalf("function Case_Func_Global not found")
}
dep = findDep(refFn.GlobalVars, var6)
if dep == nil {
t.Fatalf("Var6 not found in GlobalVars of Case_Func_Global")
}
if v, _ := dep.GetExtra(ExtraKey_IsInvoked).(bool); v {
t.Fatalf("expected Var6 to NOT be marked IsInvoked in Case_Func_Global")
}
}

func findDep(deps []Dependency, id Identity) *Dependency {
for i := range deps {
if deps[i].Identity == id {
return &deps[i]
}
}
return nil
}

func TestGoAst(t *testing.T) {
src := `
package parse
Expand Down
7 changes: 7 additions & 0 deletions testdata/go/0_golang/pkg/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ func Case_Func_Global() {
_ = entity.V1
}

// Case_Invoke_GlobalFuncVar directly invokes a global var that holds a func value.
// Used to verify that the GlobalVars dependency for Var6 is marked IsInvoked=true,
// while a pure reference (e.g. in Case_Func_Global) is not.
func Case_Invoke_GlobalFuncVar() {
Var6()
}

// Type is Result type
type Type int

Expand Down
Loading