This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Handle queries without an originating file in ProjectAwareIndex
AbandonedPublic

Authored by kadircet on May 26 2021, 9:14 AM.

Details

Summary

This enables handling of queries like workspaceSymbols by the last used
external index, which might be null when the query comes from a file specific
context but that file doesn't have any ExternalIndex set (existing behaviour).

This also moves config::Params into Config, rather than just having a file path
inside the Config struct or deducing the environment from Context.

Diff Detail

Event Timeline

kadircet created this revision.May 26 2021, 9:14 AM
kadircet requested review of this revision.May 26 2021, 9:14 AM

Note that I don't feel strongly about making use of Context to figure out config::Params vs moving the Params into the Config. But I'd rather not only store Path in the Config since we might end up needing other environment variables in future.

I didn't go with the Context option as it is hard to find a place to fetch it. Maybe we can just forward declare it in Config.h and have a Config::Params similar to Config::Current. (but this would decouple the Config and Params that generated it :/)

Sorry for lots of comments on a fairly small patch.


I want to mention one alternative we haven't considered. Ultimately the problem here is that we have actions that depend on config but we don't know what file to pull the config from.
This corresponds to passing Path="" to TUScheduler::run (3 calls) or runQuick (0 such calls).
Our decision is to effectively use the config from the last accessed file.
Why don't we put this policy in TUScheduler, rather than inferring it at the edges?
Because TUScheduler isn't threadsafe, I think this is as simple as adding a std::string LastFile member, and reading/writing to it in all the run* methods.


But I'd rather not only store Path in the Config since we might end up needing other environment variables in future.

Right. However this patch goes further, and says we must expose *all* other parameters, in the same way and with the same semantics (since we only get to document them once).
I don't find the argument totally convincing, because currently we have 2 params, and:

  • fresh time shouldn't be exposed at all, unless i'm missing something
  • the path is exposed for fairly subtle reasons, and we want to use it sparingly and so probably give it quite weak semantics (e.g. wouldn't be appropriate to grab "the current filename" for logging purposes, I think)
clang-tools-extra/clangd/Config.h
60

who owns the underlying string, with what lifetime?

The "root" that creates the config doesn't currently have any obligation to keep the params around for as long as the config might be active (which can be async via context). I think in config this should be a std::string

60

How do we expect this to be used?
If it's for determining the active project, then I'd expect us to give some weaker semantic like "representative file from the active project" so we can fill in e.g. the main file associated with a TU.

But actually we only use the boolean "is this set". Maybe we should just provide that?
"bool WasConfiguredForPath" or something? Generalizing past that might be premature.

69

try to avoid using multiple abbreviations of the same word :-)

clang-tools-extra/clangd/index/ProjectAware.cpp
152

This logic feels unnecessarily tricky: you check whether the spec is set both here and above.
Consider something longer but more direct

SymbolIndex *Specified = C.Index.External ? GetIndexFromSpec(*C.Index.External) : nullptr;
if (!Specified && C.Parm.Path.empty()) {
  // There was no index specified, but we're also not sure which path we're using.
  // Use the index from the last operation that had a valid path.
  return LastIndex.
}
// Cache the last-used index, even if it's null ("no external index" is a valid config!)
LastIndex = Specified;
return Specified;
154

this is racy: if there *is* a well-defined external index for the current config, then we should return it even if another thread is able to concurrently write to LastIndex.

kadircet abandoned this revision.Jun 2 2021, 1:52 PM

in favor of D103476