This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Add marshalling code for all request types
ClosedPublic

Authored by kbobyrev on Jul 24 2020, 6:36 AM.

Details

Summary

Only FuzzyFindRequest is implemented via Marshaller even though other requests
also follow a similar pattern. Unify them under the marshalling umbrella and
make the server requests even more uniform to complement D84499.

Diff Detail

Event Timeline

kbobyrev created this revision.Jul 24 2020, 6:36 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 24 2020, 6:36 AM
kadircet added inline comments.Jul 24 2020, 8:15 AM
clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp
69–80

nit: move anon namespace to the top

71

I would make this return an expected instead of an optional and print the error in the callers, instead of logging twice.

(I also think a similar problem is present with the existing fromProtobuf APIs too, they return None in case of failure while logging the error, and then callers again log the error. I am not sure if we plan to implement some error handling strategies but even if we did, it feels like Marshalling is the lowest layer that wouldn't know any other strategy to handle such errors, so it seems like always returning an error from the marshalling and letting the caller handle the error sounds like a safe bet. But no action needed in this patch just stating some ideas in case you find them useful :D)

clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
308–309

ASSERT_TRUE to ensure we don't try to dereference in case of None.

kbobyrev updated this revision to Diff 280476.Jul 24 2020, 8:57 AM
kbobyrev marked 4 inline comments as done.

Address review comments.

clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp
71

Good point: we thought about error handling and discussed it with Sam on multiple occasions, we tested several strategies and I think converged to this. I don't think it's optimal, you are right, but this code is consistent with the rest of the file.

The problem here is that in some cases these should actually be Optionals (some fields may or may not be missing) and in some cases it makes sense to have Expecteds, which would leave a weird mixture of these things. But maybe carefully thinking about those cases would simplify the code.

How do you feel about leaving this as is and maybe carefully thinking about Optionals to Expected in the next patches?

clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
308–309

Good point, I should do ASSERT_TRUE in most cases throughout the file.

kbobyrev updated this revision to Diff 280600.Jul 24 2020, 3:06 PM

Add missing Limit & Filter for fromProtobuf(RefsRequest *)

kbobyrev marked an inline comment as not done.Jul 24 2020, 3:08 PM
kbobyrev updated this revision to Diff 280819.Jul 27 2020, 1:47 AM

Fix formatting.

kbobyrev updated this revision to Diff 280820.Jul 27 2020, 1:47 AM

Rebase on top of master.

kadircet added inline comments.Jul 27 2020, 1:55 AM
clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp
71

Good point: we thought about error handling and discussed it with Sam on multiple occasions, we tested several strategies and I think converged to this. I don't think it's optimal, you are right, but this code is consistent with the rest of the file.

i believe rest of the file doesn't handle such low level primitives, i.e. this one is specifically for extracting symbol ids, not for converting bigger proto messages into native structs (as done in the rest of the file)

The problem here is that in some cases these should actually be Optionals (some fields may or may not be missing) and in some cases it makes sense to have Expecteds, which would leave a weird mixture of these things. But maybe carefully thinking about those cases would simplify the code.

i agree that it might be the case in other places, I haven't really looked at them carefully and they are also submitted (hence they were in parentheses in my previous comment). But I think the situation specifically in here is a little bit different.
There is a more clear struct for indicating missing fields in here, an empty set of results(and actually you are using that already), and using None to indicate an error. I believe using an Error (through an Expected) is a lot clear to indicate that.

How do you feel about leaving this as is and maybe carefully thinking about Optionals to Expected in the next patches?

As I mentioned, I believe this one is different than other places, and at least my taste/reasoning says that this should clearly be an Expected rather than an Optional. But it is not a big issue for me totally up to you.

109

can you also add tests for these? (well actually it looks like there are no tests for LookupRequests too)

kbobyrev planned changes to this revision.Jul 27 2020, 2:08 AM

Need to address the review comments.

kbobyrev updated this revision to Diff 280840.Jul 27 2020, 3:29 AM
kbobyrev marked 4 inline comments as done.

Resolve the remaining comments.

mostly LG. sorry for lots of nits, only two important bits are changing the {1} to {0} in logs, wrapping symbolid generations in llvm::cantFail and making sure Deserialized is exactly the same thing as Request in tests. feel free to ignore the rest (I should've marked them with nit hopefully, but might've missed some)

clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp
104

nit: braces

clang-tools-extra/clangd/index/remote/server/Server.cpp
65

printing indices are zero-based so

s/{1}/{0}/g

(same for others)

clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
277

you can wrap these in llvm::cantFail as the symbolid generation bit is constant, and isn't really something we are testing here

nit: also I would suggest a less random string to indicate that these are arbitrary like 0000...001 (the length still needs to match tho)

287

nit: instead of 2 use Request.IDs.size()

Moreover, SymbolID has an opreator== so in theory you could do an EXPECT_THAT(Serialized.ids(), ElementsAreArray(Request.IDs)) trick to make this check even nicer. But I am not sure about how nicely repeated proto fields plays with gtest version in llvm. So if it doesn't work nvm. (same for the other places with this pattern)

290

you should definitely be able to make sure IDs are exactly the same with Request.IDs

292

nit: I would put this one into a separate test

329

again I would suggest comparing to Requests.IDs.size(), and other relevant fields below instead of repeating some constants (which would be tedious to change in future)

333

again I would make sure IDs are same element-wise in here.

338

nit: again this could be a separate test

kbobyrev updated this revision to Diff 280853.Jul 27 2020, 4:33 AM
kbobyrev marked 9 inline comments as done.

Resolve nits.

kadircet accepted this revision.Jul 27 2020, 4:53 AM

thanks for bearing with me, LGTM!

clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
277

nit: you could inline these into insert calls now.

290

looks like you forgot to delete this

328

s/9000U/Request.Limit

333

s/9000U/Request.Limit

334

s/RefKind::Spelled | RefKind::Declaration/Request.Filter

336

again you forgot to delete this

This revision is now accepted and ready to land.Jul 27 2020, 4:53 AM
kbobyrev updated this revision to Diff 280862.Jul 27 2020, 5:14 AM
kbobyrev marked 6 inline comments as done.

Address post-LGTM comments.

This revision was automatically updated to reflect the committed changes.