Commit Graph

2925 Commits

Author SHA1 Message Date
Robert Findley 4d0b383458 internal/lsp/regtest: minor cleanup for magic regtest envvar
For some reason, we were not reusing the constant runTestAsGoplsEnvVar
in the regtest Main function. Fix this, add a bit more commentary, and
check the envvar before doing anything else. Also fix the threading of
hooks to the created gopls server.

Tested manually via -enable_gopls_subprocess_tests.

Change-Id: Ieb5329aa5850e845f4d9e3868703bfa16387bce3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/420716
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-08-02 16:05:48 +00:00
Dylan Le bd3f524777 internal/lsp: rename all the package names in the renamed package
This CL contains a partial implementation of package renaming. Currently gopls is only able to rename references to the renaming package within the renaming package itself.

prepareRename is still expected to return an error for renaming a package.

For golang/go#41567

Change-Id: I3683a0a7128bba7620ef30db528f45b753e6c08f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/420219
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Dylan Le <dungtuanle@google.com>
2022-08-01 17:28:00 +00:00
Robert Findley 9f65685098 internal/lsp/source: enable the new diff with allExperiments
When enabling all experiments (done by VS Code nightly), switch to the
checked version of the new diff implementation.

Also remove some experimental settings that are now on by default.

Updates golang/go#52967

Change-Id: Id272c4a646006a739e49d48f0f09b2f8b0982bab
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419981
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Peter Weinberger <pjw@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-08-01 13:49:32 +00:00
Dylan Le 9580c84d57 internal/lsp: Check if user's editor support rename operation
Change-Id: Iadda768e93eda1d53fa00a5ff8a28013a575ef57
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419774
Run-TryBot: Dylan Le <dungtuanle@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-29 20:19:23 +00:00
Robert Findley f560bc877f internal/lsp/cache: don't set context cancellation as a critical err
Fix a tricky race in gopls/internal/regtest/diagnostics.Test_Issue38211:
When reloading the workspace, we can encounter context cancellation if
the snapshot is cancelled, and can write this cancellation as a critical
error *before* the context is cloned, leading to a state where there is
a critical error that won't go away.

This should resolve test flakes reported in golang/go#44098.

For golang/go#44098

Change-Id: I41c0f49b2fe999131f4c31166e69b2cde85470b7
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419502
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
2022-07-29 15:25:28 +00:00
Robert Findley 8ea5687987 internal/lsp/regtest: remove arbitrary timeout for closing the editor
Following up on some post-submit feedback in CL 417583.

Fixes golang/go#53819

Change-Id: Iebb1e6496ab1d6fde8961d8617d0b63e19c7033b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419503
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-28 20:06:00 +00:00
Robert Findley d01bb2ff91 internal/lsp/source: document the handling of GOPRIVATE for linkTarget
Document that modules matching GOPRIVATE will not be linked.

Updates golang/vscode-go#2362

Change-Id: I7e2447bb50a2cd0d7d394f8589ccd4498f889048
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419979
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
2022-07-28 19:37:47 +00:00
Robert Findley 98bfcd1bee internal/memoize: fix race in Store.Promise
When releasing a promise, there was a theoretical race whereby a
promise's refcount could be incremented before Store.promisesMu was
acquired and the promise deleted.

We could fix this by double-checking after acquiring Store.promisesMu,
but it seemed simpler to just guard Promise.refcount with
Store.promisesMu, and skip using atomics. We already lock promisesMu
when acquiring the promise, and so locking when releasing should not
significantly affect our level of contention.

Additionally, make it a panic to call the returned release function more
than once, and document this behavior.

Change-Id: I1135b558b1f13f2b063dcaad129a432c22da0b28
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419504
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-28 15:35:11 +00:00
Robert Findley e02e98a037 internal/lsp/cache: allow network whenever reloading the workspace
Per the explanation at golang/go#54069, allow network access whenever
loading the workspace. Enable one test that exercises this behavior.
More tests will be added in subsequent CLs.

Updates golang/go#47540
Updates golang/go#53676
Updates golang/go#54069

Change-Id: I9c3bb19d36702bc6b8051bee6b7cddaec5b97c0c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419500
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-27 19:28:51 +00:00
Robert Findley b52794acc2 internal/lsp/cache: simplify snapshot.Clone reinitialization logic
The logic to detect whether the snapshot should be reinitialized is
complicated, and had at least a couple latent bugs:
 - It depends on workspace.Clone to learn whether relevant mod/work
   files have been saved.
 - It naively checks for changes in vendor directories, and
   reinitializes if there was an initialization failure.
 - It copies the initializeOnce field. Pragmatically this may not matter
   (due to context cancellation, for example), but as a matter of best
   practices we should not copy this field. It could lead to missing an
   initialization on the new snapshot.
 - Writing initializeOnce was technically racy.

Furthermore, due to vendored file handling being interleaved with other
changes, it was possible that we detect that the snapshot should be
reinitialied only after we have processed other changes, and that
processing of other changes depended on knowing whether the snapshot
will be reinitialized.

Simplify this by
- Replacing 'initializeOnce' with an 'initialized' bool, which is
  guarded with snapshot.mu. We were relying on the view initialization
  semaphore to prevent races anyway, so there is no need for a sync.Once
  to prevent multiple in-flight initializations.
- Removing the 'changed' result from workspace.Clone: it shouldn't
  actualy matter for snapshot.Clone (only reinit matters), and in any
  case can be derived by comparing the new workspace with the old.
- Detect changes to vendored files before processing the rest of the
  changes.

Change-Id: I3624a46d4be9c054a6f719f20549599986b64cbd
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419499
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-27 19:27:52 +00:00
Robert Findley f1bb5ca08f internal/lsp/cache: report a critical error when go.work is invalid
When a go.work file fails to validate, the workspace is left in an
invalid state: we will detect that the workspace is defined by the
go.work, but will not actually parse any active modules. This should be
a critical error.

Fix this by adding allowing the workspace to surface critical errors via
a new cache.workspace.criticalError method.

Additionally:
 - only build the workspace mod file in workspace.build if the mode is
   fileSystemWorkspace (in all other modes the modfile is already
   determined)
 - rename workspace.invalidate to workspace.Clone, to be consistent with
   other data structures
 - rename CriticalError.DiagList to CriticalError.Diagnostics
 - add several TODOs for observations while reading the code
 - create a new file for regtests related to broken workspaces
 - make the regtest sandbox panic when duplicate paths are present in
   the sandbox file set (an error I made while writing the test)

Updates golang/go#53933

Change-Id: If8625ab190129bc9c57e784314bc9cc92644c955
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417593
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
2022-07-27 18:59:40 +00:00
Robert Findley b3b5c13b29 internal/lsp/cache: invalidate packages with missing deps when files are
added

Add logic to invalidate any packages with missing dependencies when a
file is added.

Also fix a latent bug overwriting 'anyFileOpenenedOrClosed' for each
loop iteration.

Fixes golang/go#54073

Change-Id: I000ceb354885bd4863a1dfdda09e4d5f0e5481f3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419501
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Suzy Mueller <suzmue@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-27 16:29:04 +00:00
Robert Findley 39a4e36475 internal/lsp/regtest: only run /default tests with -short
Due to shared caching, the "default" tests can run faster than other
execution modes and still retain most of the test coverage. Update the
test runner to only run the singleton tests if testing.Short() is true,
independent of GOOS.

On the other hand, we lost noticeable coverage when disabling the
Forwarded testing mode. Now that the regtests are lighter weight in
general, reenable it on the longtests builders.

While at it, clean up tests that used the server-side Options hook to
instead use Settings, since clients would configure their server via
Settings and Options can't work with a shared daemon.

Updates golang/go#39384

Change-Id: I33e8b746188d795e88841727e6b7116cd4851dc2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/418774
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-26 21:20:53 +00:00
Robert Findley f157068c1b internal/lsp/regtest: allow sharing memoized results across regtests
Each regtest does a significant amount of extra work re-doing things
like parsing and type-checking the runtime package. We can share this
work across regtests by using a shared cache, significantly speeding
them up at the cost of potentially hiding bugs related to timing.

Sharing this work still retains most of the benefit of the regtests, so
implement this in the default mode (formerly called "singleton" and now
renamed to "default"). In a subsequent CL, modes will be cleaned up so
that "default" is the only mode that runs with -short.

Making this change actually revealed a caching bug: our cached package
stores error messages extracted from go/packages errors, but does not
include these errors in the cache key. Fix this by hashing all metadata
errors into the package cache key.

Updates golang/go#39384

Change-Id: I37ab9604149d34c9a79fc02b0e1bc23fcb17c454
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417587
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
2022-07-26 21:20:42 +00:00
Hana (Hyang-Ah) Kim 8ccb25c9a3 internal/lsp: treat struct tags as string type
For golang/go#54066

Change-Id: Ia4f0bf0b4d76743a7f4fafc375859db7184753fb
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419498
Reviewed-by: Peter Weinberger <pjw@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
2022-07-26 20:35:51 +00:00
Suzy Mueller 6c8a6c4093 internal/lsp: suppress parameter hint when argument matches parameter
Suppress the parameter hint when it would present redundant
information.

Fixes golang/go#2361

Change-Id: I4340a903046f212f8a035eab847da665e2692f1a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419497
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Suzy Mueller <suzmue@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
2022-07-26 18:43:08 +00:00
Suzy Mueller c83f42da70 internal/lsp: update inlay hints documentation to include go snippets
Update the markdown documentation for inlay hints and fix a couple
of typos in the examples.

Change-Id: I114502a81999bc5e4f25384ab619888f3e31a731
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419496
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Suzy Mueller <suzmue@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-26 18:27:49 +00:00
Dylan Le 2a6393fe54 internal/lsp: Refactor to share logic with rename
If a package is being operated on, getPackage returns that package information; otherwise nil.

Change-Id: I881056510b8d6862c274a7532fdfbc840c938468
Reviewed-on: https://go-review.googlesource.com/c/tools/+/418791
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Dylan Le <dungtuanle@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2022-07-25 19:36:27 +00:00
Suzy Mueller 04bd087817 internal/lsp: enable fillstruct for generics
This enables some fill struct code actions for instances of structs with
type parameters.

This additionally adds a filtering mechanism to the suggested fixes in
order to account for multiple suggested fixes in the same location.

Change-Id: I98866b462b026f4c5a4897bc278f704381623f25
Reviewed-on: https://go-review.googlesource.com/c/tools/+/418415
Reviewed-by: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Suzy Mueller <suzmue@golang.org>
2022-07-25 16:40:20 +00:00
Robert Findley 6ec939a616 internal/span: fix incorrect bounds check in ToOffset
token.File.LineStart panics if line < 1, but we were checking line < 0.
Surprising that this was not hit more often: it looks like we
pre-validate input except for parsed positions coming from the Go
command. It is possible that an older version of the Go command returned
invalid positions.

Also report a bug for one error condition in ToOffset: the position
returned by LineStart should always be valid.

Fixes golang/go#54006

Change-Id: I5965af9c62976b3e00b023512df334a8de943a3d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419109
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-25 14:31:12 +00:00
Peter Weinberger 3d474c8905 internal/lsp/diff: new diff implementation to replace go-diff
The new implementation is based on Myers' paper, and is in the
package diff/lcs.

There is a new option newDiff, that can be set to 'old', 'new',
or 'both'. The default is 'both', although that may not be
the right choice for a release. See gopls/hooks/diff.go.
'both' runs both the old and new diff algorithm and saves some
statistics in a file in os.Tempdir(),

When (or if) the new code becomes the default, this logging (and
some internal checking) will be removed.

The new implementation has internal checking, which currently
panics. The code in gopls/hooks/diff.go tries to save an encrypted
(for privacy) version of the failing input.

The package diff/myers has not been replaced, but it could be.

Fixes golang/go#52966

Change-Id: Id38d76ed383c4330d9373580561765b5a2412587
Reviewed-on: https://go-review.googlesource.com/c/tools/+/396855
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Peter Weinberger <pjw@google.com>
2022-07-24 16:55:18 +00:00
Robert Findley a2a24778ba gopls/internal/regtest: externalize shouldLoad tracking
The fundamental bug causing TestChangePackageName to fail has been
fixed, yet unskipping it revealed a new bug: tracking whether or not a
package should be loaded requires that we actually store that package in
s.meta. In cases where we drop metadata, we also lose the information
that a package path needs to be reloaded.

Fix this by significantly reworking the tracking of pending loads, to
simplify the code and separate the reloading logic from the logic of
tracking metadata. As a nice side-effect, this eliminates the needless
work necessary to mark/unmark packages as needing loading, since this is
no longer tracked by the immutable metadata graph.

Additionally, eliminate the "shouldLoad" guard inside of snapshot.load.
We should never ask for loads that we do not want, and the shouldLoad
guard either masks bugs or leads to bugs. For example, we would
repeatedly call load from reloadOrphanedFiles for files that are part of
a package that needs loading, because we skip loading the file scope.
Lift the responsibility for determining if we should load to the callers
of load.

Along the way, make a few additional minor improvements:
 - simplify the code where possible
 - leave TODOs for likely bugs or things that should be simplified in
   the future
 - reduce the overly granular locking in getOrLoadIDsForURI, which could
   lead to strange races
 - remove a stale comment for a test that is no longer flaky.

Updates golang/go#53878

Change-Id: I6d9084806f1fdebc43002c7cc75dc1b94f8514b9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417576
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Suzy Mueller <suzmue@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-22 21:31:20 +00:00
Suzy Mueller ec1f92440b internal/lsp: add check for nil results to fillreturns
Avoid panicking when allocating an array for a nil results list
by returning early.

Change-Id: I26953b5cef7832bad3006bd316d59978a5d94cbd
Reviewed-on: https://go-review.googlesource.com/c/tools/+/418416
Run-TryBot: Suzy Mueller <suzmue@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-20 19:56:16 +00:00
Dylan Le dc45e742f0 internal/lsp: Update FilterDisallow to support matching directories at arbitrary depth.
In FilterDisallow, change filter to regex form to match with file paths. Add a unit regtest for FilterDisallow.

For golang/go#46438

Change-Id: I7de1986c1cb1b65844828fa618b72b1e6b76b5b9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/414317
Run-TryBot: Dylan Le <dungtuanle@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-18 17:53:36 +00:00
Robert Findley ce6ce76626 internal/lsp/regtest: increase the time allowed for shutdown
Now that we await ongoing work during shutdown, we are seeing regtest
flakes simply due to outstanding go command invocations.

Allow more time for cleanup. If this is insufficient, we can be more
aggressive about terminating go command processes when context is
cancelled.

For golang/go#53820

Change-Id: I3df3c5510dae34cb14a6efeb02c2963a71e64f3a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417583
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dylan Le <dungtuanle@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
2022-07-15 16:56:31 +00:00
Alan Donovan c3af7c2fa9 internal/lsp/cache: delete workspacePackageHandles (dead code)
This should have been in CL 417116.

Also:
- (related to CL 417415), rename packageHandle.check to await
  to indicate its blocking nature.
- rename typeCheck to typeCheckImpl, following the pattern.
- move "prefetch" parallel loop into typeCheckImpl.
- add some comments.

Change-Id: Iea2c8e1f1f74fb65afd0759b493509147d87a4bb
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417581
Run-TryBot: Alan Donovan <adonovan@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-15 14:53:26 +00:00
Francesco Renzi 1a4e02fee4 internal/lsp/analysis/unusedvariable: add analyzer
This analyzer suggests fixes for unused variable errors.
In declarations it will remove the whole statement if the offending
variable is the only one declared in that statement, otherwise it will
just delete the offending variable.
In assignments it will remove the whole statement if the offending
variable is the only one assigned in that statement, otherwise it will
rename the offending variable to `_`. If the assignment RHS contains a
statement that can cause a side effect (a function call or reading from
a channel), the assignment will be removed but RHS will be preserved.

Fixes golang/go#48975

Change-Id: I3850f1b0340cd5ae63249931df3a5403d8617080
Reviewed-on: https://go-review.googlesource.com/c/tools/+/394934
Reviewed-by: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2022-07-15 14:27:36 +00:00
Alan Donovan db8f89b397 internal/memoize: rename Handle to Promise
Also:
- add test of NewHandle
- update package doc and other doc comments
- factor Store.Handle with NewHandle
- declare Handle before Store

Change-Id: I4bcea2c9debf1e77f973ef7ea9dbe2fd7a373996
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417417
Auto-Submit: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-14 01:47:39 +00:00
Hana (Hyang-Ah) Kim a7c53b59a6 internal/analysisinternal: move FindBestMatch to internal/lsp/fuzzy
This is used by internal/lsp/analysis/fillreturns and
internal/lsp/analysis/fillstruct. This doesn't need to be in this
analysisinternal package.

This removes the dependency path

  go/analysis/internal/checker ->
    internal/analysisinternal ->
      internal/lsp/fuzzy

Change-Id: I5db674ca30eb06ae6ce7021397cf5530a695af4e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417418
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
2022-07-13 21:41:37 +00:00
Alan Donovan 9b6c01892a internal/lsp/cache: don't trim unexported struct fields
The trimming optimization deletes parts of the syntax tree
that don't affect the type checking of package-level declarations.
It used to remove unexported struct fields, but this had
observable consequences: it would affect the offset of later
fields, and the size and aligment of structs, causing the
'fieldalignment' analyzer to report incorrect findings.
Also, it required a complex workaround in the UI element
for hovering over a type to account for the missing parts.

This change restores unexported fields.
The logic of recordFieldsUses has been inlined and specialized
for each case (params+results, struct fields, interface
methods) as they are more different than alike.

BenchmarkMemStats on k8s shows +4% HeapAlloc:
a lot, but a small part of the 32% saving of the trimming
optimization as a whole.

Also:
- trimAST: delete func bodies without visiting them.
- minor clarifications.

Updates golang/go#51016

Change-Id: Ifae15564a8fb86af3ea186af351a2a92eb9deb22
Reviewed-on: https://go-review.googlesource.com/c/tools/+/415503
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
2022-07-13 21:08:41 +00:00
Alan Donovan 85173cc4bd internal/lsp/cache: follow usual structure for packages, analysis maps
All Get/Set operations on the maps now happen within a single
function (buildPackageKey, actionHandle).

No behavior change.

Change-Id: I347dfda578c28657a28538e228ecfb6f0871b94b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417415
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
2022-07-13 20:11:14 +00:00
Alan Donovan b2eae76267 internal/lsp/cache: simplify modwhy cache
As with mod tidy in CL 417116, we can rely on invalidation
rather than cache keys to avoid reusing stale results, and
there's no need to save these handles in the global store.

Change-Id: I3763c01fa21c6114248c1d541e3c168fc6a128c9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417416
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-13 20:02:47 +00:00
Alan Donovan dcb576d3b6 internal/lsp/cache: simplify modtidy
Previously, the modtidy operation used a persistent map
of handles in the central store that cached the result
of a parsing the go.mod file after running 'go mod tidy'.
The key was complex, including the session, view, imports
of all dependencies, and the names of all unsaved overlays.
The fine-grained key prevented spurious cache hits for
invalid inputs by (we suspect) preventing nearly all cache hits.

The existing snapshot invalidation mechanism should be
sufficient to solve this problem, as the map entry is evicted
whenever the metadata or overlays change. So, this change
avoids keeping handles in the central store, so they are
never shared across views.

Also, modtidy exploited the fact that a packageHandle
used to include a copy of all the Go source files
of each package, to avoid having to read the files
itself. As a result it would entail lots of unnecessary
work building package handles and reading dependencies
when it has no business even thinking about type checking.

This change:
- extracts the logic to read Metadata.{GoFiles,CompiledGo}Files
  so that it can be shared by modtidy and buildPackageHandle.
- packageHandle.imports has moved into mod_tidy.
  One call (to compute the hash key) has gone away,
  as have various other hashing operations.
- removes the packagesMap typed persistent.Map wrapper.
- analysis: check cache before calling buildPackageHandle.
- decouple Handle from Store so that unstored handles may
  be used.
- adds various TODO comments for further simplification.

Change-Id: Ibdc086ca76d6483b094ef48aac5b1dd0cdd04973
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417116
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
2022-07-13 19:33:07 +00:00
Alan Donovan b230791f2d internal/lsp/cache: move PosTo{Decl,Field} out of cache
Before, these methods of the Source interface used to use
a cache of buildASTCache, which built a Pos-keyed map for
a whole file, but the necessary algorithm is essentially
a binary search which is plenty fast enough to avoid the
need for cache.

This change implements that algorithm and moves
both methods out of the interface into a single function,
source.FindDeclAndField.

--

I measured the duration of all calls to astCacheData (before)
and FindDeclAndField (after) occurring within this command:

  $ go test -bench=TestBenchmarkConfiguredCompletion -v ./gopls/internal/regtest/bench -completion_workdir=$HOME/w/kubernetes -completion_file=../kubernetes/pkg/generated/openapi/zz_generated.openapi.go -completion_regexp=Get

(The numbers reported by this benchmark are problematic,
which is why I measured call times directly; see
https://github.com/golang/go/issues/53798.)

Results:
before (n=4727) max =  21ms, 90% = 4.4ms, median = 19us
after  (n=6282) max = 2.3ms, 90% = 25us,  median = 14us

The increased number of calls to the function after the change
is due to a longstanding bug in the benchmark: each iteration of
the b.N loop doesn't do a fixed amount of work, it does as much
as it can in 10s. Thus making the code faster simply causes
the benchmark to spend the same amount of time on other parts of
the program--such as the loop that calls FindDeclAndField.

See https://go-review.googlesource.com/c/tools/+/221021 for
background on the previous implementation.

Change-Id: I745ecc4e65378fbe97f456228cafba84105b7e49
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416880
Auto-Submit: Alan Donovan <adonovan@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2022-07-13 14:49:57 +00:00
Robert Findley 8730184efb internal/lsp/fake: retry spurious file lock errors on windows
Cleaning the regtest sandbox sometimes fails on windows with errors that
may be spurious. Copy logic from the testing package to retry these
errors.

For golang/go#53819

Change-Id: I059fbb5e023af1cd52a5d231cd11a7c2ae72bc92
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417117
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-12 22:26:41 +00:00
Robert Findley 459e2b88fc internal/lsp/progress: actually close over Context in WorkDoneWriter
CL 409936 eliminated cases where we close over a Context during progress
reporting, except in one instance where it wasn't possible: the
WorkDoneWriter that must implement the io.Writer interface.

Unfortunately it contained a glaring bug that the ctx field was never
set, and the regression test for progress reporting during `go generate`
was disabled due to flakiness (golang/go#49901).

Incidentally, the fundamental problem that CL 409936 addressed may also
fix the flakiness of TestGenerateProgress.

Fix the bug, and re-enable the test.

Fixes golang/go#53781

Change-Id: Ideb99a5525667e45d2e41fcc5078699ba1e0f1a3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417115
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
2022-07-12 22:14:18 +00:00
Robert Findley 6e6f3131ec internal/lsp/regtest: simplify, consolidate, and document settings
Configuration of LSP settings within the regression test runner had
become a bit of a grab-bag: some were configured via explicit fields on
EditorConfig, some via the catch-all EditorConfig.Settings field, and
others via custom RunOption implementations.

Consolidate these fields as follows:
 - Add an EnvVars and Settings field, for configuring environment and
   LSP settings.
 - Eliminate the EditorConfig RunOption wrapper. RunOptions help build
   the config.
 - Remove RunOptions that just wrap a key-value settings pair. By
   definition settings are user-facing and cannot change without
   breaking compatibility. Therefore, our tests can and should set the
   exact string keys they are using.
 - Eliminate the unused SendPID option.

Also clean up some logic to change configuration.

For golang/go#39384

Change-Id: Id5d1614f139550cbc62db2bab1d1e1f545ad9393
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416876
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
2022-07-12 16:56:46 +00:00
Robert Findley 3db2cdc060 internal/lsp: wait for ongoing work to complete during server shutdown
Add a new WaitGroup to the View that allows waiting for all snapshot
destroy operations to complete. This helps ensure that the server
properly cleans up resources when shutting down, and lets us remove
work-arounds in the gopls regtests intended to avoid races during
shutdown.

Also:
 - re-enable postfix completion tests that had to be disabled due to
   being too racy
 - rename the inlayHints regtest package to follow lower-cased naming
   conventions
 - add several TODOs

Fixes golang/go#50707
Fixes golang/go#53735

Change-Id: If216763fb7a32f487f6116459e3dc45f4c903b8a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416594
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
2022-07-12 14:39:29 +00:00
Robert Findley a5adb0f2c2 internal/lsp/cache: use mod=readonly for process env funcs
CL 416874 changed the logic of populateProcessEnv and incorrectly
removed a write of ProcessEnv.ModFlag. We should explicitly set
-mod=readonly.

Change-Id: Ibacf3d4b4c0c978d65fde345741945d6136db159
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416877
Reviewed-by: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
2022-07-12 14:39:19 +00:00
Robert Findley a79ee0f0f0 Revert "Revert "internal/lsp/cache: don't pin a snapshot to view.importsState"
This reverts CL 416879, which itself was a revert of CL 416874.

Reason for revert: failure is understood now, as described in 
https://github.com/golang/go/issues/53796#issuecomment-1181157704 and fixed in CL 416881.

Change-Id: I1d6a4ae46fbb1bf78e2f23656de7885b439f43fb
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416882
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-12 14:39:12 +00:00
Robert Findley bc957ec62f internal/lsp/source: use token.File-agnostic positions to dedupe refs
We were already using a token.File-agnostic position for object
positions in our references algorithm, but still relied on token.Pos for
identifying duplicate references. This breaks down when a file may have
multiple parsed representations in different packages.

While we should endeavor to eliminate duplicate parsing, our algorithms
should not rely on this for correctness. Update the reference
de-duplication to use the same position key as object search.

For golang/go#53796

Change-Id: Ic2e6c23380ea4e6b2747e4e5b45d7bfa6e656f0f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416881
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
2022-07-12 14:39:04 +00:00
Robert Findley b6e495100e Revert "internal/lsp/cache: don't pin a snapshot to view.importsState"
This reverts commit 42457a544a.

Reason for revert: test flakes (golang/go#53796)

Change-Id: I9d7061220b43f9de88060a0bba5c5635d92fe3d9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416879
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-11 22:19:10 +00:00
Alan Donovan 71dc5e295f internal/lsp/cache: make snapshot reference counting uniform
Previously, snapshots were born with a reference count of zero.
Although leases were created and returned by functions that
return a snapshot, and correctly disposed of by the caller, the
view did not hold a lease for its snapshot. The view's lease
on the snapshot was implicit, and for this reason the view
made explicit calls to Destroy when these implicit leases ended,
which would then wait for all explicit leases to end.

Now that the view holds an explicit lease to its snapshot, it is
safe (as a follow-up change) to move the destroy logic into the
call of release() that brings the refcount to zero.

Also:
- clarify that release functions should be called when
  and only when err is nil.
- in View: remove unused View.cancel field.
- in tempModFile: clarify tricky return + defer + named-result-var statement.
- in DidModifyFiles: simplify type of releases from []func() to func().
- in Server.addFolders: fix reference leak (looks minor).

Change-Id: Ibf61f4ce109e91060e2ccd854c32214b119f2f0a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416875
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-07-11 18:57:05 +00:00
Robert Findley 42457a544a internal/lsp/cache: don't pin a snapshot to view.importsState
Whenever a view.importsState value is created, we use
snapshot.goCommandInvocation to extract information used to run the go
command in the imports.ProcessEnv. Before this CL, that process acquired
the current snapshot (whatever it was), and held onto it for the purpose
of sharing a workspace directory. As a consequence all the memory in
that snapshot was pinned for the lifecycle of the importsState, which
can be the entire editing session. This results in a memory leak as
information in the session is invalidated.

Fix this by creating a copy of the workspace directory to be owned by
the importsState.

Also:
 - Add some TODOs
 - Clean up some stale comments

Fixes golang/go#53780

Change-Id: I2c55cc26b2d46c9320c6c7cd86b3e24971cd5073
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416874
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
2022-07-11 17:33:27 +00:00
Alan Donovan d6c099e3c1 internal/memoize: document stateIdle, RefCounted
...now that I have understood why they are not
in fact inessential.

Change-Id: I1ab881a7d24cd71ee183bc8c6a1a058dbda641e2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416077
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Alan Donovan <adonovan@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2022-07-08 19:48:04 +00:00
Alan Donovan 53ead67a98 internal/memoize: delete Generation and Bind
Now that the lifetime of all handles in the store is
determined by reference counting, we no longer need
the generation feature.

The Arg interface, renamed RefCounted, is now optional,
and causes the lifetime of the argument to be extended
for the duration of the Function call.  This is important
when the Get(ctx) context is cancelled, causing the
function call to outlive Get: if Get's reference to
the argument was borrowed, it needs to increase the
refcount to prevent premature destruction.

Also:
- add missing snapshot.release() call in
  importsState.populateProcessEnv.
- remove the --memoize_panic_on_destroyed flag.

Change-Id: I0b3d37c16f8b3f550bb10120c066b628c3db244b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416076
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-08 19:22:01 +00:00
Alan Donovan 8746177218 internal/lsp/cache: simplify ParseGo
This change simplifes the ParseGo interface to
make it consistent with the other handle+map operations:

- ParseGoImpl is the basic parser.
- The 'fixed' bool result is a field of ParsedGoFile.
- ParseGo is the caching wrapper.
  The map accessors have been inlined into it.
- goFiles (renamed parsedGoFiles) is now just a bare
  persistent.Map.
- parseGoHandle is replaced by *memoize.Handle
- the operations of "make a handle" and "wait for it"
  are no longer separate (since clients never want
  one without the other).
- cachedPGF and peekOrParse have been combined into
  peekParseGoLocked.

Change-Id: If01a6aaa7e6a8d78cb89c305e5279738e8e7bb55
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416223
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
2022-07-08 18:52:03 +00:00
Robert Findley 9c2a5567e3 internal/lsp/cache: fail addPackageHandle if metadata is stale
If metadata is refreshed during the execution of buildPackageHandle, we
should not store the resulting package handle in the snapshot, as it
breaks the invariant that computed packages match the currently loaded
metadata.

This strictness revealed another bug: because of our fine-grained
locking in snapshot.load, it is possible that we set valid metadata
multiple times, leading to unnecessary invalidation and potential
further races to package handles. Fix this by building all metadata when
processing the go/packages result, and only filtering updates after
grabbing the lock.

For golang/go#53733

Change-Id: Ib63ae4fbd97d0d25d45fe04f9bcd835996db41da
Reviewed-on: https://go-review.googlesource.com/c/tools/+/416224
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-08 17:11:40 +00:00
Alan Donovan 1dfab61a48 internal/lsp/cache: use GetHandle not Bind for 5 URI-keyed maps
This change replaces the 5 remaining calls to Bind (generational
lifetime) with GetHandle (reference counting). The handles
are now stored in persistent.Maps, which simplifies the
invalidation logic.

All 5 have span.URIs as keys:
  symbolizeHandles
  parse{Mod,Work}Handles
  mod{Tidy,Why}Handles

Also, factor the functions that use these maps to have a common form:
- a fooImpl function that returns an R result and an error;
- a foo wrapper that decorates it with caching.
- a local fooResult type, defined struct{R; error} that is the cache entry.
The functions for getting/setting map entries are all inlined.
The fooHandle types are all replaced by *memoize.Handle, now that
their use is local.

No behavior change is intended.

The other uses of Bind are deleted in these CLs:
https://go-review.googlesource.com/c/tools/+/415975 (astCacheData)
https://go-review.googlesource.com/c/tools/+/415504 (actions)

Change-Id: I77cc4e828936fe171152ca13a12f7a639299e9e5
Reviewed-on: https://go-review.googlesource.com/c/tools/+/415976
Auto-Submit: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2022-07-07 16:57:02 +00:00
Alan Donovan 2aef121b83 internal/lsp: consolidate .go/go.mod link logic
Now that we have a token.File (albeit throwaway)
for a parsed go.mod file, we can combine the .go and go.mod
logic for turning it into a protocol.DocumentLink.

Change-Id: Id1783644cbd450f0e8dc807beb8ba625675d8540
Reviewed-on: https://go-review.googlesource.com/c/tools/+/410136
Run-TryBot: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
2022-07-07 14:56:05 +00:00