================
@@ -1637,6 +1678,144 @@ TEST(TypeHints, SubstTemplateParameterAliases) {
                         ExpectedHint{": static_vector<int>", "vector_name"});
 }
 
+template <typename... Labels>
+void assertTypeLinkHints(StringRef Code, StringRef HintRange,
+                         Labels... ExpectedLabels) {
+  Annotations Source(Code);
+  auto HintAt = [&](llvm::ArrayRef<InlayHint> InlayHints,
+                    llvm::StringRef Range) {
+    auto *Hint = llvm::find_if(InlayHints, [&](const InlayHint &InlayHint) {
+      return InlayHint.range == Source.range(Range);
+    });
+    assert(Hint && "No range was found");
+    return llvm::ArrayRef(Hint->label);
+  };
+
+  TestTU TU = TestTU::withCode(Source.code());
+  TU.ExtraArgs.push_back("-std=c++2c");
+  auto AST = TU.build();
+
+  Config C;
+  C.InlayHints.TypeNameLimit = 0;
+  WithContextValue WithCfg(Config::Key, std::move(C));
+
+  auto Hints = hintsOfKind(AST, InlayHintKind::Type);
+  EXPECT_THAT(HintAt(Hints, HintRange),
+              ElementsAre(HintLabelPieceMatcher(ExpectedLabels, Source)...));
+}
+
+TEST(TypeHints, Links) {
+  StringRef Source(R"cpp(
+    $Package[[template <class T, class U>
+    struct Package {]]};
+
+    $SpecializationOfPackage[[template <>
+    struct Package<float, const int> {]]};
+
+    $Container[[template <class... T>
+    struct Container {]]};
+
+    $NttpContainer[[template <auto... T>
+    struct NttpContainer {]]};
+
+    enum struct ScopedEnum {
+      X = 1,
+    };
+
+    enum Enum {
+      E = 2,
+    };
+
+    namespace ns {
+      $Nested[[template <class T>
+      struct Nested {
+        $NestedClass[[template <class U>
+        struct ]]Class {
+        };
+      ]]};
+
+      $NestedInt[[using NestedInt = Nested<int]]>;
+    }
+
+    void basic() {
+      auto $1[[C]] = Container<Package<char, int>>();
+      auto $2[[D]] = Container<Package<float, const int>>();
+      auto $3[[E]] = Container<Container<int, int>, long>();
+      auto $4[[F]] = NttpContainer<D, E, ScopedEnum::X, Enum::E>();
+      auto $5[[G]] = ns::Nested<Container<int>>::Class<Package<char, int>>();
+    }
+
+    void compounds() {
+      auto $6[[A]] = Container<ns::Nested<int>::Class<float>&>();
+      auto $7[[B]] = Container<ns::Nested<int>::Class<float>&&>();
+      auto $8[[C]] = Container<ns::Nested<int>::Class<const Container<int>> 
*>();
+    }
+
+    namespace nns {
+      $UsingShadow[[using ns::]]NestedInt;
+
+      void aliases() {
+        auto $9[[A]] = Container<NestedInt>();
+        auto $10[[B]] = Container<ns::NestedInt>();
+      }
+    }
+
+  )cpp");
+
+  assertTypeLinkHints(Source, "1", ExpectedHintLabelPiece{": Container<"},
----------------
HighCommander4 wrote:

My preference would be to emit a link for the outer-most types as well.

 * This feels more consistent (a type gets a link whether or not it's the 
outer-most)
 * It also matches how rust-analyzer behaves
 * I think the links in the type hint are more discoverable than the fact that 
`auto` has a go-to-def target (e.g. in vscode, just hovering over an inlay hint 
part causes an underline to appear, whereas hovering over `auto` does not)

The fact that there will then be two ways to get to the outer-most type (via 
`auto` and via the inlay hint part) does not seem problematic to me.

https://github.com/llvm/llvm-project/pull/86629
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to