buildPackage parses a package and extracts its reference graph. It should only be called from Package.
(ctx context.Context, id metadata.PackageID)
| 123 | // buildPackage parses a package and extracts its reference graph. It should |
| 124 | // only be called from Package. |
| 125 | func (g *PackageGraph) buildPackage(ctx context.Context, id metadata.PackageID) (*Package, error) { |
| 126 | p := &Package{ |
| 127 | metapkg: g.meta.Metadata(id), |
| 128 | transitiveRefs: make(map[string]*typerefs.PackageSet), |
| 129 | } |
| 130 | var files []*parsego.File |
| 131 | for _, filename := range p.metapkg.CompiledGoFiles { |
| 132 | f, err := g.parse(ctx, filename) |
| 133 | if err != nil { |
| 134 | return nil, err |
| 135 | } |
| 136 | files = append(files, f) |
| 137 | } |
| 138 | imports := make(map[metadata.ImportPath]*metadata.Package) |
| 139 | for impPath, depID := range p.metapkg.DepsByImpPath { |
| 140 | if depID != "" { |
| 141 | imports[impPath] = g.meta.Metadata(depID) |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | // Compute the symbol-level dependencies through this package. |
| 146 | data := typerefs.Encode(files, imports) |
| 147 | |
| 148 | // data can be persisted in a filecache, keyed |
| 149 | // by hash(id, CompiledGoFiles, imports). |
| 150 | |
| 151 | // This point separates the local preprocessing |
| 152 | // -- of a single package (above) from the global -- |
| 153 | // transitive reachability query (below). |
| 154 | |
| 155 | // classes records syntactic edges between declarations in this |
| 156 | // package and declarations in this package or another |
| 157 | // package. See the package documentation for a detailed |
| 158 | // description of what these edges do (and do not) represent. |
| 159 | classes := typerefs.Decode(g.pkgIndex, data) |
| 160 | |
| 161 | // Debug |
| 162 | if trace && len(classes) > 0 { |
| 163 | var buf bytes.Buffer |
| 164 | fmt.Fprintf(&buf, "%s\n", id) |
| 165 | for _, class := range classes { |
| 166 | for i, name := range class.Decls { |
| 167 | if i == 0 { |
| 168 | fmt.Fprintf(&buf, "\t") |
| 169 | } |
| 170 | fmt.Fprintf(&buf, " .%s", name) |
| 171 | } |
| 172 | // Group symbols by package. |
| 173 | var prevID PackageID |
| 174 | for _, sym := range class.Refs { |
| 175 | id := g.pkgIndex.DeclaringPackage(sym) |
| 176 | if id != prevID { |
| 177 | prevID = id |
| 178 | fmt.Fprintf(&buf, "\n\t\t-> %s:", id) |
| 179 | } |
| 180 | fmt.Fprintf(&buf, " .%s", sym.Name) |
| 181 | } |
| 182 | fmt.Fprintln(&buf) |
no test coverage detected