1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cache
import (
"fmt"
"go/ast"
"go/scanner"
"go/token"
"go/types"
"sync"
"cuelang.org/go/internal/golangorgx/gopls/cache/metadata"
"cuelang.org/go/internal/golangorgx/gopls/cache/methodsets"
"cuelang.org/go/internal/golangorgx/gopls/cache/parsego"
"cuelang.org/go/internal/golangorgx/gopls/cache/xrefs"
"cuelang.org/go/internal/golangorgx/gopls/protocol"
)
// Convenient aliases for very heavily used types.
type (
PackageID = metadata.PackageID
PackagePath = metadata.PackagePath
PackageName = metadata.PackageName
ImportPath = metadata.ImportPath
ParsedGoFile = parsego.File
)
const (
ParseHeader = parsego.ParseHeader
ParseFull = parsego.ParseFull
)
// A Package is the union of package metadata and type checking results.
//
// TODO(rfindley): for now, we do not persist the post-processing of
// loadDiagnostics, because the value of the snapshot.packages map is just the
// package handle. Fix this.
type Package struct {
metadata *metadata.Package
loadDiagnostics []*Diagnostic
pkg *syntaxPackage
}
// syntaxPackage contains parse trees and type information for a package.
type syntaxPackage struct {
// -- identifiers --
id PackageID
// -- outputs --
fset *token.FileSet // for now, same as the snapshot's FileSet
goFiles []*ParsedGoFile
compiledGoFiles []*ParsedGoFile
diagnostics []*Diagnostic
parseErrors []scanner.ErrorList
typeErrors []types.Error
types *types.Package
typesInfo *types.Info
importMap map[PackagePath]*types.Package
xrefsOnce sync.Once
_xrefs []byte // only used by the xrefs method
methodsetsOnce sync.Once
_methodsets *methodsets.Index // only used by the methodsets method
}
func (p *syntaxPackage) xrefs() []byte {
p.xrefsOnce.Do(func() {
p._xrefs = xrefs.Index(p.compiledGoFiles, p.types, p.typesInfo)
})
return p._xrefs
}
func (p *syntaxPackage) methodsets() *methodsets.Index {
p.methodsetsOnce.Do(func() {
p._methodsets = methodsets.NewIndex(p.fset, p.types)
})
return p._methodsets
}
func (p *Package) String() string { return string(p.metadata.ID) }
func (p *Package) Metadata() *metadata.Package { return p.metadata }
// A loadScope defines a package loading scope for use with go/packages.
//
// TODO(rfindley): move this to load.go.
type loadScope interface {
aScope()
}
type (
fileLoadScope protocol.DocumentURI // load packages containing a file (including command-line-arguments)
packageLoadScope string // load a specific package (the value is its PackageID)
moduleLoadScope struct {
dir string // dir containing the go.mod file
modulePath string // parsed module path
}
viewLoadScope struct{} // load the workspace
)
// Implement the loadScope interface.
func (fileLoadScope) aScope() {}
func (packageLoadScope) aScope() {}
func (moduleLoadScope) aScope() {}
func (viewLoadScope) aScope() {}
func (p *Package) CompiledGoFiles() []*ParsedGoFile {
return p.pkg.compiledGoFiles
}
func (p *Package) File(uri protocol.DocumentURI) (*ParsedGoFile, error) {
return p.pkg.File(uri)
}
func (pkg *syntaxPackage) File(uri protocol.DocumentURI) (*ParsedGoFile, error) {
for _, cgf := range pkg.compiledGoFiles {
if cgf.URI == uri {
return cgf, nil
}
}
for _, gf := range pkg.goFiles {
if gf.URI == uri {
return gf, nil
}
}
return nil, fmt.Errorf("no parsed file for %s in %v", uri, pkg.id)
}
func (p *Package) GetSyntax() []*ast.File {
var syntax []*ast.File
for _, pgf := range p.pkg.compiledGoFiles {
syntax = append(syntax, pgf.File)
}
return syntax
}
func (p *Package) FileSet() *token.FileSet {
return p.pkg.fset
}
func (p *Package) GetTypes() *types.Package {
return p.pkg.types
}
func (p *Package) GetTypesInfo() *types.Info {
return p.pkg.typesInfo
}
// DependencyTypes returns the type checker's symbol for the specified
// package. It returns nil if path is not among the transitive
// dependencies of p, or if no symbols from that package were
// referenced during the type-checking of p.
func (p *Package) DependencyTypes(path PackagePath) *types.Package {
return p.pkg.importMap[path]
}
func (p *Package) GetParseErrors() []scanner.ErrorList {
return p.pkg.parseErrors
}
func (p *Package) GetTypeErrors() []types.Error {
return p.pkg.typeErrors
}
|