|
4 | 4 | "crypto/sha1" |
5 | 5 | "encoding/hex" |
6 | 6 | "fmt" |
| 7 | + "go/ast" |
7 | 8 | "go/parser" |
8 | 9 | "go/token" |
9 | 10 | "os" |
@@ -459,6 +460,8 @@ func listImports(rootPackage, libRoot, pkg string) <-chan util.Packages { |
459 | 460 | } |
460 | 461 | go func() { |
461 | 462 | defer close(sch) |
| 463 | + |
| 464 | + // Gather all the Go imports |
462 | 465 | ps, err := parser.ParseDir(token.NewFileSet(), pkgPath, noVendoredTests, parser.ImportsOnly) |
463 | 466 | if err != nil { |
464 | 467 | if os.IsNotExist(err) { |
@@ -486,6 +489,50 @@ func listImports(rootPackage, libRoot, pkg string) <-chan util.Packages { |
486 | 489 | } |
487 | 490 | } |
488 | 491 | } |
| 492 | + // Gather all the CGO imports |
| 493 | + ps, err = parser.ParseDir(token.NewFileSet(), pkgPath, noVendoredTests, parser.ParseComments) |
| 494 | + if err != nil { |
| 495 | + if os.IsNotExist(err) { |
| 496 | + logrus.Debugf("listImports, pkgPath does not exist: %s", err) |
| 497 | + } else { |
| 498 | + logrus.Errorf("Error parsing comments, pkgPath: '%s', err: '%s'", pkgPath, err) |
| 499 | + } |
| 500 | + return |
| 501 | + } |
| 502 | + logrus.Infof("Collecting CGO imports for package '%s'", pkg) |
| 503 | + for _, p := range ps { |
| 504 | + for _, f := range p.Files { |
| 505 | + // Drill down to locate C preable definitions |
| 506 | + for _, decl := range f.Decls { |
| 507 | + d, ok := decl.(*ast.GenDecl) |
| 508 | + if !ok { |
| 509 | + continue |
| 510 | + } |
| 511 | + for _, spec := range d.Specs { |
| 512 | + s, ok := spec.(*ast.ImportSpec) |
| 513 | + if !ok || s.Path.Value != `"C"` { |
| 514 | + continue |
| 515 | + } |
| 516 | + cg := s.Doc |
| 517 | + if cg == nil && len(d.Specs) == 1 { |
| 518 | + cg = d.Doc |
| 519 | + } |
| 520 | + if cg != nil { |
| 521 | + // Extract any includes from the preamble |
| 522 | + for _, line := range strings.Split(cg.Text(), "\n") { |
| 523 | + if line = strings.TrimSpace(line); strings.HasPrefix(line, "#include \"") { |
| 524 | + if includePath := filepath.Dir(line[10 : len(line)-1]); includePath != "." { |
| 525 | + if _, err := os.Stat(filepath.Join(pkgPath, includePath)); !os.IsNotExist(err) { |
| 526 | + sch <- filepath.Clean(filepath.Join(pkg, includePath)) |
| 527 | + } |
| 528 | + } |
| 529 | + } |
| 530 | + } |
| 531 | + } |
| 532 | + } |
| 533 | + } |
| 534 | + } |
| 535 | + } |
489 | 536 | }() |
490 | 537 | lnc := util.MergeStrChans(sch, util.OneStr(pkg)) |
491 | 538 | return chanPackagesFromLines(lnc) |
|
0 commit comments