Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Publish diagnostics #253

Merged
merged 7 commits into from
Jul 10, 2018
Merged

Conversation

lloiser
Copy link
Contributor

@lloiser lloiser commented Mar 29, 2018

This PR adds a very basic cache that holds diagnostics for each checked file. A file entry is removed once no more diagnostics exist for it.
An async typecheck now also happens on every save requests.

A simple unit test asserts the cache updating and an integration test modifies and saves files and then asserts certain diagnostics to be sent to the client.

Unfortunately it's currently based on #248 because it contains some changes that are necessary to work on my windows machine 😞

This is probably not 100% ready to be merged yet, but I think it is a good starting point 😁

@keegancsmith keegancsmith self-requested a review April 2, 2018 08:03
@lloiser
Copy link
Contributor Author

lloiser commented Apr 5, 2018

sry for the delay. I'm aware of the build/test problems. Let's see if I can fix them in the next few days.

@@ -217,11 +337,74 @@ func integrationTest(
}
}

ctx := context.Background()
cfg := NewDefaultConfig()
cfg.UseBinaryPkgCache = true
Copy link
Contributor Author

@lloiser lloiser Apr 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TestIntegration_FileSystem test fails because I changed this to true.
I see the code why it does not work but I have another question: why does this language server even use the binary pkg cache? Nowhere in the language server is the code actually built (aka go install). So how is this supposed to work?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I haven't looked at this yet! But cc @slimsag about UseBinaryPkgCache question.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea with UseBinaryPkgCache was that you are already running go install on your own. This concept actually comes from https://github.com/rogpeppe/godef -- which makes the same assumption. If you are not running go install on your code, however, then this option will not work well for you (you'll either get no results or stale results). This feature exists primarily because go/loader does not allow for caching type-checking results.

In your case here, I think you should just not set UseBinaryPkgCache = true. That means it will not use the cache, and will instead use the other codepath that performs type-checking on-the-fly (which is slower, but ideal for a test such as this)

remove async publishing of diagnostics because it is really hard to
assert published diagnostics then
@lloiser
Copy link
Contributor Author

lloiser commented Jun 6, 2018

I'm not sure if this PR still makes sense if we assume that diagnostics are served by another editor plugin... What's your opinion on that?

@keegancsmith
Copy link
Member

We can have another editor plugin do it, but it does make sense for the langserver to properly support diagnostics.

lloiser added 2 commits June 26, 2018 22:49
…ther integration tests

this is actually a "trick". Because it helps the test to only send 
diagnostics for `textDocument/didSave` calls
@lloiser
Copy link
Contributor Author

lloiser commented Jun 27, 2018

@slimsag @keegancsmith your review is appreciated 😁

Copy link
Member

@keegancsmith keegancsmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This is great, and the test suite is amazing. The main issue (mentioned inline) is that if we start running our own typechecker again, the memory usage balloons. This was a source of much frustration in go-langserver a while ago, which lead to us implementing a godef based approach which avoids the typechecker.

@@ -18,18 +19,37 @@ import (

type diagnostics map[string][]*lsp.Diagnostic // map of URI to diagnostics (for PublishDiagnosticParams)

type diagnosticsCache struct {
cache diagnostics
lock sync.Mutex
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use style of a "mutex hat", so call rename lock to mu and have it above cache. https://dmitri.shuralyov.com/idiomatic-go#mutex-hat

lock sync.Mutex
}

func (p *diagnosticsCache) update(fn func(diagnostics) diagnostics) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you document this behaviour here? That we enforce that only one fn is running at a time.

@@ -392,7 +397,7 @@ func (h *LangHandler) Handle(ctx context.Context, conn jsonrpc2.JSONRPC2, req *j
// a user is viewing this path, hint to add it to the cache
// (unless we're primarily using binary package cache .a
// files).
if !h.Config.UseBinaryPkgCache {
if !h.Config.UseBinaryPkgCache || req.Method == "textDocument/didSave" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the main issue with enabling typechecking again, is that it uses a lot of memory. This might be a blocker for this PR / reason to make this opt-in. WDYT @slimsag

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a simple command line flag --diagnostics to activate it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you still need to make this conditional fail if diagnostics is not enabled.

@@ -397,7 +397,7 @@ func (h *LangHandler) Handle(ctx context.Context, conn jsonrpc2.JSONRPC2, req *j
// a user is viewing this path, hint to add it to the cache
// (unless we're primarily using binary package cache .a
// files).
if !h.Config.UseBinaryPkgCache || req.Method == "textDocument/didSave" {
if h.Config.DiagnosticsEnabled && (!h.Config.UseBinaryPkgCache || req.Method == "textDocument/didSave") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suspect this matches the proper intent. We still want to run it if usebinarypkgcache is disabled

!h.Config.UseBinaryPkgCache || (h.Config.DiagnosticsEnabled && req.Method == "textDocument/didSave")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added the Config.DiagnosticsEnabled check in the publishDiagnostics. So there is no harm in doing the typecheck on save too, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway. I will change it to

if !h.Config.UseBinaryPkgCache || (h.Config.DiagnosticsEnabled && req.Method == "textDocument/didSave") {

@keegancsmith
Copy link
Member

Sorry one more inline comment then this is ready to merge :)

@keegancsmith
Copy link
Member

great CI failure is on go tip so is unrelated to your change. Merging in.

@keegancsmith keegancsmith merged commit ea78469 into sourcegraph:k/better-fmt Jul 10, 2018
@keegancsmith
Copy link
Member

oh this is merging into k/better-fmt! What do you want to do next?

@lloiser lloiser deleted the ll/diagnostics branch July 10, 2018 08:46
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants