[PATCH] D137909: [Support] Allow complex names for annotation points and ranges via ${}
Sam McCall via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 17 05:58:42 PST 2022
sammccall added a comment.
Thanks! sorry about continuing to drift this patch, but this looks like a great improvement.
Critical comments below are:
- dropping `Optional` and just use StringRef
- using one consistent way to to include payloads across the API. I think `pair<T, StringRef>` is actually best overall
Others are less important/optional if you want to get this wrapped up sooner :-)
================
Comment at: clang-tools-extra/clangd/unittests/tweaks/TweakTesting.h:119
for (const auto &P : A.points()) \
- EXPECT_EQ(Available, isAvailable(AST, {P, P})) << decorate(A.code(), P); \
+ EXPECT_EQ(Available, isAvailable(AST, {P, P, llvm::None})) \
+ << decorate(A.code(), P); \
----------------
not being able to ignore payloads (e.g. not assert the presence/absence) seems like a regression to me, this points further towards separating ranges() and rangesWithPayload
================
Comment at: llvm/include/llvm/Testing/Support/Annotations.h:58
/// represents a half-open range.
struct Range {
size_t Begin = 0;
----------------
this patch takes too many different approaches to attaching the payloads to the points:
- adding it to an existing struct that is already returned
- defining a new wrapping struct for the andPayload version
- defining a new inheriting struct for the andPayload version
I think we should keep it simple, and use `pair<T, StringRef>` for all the `andPayload` versions. This isn't optimal in isolation, but it keeps things coherent, avoiding:
- confusion around clever type-system features (inheritance, implicit conversions, smart-pointer like types, templates)
- introducing new structs whose names we have to remember
- inconsistency between how payloads are accessed between ranges/points/clangd/llvm versions
In many cases structured bindings make using the `pair` versions less cumbersome than they would have been in the past.
================
Comment at: llvm/include/llvm/Testing/Support/Annotations.h:108
+ const llvm::StringMap<llvm::SmallVector<Point, 1>> &
+ all_points_and_payloads() const;
----------------
I hadn't seen these context on these `all_` functions, I reached out to the authors to find out about them (they're used out-of-tree).
Basically the use case is to use llvm::Annotations to do the parsing, but dump out the data into some external test helper which lookups/assertions will run on.
So instead of adding extra variants, we just need to expose the parse results in some convenient way.
================
Comment at: llvm/include/llvm/Testing/Support/Annotations.h:123
std::string Code;
- llvm::StringMap<llvm::SmallVector<size_t, 1>> Points;
+ llvm::StringMap<llvm::SmallVector<Point, 1>> Points;
llvm::StringMap<llvm::SmallVector<Range, 1>> Ranges;
----------------
Internally I'd consider switching to a uniform representation of points and ranges. For two reasons:
- we're adding a new feature that's common between them
- all_points/all_ranges want to expose such a representation
Something like:
```
struct Annotation {
size_t Start;
size_t End; // or size_t(-1) for a point
StringRef Name;
StringRef Payload;
}
vector<Annotation> All;
StringMap<SmallVector<unsigned>> Points; // values are indices into All
StringMap<SmallVector<unsigned>> Ranges; // values are indices into All
ArrayRef<Annotation> all() { return All; } // replaces all_points and all_ranges
```
up to you though
================
Comment at: llvm/include/llvm/Testing/Support/Annotations.h:61
size_t End = 0;
+ llvm::Optional<llvm::StringRef> Payload;
----------------
tom-anders wrote:
> One could argue that this should just be `llvm::StringRef`. Right now, `$name^` results in `llvm::None` for the payload, while `$name()^` will yield an empty string.
>
> Do you think they should just both be empty strings instead?
Yes, I don't think that distinguishing between "no payload" and "empty payload" is useful, so would prefer the simpler API.
================
Comment at: llvm/lib/Testing/Support/Annotations.cpp:30
};
llvm::Optional<llvm::StringRef> Name;
+ llvm::Optional<llvm::StringRef> Payload;
----------------
(If using the `Annotation` struct I mentioned before, an instance of it could cover Name+Payload and it could also be the elements of OpenRanges)
================
Comment at: llvm/unittests/Support/AnnotationsTest.cpp:120
+TEST(AnnotationsTest, Payload) {
+ // A single unnamed point or range with empty payload
+ EXPECT_EQ(llvm::Annotations("a$^b").pointWithPayload(),
----------------
this is no payload specified, we should also have one test where it's specified but empty e.g. `$()^` (even if we make this equivalent to unspecified)
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D137909/new/
https://reviews.llvm.org/D137909
More information about the cfe-commits
mailing list