Skip to content

Commit 80d7d2e

Browse files
committed
fix(java): resolve internal method calls using two-pass approach
When a method calls another method that is defined later in the same class, the current single-pass logic fails to find the callee method symbol and creates a stub. This commit introduces a two-pass approach within `processClass`: 1. Iterate over methods and create definitions/symbols. 2. Iterate over methods again to process method calls and resolve them against the symbols created in the first pass.
1 parent 957f720 commit 80d7d2e

4 files changed

Lines changed: 34 additions & 12 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ require (
2323
github.com/stretchr/testify v1.10.0
2424
github.com/vifraa/gopom v1.0.0
2525
golang.org/x/mod v0.24.0
26+
golang.org/x/sync v0.13.0
2627
golang.org/x/tools v0.32.0
2728
)
2829

@@ -91,7 +92,6 @@ require (
9192
golang.org/x/arch v0.14.0 // indirect
9293
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect
9394
golang.org/x/net v0.39.0 // indirect
94-
golang.org/x/sync v0.13.0 // indirect
9595
golang.org/x/sys v0.33.0 // indirect
9696
golang.org/x/text v0.24.0 // indirect
9797
gopkg.in/yaml.v2 v2.4.0 // indirect

lang/collect/collect.go

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import (
2626
"sync"
2727
"unicode"
2828

29-
"golang.org/x/sync/errgroup"
3029
sitter "github.com/smacker/go-tree-sitter"
30+
"golang.org/x/sync/errgroup"
3131

3232
"github.com/cloudwego/abcoder/lang/cpp"
3333
"github.com/cloudwego/abcoder/lang/cxx"
@@ -819,7 +819,13 @@ func (c *Collector) ScannerByJavaIPC(ctx context.Context) ([]*DocumentSymbol, er
819819
}
820820
}
821821

822-
// 4) Methods (and method calls)
822+
// 4) Methods (Pass 1: Definitions)
823+
type methodAndSym struct {
824+
m *javapb.MethodDetail
825+
msym *DocumentSymbol
826+
}
827+
var methodSyms []methodAndSym
828+
823829
for _, m := range ci.Methods {
824830
if m == nil {
825831
continue
@@ -906,12 +912,23 @@ func (c *Collector) ScannerByJavaIPC(ctx context.Context) ([]*DocumentSymbol, er
906912
}
907913
}
908914
c.funcs[msym] = finfo
915+
methodSyms = append(methodSyms, methodAndSym{m: m, msym: msym})
916+
}
917+
918+
// 5) Process method calls (Pass 2)
919+
for _, pair := range methodSyms {
920+
m := pair.m
921+
msym := pair.msym
909922

910-
// Method calls
911923
for _, call := range m.MethodCalls {
912-
if call == nil || call.CalleeClass == "" {
924+
if call == nil {
913925
continue
914926
}
927+
928+
if call.CalleeClass == "" {
929+
continue
930+
}
931+
915932
calleeInfo := resolveClass(call.CalleeClass)
916933
if calleeInfo == nil {
917934
// drop if callee class can't be resolved
@@ -930,23 +947,29 @@ func (c *Collector) ScannerByJavaIPC(ctx context.Context) ([]*DocumentSymbol, er
930947
if call.CalleeMethod != "" {
931948
if s, ok := methodSymByKey[methodKey(call.CalleeClass, call.CalleeMethod)]; ok {
932949
calleeMethodSym = s
950+
} else {
951+
shortName := call.CalleeMethod
952+
if idx := strings.IndexByte(shortName, '('); idx >= 0 {
953+
shortName = shortName[:idx]
954+
}
955+
parts := strings.Split(shortName, " ")
956+
shortName = parts[len(parts)-1]
957+
if s, ok := methodSymByKey[methodKey(call.CalleeClass, shortName)]; ok {
958+
calleeMethodSym = s
959+
}
933960
}
934961
}
935962
if calleeMethodSym == nil {
936963
// Create a lightweight stub method symbol (one-layer only).
937964
// IMPORTANT: do NOT put it into c.syms to avoid clobbering class symbols.
938965
stubLoc := Location{URI: calleeClassSym.Location.URI, Range: Range{Start: calleeClassSym.Location.Range.Start, End: calleeClassSym.Location.Range.Start}}
939966
calleeMethodSym = &DocumentSymbol{
940-
Name: call.CalleeMethod,
967+
Name: calleeClassSym.Name + "." + call.CalleeMethod,
941968
Kind: SKMethod,
942969
Text: "",
943970
Location: stubLoc,
944971
Role: DEFINITION,
945972
}
946-
947-
if _, ok := localByName[call.CalleeClass]; !ok {
948-
calleeMethodSym.Name = call.CalleeClass + "." + call.CalleeMethod
949-
}
950973
}
951974

952975
tokFile := normalizePath(call.FilePath)

lang/golang/parser/pkg.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,6 @@ func (p *GoParser) loadPackages(mod *Module, dir string, pkgPath PkgPath) (err e
208208
return fmt.Errorf("load path '%s' with CGO failed: %v", dir, err)
209209
}
210210
} else {
211-
cfg.Env = append(cfg.Env, "CGO_ENABLED=0")
212211
pkgs, err = packages.Load(cfg, pkgPath)
213212
if err != nil {
214213
return fmt.Errorf("load path '%s' failed: %v", dir, err)

testdata/asts/localsession_g.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)