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
|
// 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 (
"go/ast"
"go/scanner"
"go/types"
"golang.org/x/mod/module"
"golang.org/x/tools/internal/lsp/source"
"golang.org/x/tools/internal/span"
errors "golang.org/x/xerrors"
)
// pkg contains the type information needed by the source package.
type pkg struct {
m *Metadata
mode source.ParseMode
goFiles []*source.ParsedGoFile
compiledGoFiles []*source.ParsedGoFile
diagnostics []*source.Diagnostic
imports map[PackagePath]*pkg
version *module.Version
parseErrors []scanner.ErrorList
typeErrors []types.Error
types *types.Package
typesInfo *types.Info
typesSizes types.Sizes
hasFixedFiles bool // if true, AST was sufficiently mangled that we should hide type errors
}
// Declare explicit types for files and directories to distinguish between the two.
type (
fileURI span.URI
moduleLoadScope string
viewLoadScope span.URI
)
func (p *pkg) ID() string {
return string(p.m.ID)
}
func (p *pkg) Name() string {
return string(p.m.Name)
}
func (p *pkg) PkgPath() string {
return string(p.m.PkgPath)
}
func (p *pkg) ParseMode() source.ParseMode {
return p.mode
}
func (p *pkg) CompiledGoFiles() []*source.ParsedGoFile {
return p.compiledGoFiles
}
func (p *pkg) File(uri span.URI) (*source.ParsedGoFile, error) {
for _, cgf := range p.compiledGoFiles {
if cgf.URI == uri {
return cgf, nil
}
}
for _, gf := range p.goFiles {
if gf.URI == uri {
return gf, nil
}
}
return nil, errors.Errorf("no parsed file for %s in %v", uri, p.m.ID)
}
func (p *pkg) GetSyntax() []*ast.File {
var syntax []*ast.File
for _, pgf := range p.compiledGoFiles {
syntax = append(syntax, pgf.File)
}
return syntax
}
func (p *pkg) GetTypes() *types.Package {
return p.types
}
func (p *pkg) GetTypesInfo() *types.Info {
return p.typesInfo
}
func (p *pkg) GetTypesSizes() types.Sizes {
return p.typesSizes
}
func (p *pkg) IsIllTyped() bool {
return p.types == nil || p.typesInfo == nil || p.typesSizes == nil
}
func (p *pkg) ForTest() string {
return string(p.m.ForTest)
}
func (p *pkg) GetImport(pkgPath string) (source.Package, error) {
if imp := p.imports[PackagePath(pkgPath)]; imp != nil {
return imp, nil
}
// Don't return a nil pointer because that still satisfies the interface.
return nil, errors.Errorf("no imported package for %s", pkgPath)
}
func (p *pkg) MissingDependencies() []string {
// We don't invalidate metadata for import deletions, so check the package
// imports via the *types.Package. Only use metadata if p.types is nil.
if p.types == nil {
var md []string
for i := range p.m.MissingDeps {
md = append(md, string(i))
}
return md
}
var md []string
for _, pkg := range p.types.Imports() {
if _, ok := p.m.MissingDeps[PackagePath(pkg.Path())]; ok {
md = append(md, pkg.Path())
}
}
return md
}
func (p *pkg) Imports() []source.Package {
var result []source.Package
for _, imp := range p.imports {
result = append(result, imp)
}
return result
}
func (p *pkg) Version() *module.Version {
return p.version
}
func (p *pkg) HasListOrParseErrors() bool {
return len(p.m.Errors) != 0 || len(p.parseErrors) != 0
}
func (p *pkg) HasTypeErrors() bool {
return len(p.typeErrors) != 0
}
|