Skip to content

Commit 651208e

Browse files
committed
feat:(go) support mock identity for unloaded symobols
1 parent aaa32a8 commit 651208e

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

lang/golang/parser/ctx.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,41 @@ func (ctx *fileContext) GetTypeId(typ ast.Expr) (x Identity, isPointer bool, isS
252252
if tinfo, ok := ctx.pkgTypeInfo.Types[typ]; ok {
253253
return ctx.getIdFromType(tinfo.Type)
254254
} else {
255-
panic("cannot find type info for " + string(ctx.GetRawContent(typ)))
255+
// NOTICE: for unloaded type, we only mock the type name
256+
fmt.Fprintf(os.Stderr, "cannot find type info for %s\n", ctx.GetRawContent(typ))
257+
return ctx.mockType(typ)
256258
}
257259
}
258260

261+
func (ctx *fileContext) mockType(typ ast.Expr) (x Identity, isPointer bool, isStdOrBuiltin bool) {
262+
switch ty := typ.(type) {
263+
case *ast.StarExpr:
264+
id, _, std := ctx.mockType(ty.X)
265+
return id, true, std
266+
case *ast.CallExpr:
267+
// try get func type
268+
id, _, std := ctx.mockType(ty.Fun)
269+
return id, false, std
270+
case *ast.SelectorExpr:
271+
// try get import path
272+
switch xx := ty.X.(type) {
273+
case *ast.Ident:
274+
impt, mod, err := ctx.imports.GetImportPath(xx.Name, "")
275+
if err != nil {
276+
goto fallback
277+
}
278+
return NewIdentity(mod, PkgPath(impt), ty.Sel.Name), false, false
279+
case *ast.SelectorExpr:
280+
// recurse
281+
id, _, std := ctx.mockType(xx)
282+
return NewIdentity(id.ModPath, id.PkgPath, ty.Sel.Name), false, std
283+
}
284+
}
285+
286+
fallback:
287+
return NewIdentity("UNLOADED", ctx.pkgPath, string(ctx.GetRawContent(typ))), false, true
288+
}
289+
259290
func (ctx *fileContext) collectFields(fields []*ast.Field, m *[]Dependency) {
260291
for _, fieldDecl := range fields {
261292
id, _, isStdOrBuiltin := ctx.GetTypeId(fieldDecl.Type)

lang/golang/parser/parser.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,16 @@ func (p *GoParser) ParseRepo() (Repository, error) {
143143
}
144144

145145
func (p *GoParser) ParseModule(mod *Module, dir string) (err error) {
146-
filepath.Walk(dir, func(path string, info fs.FileInfo, e error) error {
147-
// run go mod tidy before parse
148-
cmd := exec.Command("go", "mod", "tidy")
149-
cmd.Dir = dir
150-
buf := bytes.NewBuffer(nil)
151-
cmd.Stderr = buf
152-
if err := cmd.Run(); err != nil {
153-
return fmt.Errorf("run go mod tidy failed in %s: %v", dir, buf.String())
154-
}
146+
// run go mod tidy before parse
147+
cmd := exec.Command("go", "mod", "tidy")
148+
cmd.Dir = dir
149+
buf := bytes.NewBuffer(nil)
150+
cmd.Stderr = buf
151+
if err := cmd.Run(); err != nil {
152+
fmt.Fprintf(os.Stderr, "run go mod tidy failed in %s: %v\n", dir, buf.String())
153+
}
155154

155+
filepath.Walk(dir, func(path string, info fs.FileInfo, e error) error {
156156
if info != nil && info.IsDir() && filepath.Base(path) == ".git" {
157157
return filepath.SkipDir
158158
}
@@ -163,6 +163,7 @@ func (p *GoParser) ParseModule(mod *Module, dir string) (err error) {
163163
mod.Files[rel] = NewFile(rel)
164164
return nil
165165
})
166+
166167
return p.loadPackages(mod, dir, "./...")
167168
}
168169

lang/uniast/ast.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ type Identity struct {
279279

280280
func NewIdentity(mod, pkg, name string) Identity {
281281
if mod == "" {
282-
fmt.Fprintf(os.Stderr, "module name cannot be empty: %s.%s\n", pkg, name)
282+
fmt.Fprintf(os.Stderr, "module name cannot be empty: %s#%s\n", pkg, name)
283283
// panic(fmt.Sprintf("module name cannot be empty: %s.%s", pkg, name))
284284
}
285285
return Identity{ModPath: mod, PkgPath: pkg, Name: name}

0 commit comments

Comments
 (0)