VitaNuo added a comment.

Thanks for the comments and the discussions!



================
Comment at: clang-tools-extra/clangd/Hover.cpp:1118
+
+  for (const auto &H : Headers) {
+    if (H.kind() == include_cleaner::Header::Physical &&
----------------
hokein wrote:
> now the for-range loop doesn't seem necessary, we could always use the 
> `Headers.front()`, right?
Ok. It seems like I need to put an `empty` check on `Headers`, however, because 
contrary to the loop, `front()` might actually crash AFAIU.


================
Comment at: clang-tools-extra/clangd/Hover.cpp:1219
         maybeAddCalleeArgInfo(N, *HI, PP);
+        maybeAddSymbolProviders(AST, *HI, include_cleaner::Symbol{*DeclToUse});
       } else if (const Expr *E = N->ASTNode.get<Expr>()) {
----------------
hokein wrote:
> I wonder how well it works for the `NamespaceDecl`. NamespaceDecl is usually 
> declared in many files, we will basically show a random provider in hover. 
> We're not interested in `NamesapceDecl`, we probably need to ignore it. 
> 
> No action required here, but this is something we should bear in mind.
Thank you.


================
Comment at: clang-tools-extra/clangd/Hover.cpp:1138
+    if (H.kind() == include_cleaner::Header::Physical &&
+        H.physical() == SM.getFileEntryForID(SM.getMainFileID()))
+      continue;
----------------
hokein wrote:
> VitaNuo wrote:
> > hokein wrote:
> > > MainFile provider is a special case (I don't recall the details).
> > > 
> > > IIUC, the model is:
> > > 
> > > 1) a symbol usage that is satisfied (e.g. any of its providers that are 
> > > directly included in the main file), we show the one with highest rank of 
> > > these included providers
> > > 2) a symbol usage that is not satisfied (we choose the highest rank of 
> > > all providers)
> > > 3) If the provider is the main-file, we don't show it in the hover card. 
> > > 
> > > Based on 1), if the main-file provider is the highest, we will not show 
> > > it in the hover based on 3). However, the current implementation doesn't 
> > > match this behavior
> > > -- on L1123 `ConvertedIncludes.match(H)` is always false  if H is a 
> > > main-file, and we will choose a lower-rank provider if the main-file is 
> > > the first element of `Headers`
> > > -- the logic here doesn't seem to work, we should do a `break` on L1139 
> > > rather than `continue`, which means we always use the `Headers[0]` 
> > > element.
> > > 
> > > Not sure we have discussed 3), one alternative is to show the information 
> > > for main-file provider as well, it seems fine to me that the hover shows 
> > > `provided by the current file` text (not the full path).
> > > we should do a break on L1139 rather than continue
> > 
> > Ok. I'm not sure if this is of great practical importance (what are the 
> > chances that the main file is the first provider, and there are more 
> > providers for the same symbol?),
> > but you're right that we shouldn't show the lower-ranked provider for this 
> > case.
> > 
> > > one alternative is to show the information for main-file provider as well
> > 
> > Yeah, this is possible ofc, but I'm not sure what the use would be. The 
> > general intention of this feature (or feature set, even) is to help users 
> > eliminate unnecessary dependencies, and they can hardly get rid of the main 
> > file :)
> > So of the two options, I'd rather opt for not showing anything at all.
> >  I'm not sure if this is of great practical importance  
> I think the code should match our mental model, otherwise it is hard to 
> reason about whether the actual behavior is expected or a bug.
> 
> > (what are the chances that the main file is the first provider, and there 
> > are more providers for the same symbol?),
> 
> I think the pattern is not rare (especially for headers), think of the case 
> below.
> 
> ```
> #include "other.h" // other.h transitively includes the `foo.h`
> 
> class Foo;
> const Foo& createFoo();
> ```
> 
> although the main-file provider is not the top1 given the current ranking 
> implementation, we have a plan to address it, see the FIXME in 
> https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp#L219.
>  After addressing the FIXME, the main-file could be the top1.
> 
> > on L1123 ConvertedIncludes.match(H) is always false if H is a main-file, 
> > and we will choose a lower-rank provider if the main-file is the first 
> > element of Headers
> 
> This comment doesn't seem to be addressed, now it is L1105.
> 
> Given the following case, if the returned providers is [main-file, `foo.h`], 
> the current code will show `foo.h` in hover.
> However, based on our mental model:
>  1) the main-file is one of the `Foo` providers, and it is the top1, we 
> choose it
>  2) we don't show main-file provider in hover
> -> we should not show any information in hover.
> 
> ```
> #include "foo.h"
> 
> class Foo;
> Foo* b;  // hover on `Foo`.
> ```
> I think the pattern is not rare (especially for headers), think of the case 
> below.

Makes sense, I didn't think about headers at all.

> This comment doesn't seem to be addressed, now it is L1105.

Oops. See the current version please.


================
Comment at: clang-tools-extra/clangd/IncludeCleaner.cpp:258
+std::vector<include_cleaner::SymbolReference>
+collectMacroReferences(ParsedAST &AST) {
+  const auto &SM = AST.getSourceManager();
----------------
hokein wrote:
> let's keep it unchanged, we don't need any change for this function in this 
> patch.
oh it's not changed, just got moved because of the other two. But no worries, I 
can put it exactly in the previous position.


================
Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:2897
+    const std::function<void(HoverInfo &)> ExpectedBuilder;
+  } Cases[] = {
+      {Annotations(
----------------
hokein wrote:
> I have some trouble following the test here:
> 
> - this is a long list of testcases (see my other comments)
> - we construct each testcase with five fields, it is hard to track which 
> content is for foo.h/bar.h/foobar.h
> 
> I'd suggest to find way to simplify it, some ideas
> - we can use a fixed content foo.h, foo_fwd.h for all testcases (I guess 
> something like below should be enough to cover the major cases), so that we 
> don't need to specify all these content in every testcase.
> - only test critical cases 1) symbol ref is satisfied (by the main-file 
> provider or by regular headers) 2) symbol ref is not satisfied, verify we 
> show first provider of `Providers`. And test 3 different symbol kinds 
> (regular decl, macro, operator)
> 
> 
> // foo.h
> #define FOO 1
> class Foo {};
> Foo& operator+(const Foo, const Foo);
> 
> // foo_fwd.h
> class Foo;
> 
> // all.h
> #include "foo.h"
> #include "foo_fwd.h"
Ok, I have simplified the test considerably. Please take a look.


================
Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:2922
+                  #include "foo.h"
+                  int F = [[^foo]]();
+                )cpp"),
----------------
hokein wrote:
> unclear to me the intention of this testcase.
Testing that `foo.h` is ranked higher since it's providing the symbol directly. 
But maybe this makes no sense, I will remove it then.


================
Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:2948
+
+                 Foo [[f^oo]] = 42;
+                )cpp"),
----------------
hokein wrote:
> this case seems to be duplicated with the first one, can be removed, I think.
yeah this is also provided by the main file


================
Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:3008
+       "#define MACRO 5",
+       "#define MACRO 10", "",
+       [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
----------------
hokein wrote:
> This will have macro-redefined warnings, `foo.h` is better than `bar.h` 
> because the MACRO in main-file refers to the one defined in `foo.h`. Not sure 
> the value of this testcase, I would suggest dropping it for simplicity.
> 
> The same for the below one.
ok.


================
Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:3023
+                  #include "foo.h"
+                  int [[^F]] = MACRO(5);
+                )cpp"),
----------------
hokein wrote:
> this seems to be duplicated with the first testcase, nothing related to 
> macro, can be dropped as well.
ok.


================
Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:3123
+
+  HoverInfo HIFooBar;
+  HIFooBar.Name = "foo";
----------------
hokein wrote:
> What's the difference between `HIFoo` and `HIFooBar`? Looks like they are the 
> same.
> 
> I guess you want to check the `<>` and `""` cases?
yes, thank you.


================
Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:3139
+    #include "absl_string_view.h"
+    absl::str^ing_view abc; // hover on string_view
+  )cpp");
----------------
hokein wrote:
> I think we can simplify this test and merge it to the above `TEST(Hover, 
> Providers)`. 
> 
> Just verifying the hover symbol respects the using decl is sufficient, 
> something like
> 
> ```
> #include "foo.h"
> 
> namespace ns {
> using ::Foo;
> }
> 
> ns::F^oo d; // verify that provider in hover is the main-file.
> ```
Ok, I will translate this to a "foobar" example. But I think the correct answer 
in this example is actually `foo.h` since we want the provider of the 
underlying decl, not the using decl.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144976

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to