[PATCH] D98499: [clangd] Introduce ASTHooks to FeatureModules

Kadir Cetinkaya via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 29 14:36:57 PDT 2021


kadircet added inline comments.


================
Comment at: clang-tools-extra/clangd/FeatureModule.h:112
+  };
+  /// Can be called asynchronously before building an AST.
+  virtual std::unique_ptr<ParseASTHooks> astHooks() { return nullptr; }
----------------
sammccall wrote:
> kadircet wrote:
> > sammccall wrote:
> > > This comment hints at what I *thought* was the idea: astHooks() is called each time we parse a file, the returned object has methods called on it while the file is being parsed, and is then destroyed.
> > > 
> > > But the code suggests we call once globally and it has effectively the same lifetime as the module.
> > > This seems much less useful, e.g. if we want to observe several diagnostics, examine the preamble, and emit new diagnostics, then we have to plumb around some notion of "AST identity" rather than just tying it to the identity of the ParseASTHooks object itself.
> > > 
> > > (Lots of natural extensions here like providing ParseInputs to astHooks(), but YAGNI for now)
> > > This comment hints at what I *thought* was the idea: astHooks() is called each time we parse a file, the returned object has methods called on it while the file is being parsed, and is then destroyed.
> > 
> > This was the intent actually (to enable modularization of other features like clangtidy, includefixer, etc. as mentioned above), but looks like i got confused while integrating this into clangdserver :/
> > 
> > While trying to resolve my confusion i actually noticed that we cannot uphold the contract of "hooks being called synchronously", because we actually have both a preamblethread and astworker that can invoke hooks (embarrassing of me to forget that 😓).
> > 
> > So we can:
> > - Give up on that promise and make life slightly complicated for module implementers
> > - Don't invoke hooks from preamblethread, (at the cost of limiting functionality, we can still have downstream users that act on PPCallbacks, but no direct integration with compiler, and that's where layering violations are generated :/)
> > - Handle the synchronization ourselves, only complicates TUScheduler more, rather than all the module implementers.
> > - Propogate FeatureModuleSet into TUScheduler and create 2 set of hooks on each thread :)
> > 
> > I am leaning towards 4, but unsure (mostly hesitant about dependency schema, as featuremodules also depend on TUScheduler..). WDYT?
> > we actually have both a preamblethread and astworker that can invoke hooks (embarrassing of me to forget that 😓)
> 
> Ha! And yes, in our motivating case of fixing build system rules, the diagnostics are mostly going to be in the preamble.
> 
> The options that seem most tempting to me are:
>  - don't attempt to create/run astHooks while building preambles, but *do* feed the preamble's Diags into the main-file's AST hooks every time it's used. (you won't have a clang::Diagnostic, so that param would have to be gone/optional, and we'd scrape the messages instead of extracting args). This is kind of thematic, remember how we replay PPCallbacks for clang-tidy :-). This is the smallest tweak to your #2 that actually works for us, I think.
>  - create one astHooks for the preamble, and another for the AST build, and try to make the interface suitable for both. This is cute but there may be too much tension between the two cases. (Is this what you mean by #4?)
>  - or have separate ASTHooks & PreambleHooks interfaces and support all this crap for both. (Or is *this* what you mean by #4?) Hybrid is also possible, give the interfaces an inheritance relationship, or have one interface but pass boolean parameters to indicate which version we're doing, or...
>  - preambles and ASTs are a tree, so... give modules a PreambleHooks factory, and the factory function for ASTHooks is PreambleHooks::astHooks(). Holy overengineering batman...
> 
> These are roughly in order of complexity so we should probably start toward the top of the list somewhere. Up to you.
> 
> (I don't like the #1 or #3 in your list above much at all.)
> create one astHooks for the preamble, and another for the AST build, and try to make the interface suitable for both. This is cute but there may be too much tension between the two cases. (Is this what you mean by #4?)

yes this is what i meant by #4. 

> These are roughly in order of complexity so we should probably start toward the top of the list somewhere. Up to you.

I'd lean towards the second option(creating separate ASTHooks with the same interface for preamble and astworker). As discussed before first one (i.e. scraping diag message) is a limited solution that's likely to get us into a corner in the future. let me know if you have any concerns around this approach.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98499/new/

https://reviews.llvm.org/D98499



More information about the cfe-commits mailing list