This is an archive of the discontinued LLVM Phabricator instance.

Added functionality to suggest FixIts for conversion of '->' to '.' and vice versa.
ClosedPublic

Authored by kadircet on Aug 2 2018, 9:42 AM.

Event Timeline

kadircet created this revision.Aug 2 2018, 9:42 AM

Thanks for the change! Overall LG, mostly NITs about the tests.

clangd/CodeComplete.cpp
960

NIT: this change is unrelated, maybe remove from the diff?

We can submit it separately without review, since it's a noop formatting cleanup

1102–1103

Same here: maybe remove from this change and submit separately?
Again, no review needed, this is clearly a no-op change

1292

IIUC, it does not play nicely with the insertText in VSCode, right? (I.e. completing this.^ will produce this-push_back)
Let's add a FIXME comment explaining this case and indicate how we're going to fix this (using textEdit instead of the insertText, right?)

unittests/clangd/CodeCompleteTests.cpp
508

NIT: also submit as a separate change?

1381

Maybe remove the body of opeartor->() and the private field?
Will make the test a little smaller.

1385

Maybe remove namespace and put everything into global ns?

1388

Maybe tests without the prefix, so that both AuxFunction and MemberFunction are available and assert that AuxFunction does not have a fix-it?

1396

This can be made more readable with helpers from unittests/clangd/Annotations.h.

Annotations Source(R"cpp(
/// ....
void f() {
  ClassWithPtr x;
  x[[->]]MemberFunction^ 
})cpp");

Source.point(); // <-- completion point
Source.range(); // <-- range for the fix-it

Our completions helper already has parsing of annotations internally, though. But we can write a new overload for the helper that accepts completion point and the parsed text directly.

yvvan added a subscriber: yvvan.Aug 3 2018, 2:47 AM
kadircet updated this revision to Diff 159000.Aug 3 2018, 6:54 AM
kadircet marked 8 inline comments as done.

Fixed discussions

ilya-biryukov added inline comments.Aug 3 2018, 9:05 AM
clangd/CodeComplete.cpp
286

IIRC LangOptions are actually important when running lexer (that is used internally to measure the length of the tokens).
Use ASTCtx.getLangOptions()?

clangd/SourceCode.cpp
11

NIT: no need for this include in .cpp file, since the header already has that.

clangd/SourceCode.h
16

NIT: #include "clang/Basic/Diagnostic.h" should be enough here

unittests/clangd/CodeCompleteTests.cpp
82–83

Maybe accept a stringref to source code and completion point directly?
A potential use-case: Annotaions instance might have multiple named rangers (e.g. if you have multiple completion points in same code and want to test one after another). In that case, point() will fail with an assert if we pass Annotations directly

kadircet updated this revision to Diff 159261.Aug 6 2018, 2:21 AM
kadircet marked 4 inline comments as done.

Added functionality to suggest FixIts for conversion of '->' to '.' and vice versa.

  • Fixes for comments.
  • Take unnecessary patches back
  • Second pass for comments.
  • Add downranking for scores of fixit elements.

Thanks! The only major comment I have is about the FixItsScore, others are mostly NITs.

clangd/Quality.cpp
298

NIT: remove braces around single-statement loop body

clangd/Quality.h
80

The comment is a bit misleading, since it's actually the length of the inserted code.
I'd suggest keeping the comment and a name of this variable a bit more vague on the definition of this field, e.g. something like

int FixItScore; // Measure of the total amount of edit needed by the fix-its. Higher is worse, i.e. more code needs to change

And overall, it looks like the penalty might be too harsh for some potential fix-its. E.g. imagine a fix-it that adds a using ns::some_class directive somewhere to the file. The size of the inserted text will be proprotional to the size of the fully-qualfiied-name of the class, but it does not seem like the fix-its for items with larger names should be downranked more than others, after all it's the same type of fix-it.

// Hypothetical example, we don't have fix-its like that yet.
namespace ns {
  class SomeVeryLongName {};
  class ShortName {};
}


^ // <-- complete here, imagine the completion items for both classes are available and 
  // add `using ns::<ClassName>;`  to the global namespace.

In that case, we will penalize SomeVeryLongName more than ShortName, because it has a longer fix-it, but it does not look like a useful distinction.
I suggest we start with something simple, like having the same predefined penalty for all fix-its or penalize based on the number of fix-its in the list. We can generalize later when we see more fix-its and have a better understanding on penalties we want from them

unittests/clangd/CodeCompleteTests.cpp
112

NIT: use const Annotations&?

119

The number of completions overloads seems to be getting out of hand.
Any ideas on how we can reduce them?

Generally, I think we want the most general version:

CodeCompleteResult completionsImpl(ClangdServer&, Text, Point, Index, Opts)

And two conveniece wrappers that create ClangdServer for us:

// Parses Annotations(Text) and creates a ClangdServer instance.
CodeCompleteResult completions(Text, Index = ..., Opts = ...);
// Only creates a ClangdServer instance.
CodeCompleteResult completions(Text, Point, Index=..., Opts =...);

Can we make the rest of the code to use this API? (e.g. if function accepts a ClangdServer, the callers have to do quite a bit of setup anyway and I don't think adding the annotations parsing to get the completion point will hurt the readability there).

1397

NIT: remove braces around single-statement ifs, LLVM code generally tends to avoid adding braces around single-statement bodies of loops, conditionals, etc

1439

We tend to unit-test the scores separately from general completion tests.
Could we replace this test with a unit-test in QualityTests.cpp?

kadircet updated this revision to Diff 159510.Aug 7 2018, 7:51 AM
kadircet marked 6 inline comments as done.
  • Resolve discussions.
ilya-biryukov accepted this revision.Aug 7 2018, 10:18 AM

LGTM, with a few NITs.
Thanks for the change!

clangd/Quality.h
81

NIT: put the comment at the previous line to keep false at the same line.
NIT2: use three slashes, to make it a doxygen comment (previous one should also be three slashes).

unittests/clangd/CodeCompleteTests.cpp
99

It seems this comment got moved accidentally, move it back?

unittests/clangd/QualityTests.cpp
360 ↗(On Diff #159510)

NIT: took me some time to figure out the difference between this and the next one.
Maybe add the explicit type name to make more implicit that we're creating a fix-it here, i.e. {FixItHint{}}?

This revision is now accepted and ready to land.Aug 7 2018, 10:18 AM
kadircet updated this revision to Diff 159648.Aug 8 2018, 1:05 AM
kadircet marked 3 inline comments as done.
  • Resolve some more discussions.
This revision was automatically updated to reflect the committed changes.