Skip to content

Commit

Permalink
gopls/internal: move Options and FileKind from View to Snapshot
Browse files Browse the repository at this point in the history
In preparation for making snapshots truly idempotent, move certain
methods that depend on settings into the snapshot. Nothing should access
settings through the View.

For golang/go#42814

Change-Id: Ib3ced985dc89515f5a6e6049c7be316342706e54
Reviewed-on: https://go-review.googlesource.com/c/tools/+/524837
Run-TryBot: Robert Findley <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Alan Donovan <[email protected]>
  • Loading branch information
findleyr committed Sep 1, 2023
1 parent 1bfa8e3 commit 5fc00b4
Show file tree
Hide file tree
Showing 39 changed files with 92 additions and 87 deletions.
2 changes: 1 addition & 1 deletion gopls/internal/lsp/cache/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (s *snapshot) load(ctx context.Context, allowNetwork bool, scopes ...loadSc
panic(fmt.Sprintf("internal error: load called with multiple scopes when a file scope is present (file: %s)", uri))
}
fh := s.FindFile(uri)
if fh == nil || s.View().FileKind(fh) != source.Go {
if fh == nil || s.FileKind(fh) != source.Go {
// Don't try to load a file that doesn't exist, or isn't a go file.
continue
}
Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/cache/mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func sumFilename(modURI span.URI) string {
func (s *snapshot) ModWhy(ctx context.Context, fh source.FileHandle) (map[string]string, error) {
uri := fh.URI()

if s.View().FileKind(fh) != source.Mod {
if s.FileKind(fh) != source.Mod {
return nil, fmt.Errorf("%s is not a go.mod file", uri)
}

Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/cache/mod_tidy.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func modTidyDiagnostics(ctx context.Context, snapshot *snapshot, pm *source.Pars
for _, req := range wrongDirectness {
// Handle dependencies that are incorrectly labeled indirect and
// vice versa.
srcDiag, err := directnessDiagnostic(pm.Mapper, req, snapshot.View().Options().ComputeEdits)
srcDiag, err := directnessDiagnostic(pm.Mapper, req, snapshot.Options().ComputeEdits)
if err != nil {
// We're probably in a bad state if we can't compute a
// directnessDiagnostic, but try to keep going so as to not suppress
Expand Down
10 changes: 9 additions & 1 deletion gopls/internal/lsp/cache/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,14 @@ func (s *snapshot) View() source.View {
return s.view
}

func (s *snapshot) FileKind(h source.FileHandle) source.FileKind {
return s.view.FileKind(h)
}

func (s *snapshot) Options() *source.Options {
return s.view.Options() // temporarily return view options.
}

func (s *snapshot) BackgroundContext() context.Context {
return s.backgroundCtx
}
Expand Down Expand Up @@ -894,7 +902,7 @@ const fileExtensions = "go,mod,sum,work"

func (s *snapshot) fileWatchingGlobPatterns(ctx context.Context) map[string]struct{} {
extensions := fileExtensions
for _, ext := range s.View().Options().TemplateExtensions {
for _, ext := range s.Options().TemplateExtensions {
extensions += "," + ext
}
// Work-around microsoft/vscode#100870 by making sure that we are,
Expand Down
10 changes: 5 additions & 5 deletions gopls/internal/lsp/code_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionPara
uri := fh.URI()

// Determine the supported actions for this file kind.
kind := snapshot.View().FileKind(fh)
supportedCodeActions, ok := snapshot.View().Options().SupportedCodeActions[kind]
kind := snapshot.FileKind(fh)
supportedCodeActions, ok := snapshot.Options().SupportedCodeActions[kind]
if !ok {
return nil, fmt.Errorf("no supported code actions for %v file kind", kind)
}
Expand Down Expand Up @@ -185,7 +185,7 @@ func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionPara
}

var stubMethodsDiagnostics []protocol.Diagnostic
if wantQuickFixes && snapshot.View().Options().IsAnalyzerEnabled(stubmethods.Analyzer.Name) {
if wantQuickFixes && snapshot.Options().IsAnalyzerEnabled(stubmethods.Analyzer.Name) {
for _, pd := range diagnostics {
if stubmethods.MatchesMessage(pd.Message) {
stubMethodsDiagnostics = append(stubMethodsDiagnostics, pd)
Expand Down Expand Up @@ -453,7 +453,7 @@ func refactorRewrite(ctx context.Context, snapshot source.Snapshot, pkg source.P
//
// TODO: Consider removing the inspection after convenienceAnalyzers are removed.
inspect := inspector.New([]*ast.File{pgf.File})
if snapshot.View().Options().IsAnalyzerEnabled(fillstruct.Analyzer.Name) {
if snapshot.Options().IsAnalyzerEnabled(fillstruct.Analyzer.Name) {
for _, d := range fillstruct.DiagnoseFillableStructs(inspect, start, end, pkg.GetTypes(), pkg.GetTypesInfo()) {
rng, err := pgf.Mapper.PosRange(pgf.Tok, d.Pos, d.End)
if err != nil {
Expand All @@ -480,7 +480,7 @@ func refactorRewrite(ctx context.Context, snapshot source.Snapshot, pkg source.P
})
}

if snapshot.View().Options().IsAnalyzerEnabled(infertypeargs.Analyzer.Name) {
if snapshot.Options().IsAnalyzerEnabled(infertypeargs.Analyzer.Name) {
for _, d := range infertypeargs.DiagnoseInferableTypeArgs(pkg.FileSet(), inspect, start, end, pkg.GetTypes(), pkg.GetTypesInfo()) {
if len(d.SuggestedFixes) != 1 {
panic(fmt.Sprintf("unexpected number of suggested fixes from infertypeargs: %v", len(d.SuggestedFixes)))
Expand Down
4 changes: 2 additions & 2 deletions gopls/internal/lsp/code_lens.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (s *Server) codeLens(ctx context.Context, params *protocol.CodeLensParams)
return nil, err
}
var lenses map[command.Command]source.LensFunc
switch snapshot.View().FileKind(fh) {
switch snapshot.FileKind(fh) {
case source.Mod:
lenses = mod.LensFuncs()
case source.Go:
Expand All @@ -38,7 +38,7 @@ func (s *Server) codeLens(ctx context.Context, params *protocol.CodeLensParams)
}
var result []protocol.CodeLens
for cmd, lf := range lenses {
if !snapshot.View().Options().Codelenses[string(cmd)] {
if !snapshot.Options().Codelenses[string(cmd)] {
continue
}
added, err := lf(ctx, snapshot, fh)
Expand Down
9 changes: 4 additions & 5 deletions gopls/internal/lsp/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ func dropDependency(snapshot source.Snapshot, pm *source.ParsedModule, modulePat
return nil, err
}
// Calculate the edits to be made due to the change.
diff := snapshot.View().Options().ComputeEdits(string(pm.Mapper.Content), string(newContent))
diff := snapshot.Options().ComputeEdits(string(pm.Mapper.Content), string(newContent))
return source.ToProtocolEdits(pm.Mapper, diff)
}

Expand Down Expand Up @@ -633,7 +633,7 @@ func collectFileEdits(ctx context.Context, snapshot source.Snapshot, uri span.UR
}

m := protocol.NewMapper(fh.URI(), oldContent)
diff := snapshot.View().Options().ComputeEdits(string(oldContent), string(newContent))
diff := snapshot.Options().ComputeEdits(string(oldContent), string(newContent))
edits, err := source.ToProtocolEdits(m, diff)
if err != nil {
return nil, err
Expand Down Expand Up @@ -899,7 +899,7 @@ type pkgLoadConfig struct {
func (c *commandHandler) FetchVulncheckResult(ctx context.Context, arg command.URIArg) (map[protocol.DocumentURI]*govulncheck.Result, error) {
ret := map[protocol.DocumentURI]*govulncheck.Result{}
err := c.run(ctx, commandConfig{forURI: arg.URI}, func(ctx context.Context, deps commandDeps) error {
if deps.snapshot.View().Options().Vulncheck == source.ModeVulncheckImports {
if deps.snapshot.Options().Vulncheck == source.ModeVulncheckImports {
for _, modfile := range deps.snapshot.ModFiles() {
res, err := deps.snapshot.ModVuln(ctx, modfile)
if err != nil {
Expand Down Expand Up @@ -936,8 +936,7 @@ func (c *commandHandler) RunGovulncheck(ctx context.Context, args command.Vulnch
}, func(ctx context.Context, deps commandDeps) error {
tokenChan <- deps.work.Token()

view := deps.snapshot.View()
opts := view.Options()
opts := deps.snapshot.Options()
// quickly test if gopls is compiled to support govulncheck
// by checking vulncheck.Main. Alternatively, we can continue and
// let the `gopls vulncheck` command fail. This is lighter-weight.
Expand Down
4 changes: 2 additions & 2 deletions gopls/internal/lsp/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (s *Server) completion(ctx context.Context, params *protocol.CompletionPara
}
var candidates []completion.CompletionItem
var surrounding *completion.Selection
switch snapshot.View().FileKind(fh) {
switch snapshot.FileKind(fh) {
case source.Go:
candidates, surrounding, err = completion.Completion(ctx, snapshot, fh, params.Position, params.Context)
case source.Mod:
Expand Down Expand Up @@ -65,7 +65,7 @@ func (s *Server) completion(ctx context.Context, params *protocol.CompletionPara

// When using deep completions/fuzzy matching, report results as incomplete so
// client fetches updated completions after every key stroke.
options := snapshot.View().Options()
options := snapshot.Options()
incompleteResults := options.DeepCompletion || options.Matcher == source.Fuzzy

items := toProtocolCompletionItems(candidates, rng, options)
Expand Down
4 changes: 2 additions & 2 deletions gopls/internal/lsp/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (s *Server) definition(ctx context.Context, params *protocol.DefinitionPara
if !ok {
return nil, err
}
switch kind := snapshot.View().FileKind(fh); kind {
switch kind := snapshot.FileKind(fh); kind {
case source.Tmpl:
return template.Definition(snapshot, fh, params.Position)
case source.Go:
Expand All @@ -51,7 +51,7 @@ func (s *Server) typeDefinition(ctx context.Context, params *protocol.TypeDefini
if !ok {
return nil, err
}
switch kind := snapshot.View().FileKind(fh); kind {
switch kind := snapshot.FileKind(fh); kind {
case source.Go:
return source.TypeDefinition(ctx, snapshot, fh, params.Position)
default:
Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (s *Server) diagnoseSnapshots(snapshots map[source.Snapshot][]span.URI, onD
diagnosticWG.Add(1)
go func(snapshot source.Snapshot, uris []span.URI) {
defer diagnosticWG.Done()
s.diagnoseSnapshot(snapshot, uris, onDisk, snapshot.View().Options().DiagnosticsDelay)
s.diagnoseSnapshot(snapshot, uris, onDisk, snapshot.Options().DiagnosticsDelay)
}(snapshot, uris)
}
diagnosticWG.Wait()
Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/folding_range.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (s *Server) foldingRange(ctx context.Context, params *protocol.FoldingRange
return nil, err
}

ranges, err := source.FoldingRange(ctx, snapshot, fh, snapshot.View().Options().LineFoldingOnly)
ranges, err := source.FoldingRange(ctx, snapshot, fh, snapshot.Options().LineFoldingOnly)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (s *Server) formatting(ctx context.Context, params *protocol.DocumentFormat
if !ok {
return nil, err
}
switch snapshot.View().FileKind(fh) {
switch snapshot.FileKind(fh) {
case source.Mod:
return mod.Format(ctx, snapshot, fh)
case source.Go:
Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/highlight.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (s *Server) documentHighlight(ctx context.Context, params *protocol.Documen
return nil, err
}

if snapshot.View().FileKind(fh) == source.Tmpl {
if snapshot.FileKind(fh) == source.Tmpl {
return template.Highlight(ctx, snapshot, fh, params.Position)
}

Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/hover.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*prot
if !ok {
return nil, err
}
switch snapshot.View().FileKind(fh) {
switch snapshot.FileKind(fh) {
case source.Mod:
return mod.Hover(ctx, snapshot, fh, params.Position)
case source.Go:
Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/inlay_hint.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (s *Server) inlayHint(ctx context.Context, params *protocol.InlayHintParams
if !ok {
return nil, err
}
switch snapshot.View().FileKind(fh) {
switch snapshot.FileKind(fh) {
case source.Mod:
return mod.InlayHint(ctx, snapshot, fh, params.Range)
case source.Go:
Expand Down
17 changes: 8 additions & 9 deletions gopls/internal/lsp/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (s *Server) documentLink(ctx context.Context, params *protocol.DocumentLink
if !ok {
return nil, err
}
switch snapshot.View().FileKind(fh) {
switch snapshot.FileKind(fh) {
case source.Mod:
links, err = modLinks(ctx, snapshot, fh)
case source.Go:
Expand Down Expand Up @@ -69,7 +69,7 @@ func modLinks(ctx context.Context, snapshot source.Snapshot, fh source.FileHandl
}
// Shift the start position to the location of the
// dependency within the require statement.
target := source.BuildLink(snapshot.View().Options().LinkTarget, "mod/"+req.Mod.String(), "")
target := source.BuildLink(snapshot.Options().LinkTarget, "mod/"+req.Mod.String(), "")
l, err := toProtocolLink(pm.Mapper, target, start+i, start+i+len(dep))
if err != nil {
return nil, err
Expand All @@ -82,7 +82,7 @@ func modLinks(ctx context.Context, snapshot source.Snapshot, fh source.FileHandl
}

// Get all the links that are contained in the comments of the file.
urlRegexp := snapshot.View().Options().URLRegexp
urlRegexp := snapshot.Options().URLRegexp
for _, expr := range pm.File.Syntax.Stmt {
comments := expr.Comment()
if comments == nil {
Expand All @@ -103,7 +103,6 @@ func modLinks(ctx context.Context, snapshot source.Snapshot, fh source.FileHandl

// goLinks returns the set of hyperlink annotations for the specified Go file.
func goLinks(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]protocol.DocumentLink, error) {
view := snapshot.View()

pgf, err := snapshot.ParseGo(ctx, fh, source.ParseFull)
if err != nil {
Expand All @@ -113,12 +112,12 @@ func goLinks(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle
var links []protocol.DocumentLink

// Create links for import specs.
if view.Options().ImportShortcut.ShowLinks() {
if snapshot.Options().ImportShortcut.ShowLinks() {

// If links are to pkg.go.dev, append module version suffixes.
// This requires the import map from the package metadata. Ignore errors.
var depsByImpPath map[source.ImportPath]source.PackageID
if strings.ToLower(view.Options().LinkTarget) == "pkg.go.dev" {
if strings.ToLower(snapshot.Options().LinkTarget) == "pkg.go.dev" {
if meta, err := source.NarrowestMetadataForFile(ctx, snapshot, fh.URI()); err == nil {
depsByImpPath = meta.DepsByImpPath
}
Expand All @@ -130,7 +129,7 @@ func goLinks(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle
continue // bad import
}
// See golang/go#36998: don't link to modules matching GOPRIVATE.
if view.IsGoPrivatePath(string(importPath)) {
if snapshot.View().IsGoPrivatePath(string(importPath)) {
continue
}

Expand All @@ -145,7 +144,7 @@ func goLinks(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle
if err != nil {
return nil, err
}
targetURL := source.BuildLink(view.Options().LinkTarget, urlPath, "")
targetURL := source.BuildLink(snapshot.Options().LinkTarget, urlPath, "")
// Account for the quotation marks in the positions.
l, err := toProtocolLink(pgf.Mapper, targetURL, start+len(`"`), end-len(`"`))
if err != nil {
Expand All @@ -155,7 +154,7 @@ func goLinks(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle
}
}

urlRegexp := snapshot.View().Options().URLRegexp
urlRegexp := snapshot.Options().URLRegexp

// Gather links found in string literals.
var str []*ast.BasicLit
Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/mod/diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func ModVulnerabilityDiagnostics(ctx context.Context, snapshot source.Snapshot,

diagSource := source.Govulncheck
vs := snapshot.View().Vulnerabilities(fh.URI())[fh.URI()]
if vs == nil && snapshot.View().Options().Vulncheck == source.ModeVulncheckImports {
if vs == nil && snapshot.Options().Vulncheck == source.ModeVulncheckImports {
vs, err = snapshot.ModVuln(ctx, fh.URI())
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/mod/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ func Format(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle)
return nil, err
}
// Calculate the edits to be made due to the change.
diffs := snapshot.View().Options().ComputeEdits(string(pm.Mapper.Content), string(formatted))
diffs := snapshot.Options().ComputeEdits(string(pm.Mapper.Content), string(formatted))
return source.ToProtocolEdits(pm.Mapper, diffs)
}
8 changes: 4 additions & 4 deletions gopls/internal/lsp/mod/hover.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func hoverOnRequireStatement(ctx context.Context, pm *source.ParsedModule, offse
// Get the vulnerability info.
fromGovulncheck := true
vs := snapshot.View().Vulnerabilities(fh.URI())[fh.URI()]
if vs == nil && snapshot.View().Options().Vulncheck == source.ModeVulncheckImports {
if vs == nil && snapshot.Options().Vulncheck == source.ModeVulncheckImports {
var err error
vs, err = snapshot.ModVuln(ctx, fh.URI())
if err != nil {
Expand All @@ -109,7 +109,7 @@ func hoverOnRequireStatement(ctx context.Context, pm *source.ParsedModule, offse
if err != nil {
return nil, err
}
options := snapshot.View().Options()
options := snapshot.Options()
isPrivate := snapshot.View().IsGoPrivatePath(req.Mod.Path)
header := formatHeader(req.Mod.Path, options)
explanation = formatExplanation(explanation, req, options, isPrivate)
Expand Down Expand Up @@ -140,7 +140,7 @@ func hoverOnModuleStatement(ctx context.Context, pm *source.ParsedModule, offset
fromGovulncheck := true
vs := snapshot.View().Vulnerabilities(fh.URI())[fh.URI()]

if vs == nil && snapshot.View().Options().Vulncheck == source.ModeVulncheckImports {
if vs == nil && snapshot.Options().Vulncheck == source.ModeVulncheckImports {
vs, err = snapshot.ModVuln(ctx, fh.URI())
if err != nil {
return nil, false
Expand All @@ -150,7 +150,7 @@ func hoverOnModuleStatement(ctx context.Context, pm *source.ParsedModule, offset
modpath := "stdlib"
goVersion := snapshot.View().GoVersionString()
affecting, nonaffecting := lookupVulns(vs, modpath, goVersion)
options := snapshot.View().Options()
options := snapshot.Options()
vulns := formatVulnerabilities(modpath, affecting, nonaffecting, options, fromGovulncheck)

return &protocol.Hover{
Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/lsp/references.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (s *Server) references(ctx context.Context, params *protocol.ReferenceParam
if !ok {
return nil, err
}
if snapshot.View().FileKind(fh) == source.Tmpl {
if snapshot.FileKind(fh) == source.Tmpl {
return template.References(ctx, snapshot, fh, params)
}
return source.References(ctx, snapshot, fh, params.Position, params.Context.IncludeDeclaration)
Expand Down
9 changes: 4 additions & 5 deletions gopls/internal/lsp/semantic.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,12 @@ func (s *Server) computeSemanticTokens(ctx context.Context, td protocol.TextDocu
if !ok {
return nil, err
}
vv := snapshot.View()
if !vv.Options().SemanticTokens {
if !snapshot.Options().SemanticTokens {
// return an error, so if the option changes
// the client won't remember the wrong answer
return nil, fmt.Errorf("semantictokens are disabled")
}
kind := snapshot.View().FileKind(fh)
kind := snapshot.FileKind(fh)
if kind == source.Tmpl {
// this is a little cumbersome to avoid both exporting 'encoded' and its methods
// and to avoid import cycles
Expand Down Expand Up @@ -111,8 +110,8 @@ func (s *Server) computeSemanticTokens(ctx context.Context, td protocol.TextDocu
fset: pkg.FileSet(),
tokTypes: s.session.Options().SemanticTypes,
tokMods: s.session.Options().SemanticMods,
noStrings: vv.Options().NoSemanticString,
noNumbers: vv.Options().NoSemanticNumber,
noStrings: snapshot.Options().NoSemanticString,
noNumbers: snapshot.Options().NoSemanticNumber,
}
if err := e.init(); err != nil {
// e.init should never return an error, unless there's some
Expand Down
Loading

0 comments on commit 5fc00b4

Please sign in to comment.