This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Cleanup: make the diags callback global in TUScheduler
ClosedPublic

Authored by ilya-biryukov on Nov 20 2018, 9:03 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

ilya-biryukov created this revision.Nov 20 2018, 9:03 AM

The tests still model the old callbacks using callbacks, unfortunately I see no good way to test same things in any other way.

Nice!
The biggest suggestion I have is merging the callback into ASTCallbacks. That's awkward in initialization (makeUpdateCallbacks probably needs to be called unconditionally with a maybe-null pointer) but it seems like a natural grouping in all the places it gets plumbed around to... and there are a lot!

clangd/ClangdServer.h
232 ↗(On Diff #174794)

I'm not sure using context here buys much: there aren't many layers, they're fairly coupled, and this information would look pretty natural in the interfaces.

What about:

  • move the definition of DocVersion to TUScheduler
  • make DocVersion a member of ParseInputs
  • pass (PathRef, DocVersion, vector<Diag>) to the TUScheduler's diag callback
clangd/TUScheduler.h
92 ↗(On Diff #174794)

ISTM the callback would fit nicely on the ASTCallbacks?
It even gets plumbed through to ASTWorker correctly by reference.

unittests/clangd/TUSchedulerTests.cpp
32 ↗(On Diff #174794)

(up to you if you feel like fixing while here)
this is just llvm::consumeError

36 ↗(On Diff #174794)

Yeah, these are messy. I also don't see something better in general.

There's a place or two below where I think we can avoid them without much verbosity, which I think is probably worthwhile even if lots of tests need them :-/

38 ↗(On Diff #174794)

ParseInputs is always getInputs(File), you could do that here (similarly for updateWithDiags) to avoid repetition.

495 ↗(On Diff #174794)

can we just increment a counter in the callback, and have DoUpdate look for a delta?

ilya-biryukov marked an inline comment as done.
  • Merge the diagnostics callback into ParsingCallbacks
  • updateWithDiags(File, getInputs(File...)) -> updateWithDiags(File, ...)
clangd/ClangdServer.h
232 ↗(On Diff #174794)

I'd keep it separate: ParseInputs is defined in ClangdUnit.cpp and it serves the purpose of defining everything we need to run the compiler.
Adding DocVersion there would make no sense: it's of no use to the actual code doing preamble builds or parsing.

I would rather aim to get rid of DocVersion (for this particular purpose, there are other ways to fix the raciness that the DocVersions workaround).
WDYT?

clangd/TUScheduler.h
92 ↗(On Diff #174794)

Done. This is definitely less plumbing, but IMO the public interface looks a bit worse now.
Consuming ASTs and diagnostics are two independent concerns and it's a bit awkward to combine them in the same struct.

But we don't have too many callers, updating those is easy.

unittests/clangd/TUSchedulerTests.cpp
32 ↗(On Diff #174794)

Will fix in a separate commit, like it more when cleanups are the only thing in the commit.

38 ↗(On Diff #174794)

It's actually a bit more complicated: getInputs(File, Contents), note the second parameter.
Done anyway, definitely looks better (and less prone to mistakes!).

The calls are now updateWith(S, File, Contents...), there's one place that still relies on the Inputs though (checks the VFS does not change in the following read).

495 ↗(On Diff #174794)

Maybe... I haven't looked closely into the test, would prefer to keep this change mostly mechanical and avoid digging into the test logic.
Happy to take a look into simplifying the test separately, of course.

Just the context thing. Rest is some optional simplifications.

clangd/ClangdServer.cpp
77 ↗(On Diff #174914)

hmm, the double-indirection for diags seems a bit funny, especially since we have a dedicated method on ClangdServer so the lambda is trivial.

Maybe we should just make the CB class nested or friend in ClangdServer, and pass it a ClangdServer*? Then it can access DynamicIdx and consumeDiagnostics directly. The decoupling here isn't that strong to start with.

clangd/ClangdServer.h
232 ↗(On Diff #174794)

Yeah, separating it from ParseInputs makes sense conceptually, and getting rid of it is indeed better.

I don't think this justifies using Context.

Passing it as a separate parameter seems fine to me. Putting it in ParseInputs with a FIXME is a little less principled but avoids interface churn.

clangd/TUScheduler.cpp
156 ↗(On Diff #174914)

nit: we generally have the private section at the top without explicitly introducing it (as common in LLVM), or at the bottom. I'm fine with either style but would prefer not to add a third.

clangd/TUScheduler.h
92 ↗(On Diff #174794)

(Separate yes, but I'm not sure they're that much more separate than consuming preambles vs ASTs, really. Outside of the 2/1 split of where the data goes today...)

unittests/clangd/TUSchedulerTests.cpp
38 ↗(On Diff #174794)

Exactly, thanks!
(I forgot to mention Contents in the comment, doh)

495 ↗(On Diff #174794)

It seems like a trivial change, and it'd be nice not to depend on the new machinery you're introducing here when we don't have to.
I'm not going to insist, but this is just...

atomic<unsigned> DiagsReceived;
TUScheduler S(..., [&](Diags) { ++ DiagsReceived }, ...);
...
DoUpdate = [&] -> bool { // as before
  unsigned PrevDiags = DiagsReceived;
  S.update(...);  blockUntilIdle(); // as before
  return DiagsReceived != PrevDiags;
}
ilya-biryukov marked an inline comment as done.
  • Remove accidentally added redundant 'private:' section
ilya-biryukov added inline comments.Nov 22 2018, 2:37 AM
clangd/ClangdServer.cpp
77 ↗(On Diff #174914)

I would avoid doing that, because ClangdServer is not thread-safe and giving the async callbacks that run on a different threads an access to the full class is scary.
Giving a narrower interface seems better, even if that means double-indirection

After D54829, there's no need for double-indirection too, the callback is simply directly calling into the diagnostics consumer, so it shouldn't be an issue.

clangd/ClangdServer.h
232 ↗(On Diff #174794)

The versions are not too hard to remove, here's the change that does this: D54829
That would avoid the need for putting them into either the context or the ParseInputs.

clangd/TUScheduler.cpp
156 ↗(On Diff #174914)

Yeah, sorry, that was an accidental change.

clangd/TUScheduler.h
92 ↗(On Diff #174794)

but I'm not sure they're that much more separate than consuming preambles vs ASTs

ASTs and resulting diagnostics are on different layers of abstraction, so I don't think they fit well in the same interface, even if the data-flow for those is similar.

ilya-biryukov planned changes to this revision.Nov 22 2018, 2:37 AM

Would like to land D54829 first and rebase on top of it.

  • Rebase
  • Remove makeUpdateCallbacks, expose the callback class instead
sammccall accepted this revision.Nov 22 2018, 8:14 AM

Everything looks so much better...

This revision is now accepted and ready to land.Nov 22 2018, 8:14 AM
This revision was automatically updated to reflect the committed changes.