ilya-biryukov marked 6 inline comments as done.
ilya-biryukov added a comment.
A second attempt at implementing the `Context`s. Still missing a few comments,
but hopefully ready for review.
================
Comment at: clangd/Context.h:71
+/// before any clangd functions are called.
+class GlobalSession {
+public:
----------------
sammccall wrote:
> Maybe `WithGlobalContext` is a good name for this scoped object?
>
> This comment doesn't give a clear idea why someone would want to call this.
> Maybe `All contexts used by clangd inherit from this global context
> (including contexts created internally)`
Remove the global context altogether.
================
Comment at: clangd/Context.h:79
+/// Otherwise returns an empty Context.
+Context &globalCtx();
+
----------------
ilya-biryukov wrote:
> sammccall wrote:
> > ilya-biryukov wrote:
> > > bkramer wrote:
> > > > This is a giant code smell. If we want the context route, please pass
> > > > contexts everywhere. I really don't want this kind of technical debt in
> > > > clangd now.
> > > I'm with you on this one, but I think @sammccall was keen on having the
> > > global context. The main reason was to always have access to **some**
> > > loggers and tracers, even when it's hard to pass the Context into the
> > > function.
> > > It's perfectly easy to remove all usages of `globalCtx()`, currently only
> > > 8 usages to get rid of. However, I'd wait for Sam's comment before doing
> > > that.
> > It's important to be able to call functions that require a context if you
> > don't have one - adding a log statement/trace for debugging shouldn't
> > require changing plumbing/interfaces. (It's fine if we want to avoid
> > checking in such code...)
> > Having an "empty" global context allows this.
> >
> > At the same time, we want the ability to set the sink for logs/traces etc
> > globally.
> >
> > A couple of options:
> > - the sink (e.g. Logger) is part of the context, we need to allow
> > embedders to set/augment the global context
> > - the sink is not stored in the context, instead it is some other
> > singleton the embedder can set up
> >
> > I don't have a strong opinion which is better. It's nice to reuse
> > mechanisms, on the other hand loggers vs request IDs are pretty different
> > types of data.
> I'd still get rid of it. The less implicit behavior we have, the better.
> It does not seem hard to plumb the `Context` all the way through clangd
> currently. And it should not be too hard in the future.
>
> I was asking myself multiple times whether we needed the global context in
> the first place while implementing it.
> I think we should aim for avoiding global state altogether. That includes
> singletons, etc.
Removed the global context.
================
Comment at: clangd/Context.h:116
+/// Creates a new ContextBuilder, using globalCtx() as a parent.
+ContextBuilder buildCtx();
+/// Creates a new ContextBuilder with explicit \p Parent.
----------------
ilya-biryukov wrote:
> sammccall wrote:
> > This seems more naturally a method on Context, e.g.
> >
> > Context C = globalCtx().derive(key, value);
> >
> > The relationship between global and C is clear.
> >
> > (You can allow chaining+mapping by having Context::derive and
> > ContextBuilder::derive both return ContextBuilder&&, but as noted below I'm
> > not sure it's worth the complexity over Context::derive ->Context)
> I think the current interface is simple enough and allows for both storage
> implementations. I'd really avoid providing an interface that ties us into a
> single storage implementation.
Added a `derive()` method to the `Context`. It currently returns
`ContextBuilder`, I still think it's nice to have the `ContextBuilder` and a
separation between an immutable `Context` and a mutable `ContextBuilder`. Happy
to chat on whether we want to remove it.
================
Comment at: clangd/TypedValueMap.h:1
+//===--- TypedValueMap.h - Type-safe heterogenous key-value map -*- C++-*-===//
+//
----------------
ilya-biryukov wrote:
> sammccall wrote:
> > This might be doing a little more than it needs to.
> >
> > Do we need the ability to have multiple values of the same type?
> > If request ID is an int, needing to do `struct RequestID { ID int };`
> > doesn't seem like much of a burden, and simplifies the semantics here.
> >
> > And for cases like Logger where the type carries the semantics, keying by
> > type is clearer.
> Are `Key<>` types confusing? I really like the fact that I don't have to
> specify type information and it is carried in the `Key<Type>` to the
> `get`/`emplace` methods, i.e. I don't have to specify template arguments
> there.
> I don't see how `struct RequestId { ID int };` is clearer or shorter than
> `Key<int> RequestID;`. Again, are `Key<Type>` a confusing concept in the
> first place?
Unfortunately, `typeid` does not with `-fno-rtti`, so there does not seem to be
a way to significantly simplify the implementation (i.e. we'll need some form
of `Key<Type>` anyway, at least internally).
Therefore I'd keep the current interface. Does that sound ok?
================
Comment at: clangd/TypedValueMap.h:76
+
+ template <class Type, class Arg> bool emplace(PtrKey<Type> &PtrKey, Arg *A) {
+ return emplace(PtrKey.UnderlyingKey, A);
----------------
ilya-biryukov wrote:
> sammccall wrote:
> > Shouldn't this just be Type *A?
> > I think the extra convenience of PtrKey probably isn't worth the
> > complexity, though.
> With `Key<A*>` the function will be returning `A**`, which is inconvenient to
> use.
> If we index by `Type*`, as opposed to `Key<Type>`, we'll get the same
> problems.
>
> For example,
> ```
> Key<Logger*> Key;
>
> Logger ** Val = Map.get(Key); // Or Map.get<Logger*>();
> if (!Val)
> return; // No logging is enabled
>
> If (!*Val)
> return; // No logging is enabled, but the nullptr value was found in the
> map!
>
> (*Val)->logImpl(....); // Log it already!
> ```
>
> Note an extra if and extra dereference at the last line.
> I do think it's a useful addition that outweighs the complexity.
Removed `PtrKey`, added a `getPtr` helper method to the `ContextData` instead
(that does the same thing).
It's useful to have those easy-to-use helpers for common cases.
Totally agree that having a separate `PtrKey` for them is an overkill.
Repository:
rCTE Clang Tools Extra
https://reviews.llvm.org/D40485
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits