summarylogtreecommitdiffstats
path: root/inlay-hints-hide-deduced-types-ignore-evident.patch
blob: f146dd0b86ecaca26a67b8515b7ce57e8fc94359 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp
index d56b93e5f3..104341945d 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -650,6 +650,74 @@ public:
           T = D->getType();
         }
         if (!T.isNull()) {
+          // Filter evident types.
+          if (const auto *IE = D->getInit()) {
+            // Ignore literals
+            // (e.g. `auto x = 3.14f`).
+            if (llvm::isa<CompoundLiteralExpr>(IE) ||
+                llvm::isa<CXXBoolLiteralExpr>(IE) ||
+                llvm::isa<CXXNullPtrLiteralExpr>(IE) ||
+                llvm::isa<FixedPointLiteral>(IE) ||
+                llvm::isa<FloatingLiteral>(IE) ||
+                llvm::isa<ImaginaryLiteral>(IE) ||
+                llvm::isa<IntegerLiteral>(IE) || llvm::isa<StringLiteral>(IE) ||
+                llvm::isa<UserDefinedLiteral>(IE))
+              return true;
+
+            if (auto *CE = llvm::dyn_cast<CastExpr>(IE)) {
+              // Ignore type-independend cast expressions
+              // (e.g. `auto x = static_cast<int>(42)`).
+              if (auto *ECE = llvm::dyn_cast<ExplicitCastExpr>(CE)) {
+                const auto CT = ECE->getTypeAsWritten();
+                if (!CT->isDependentType())
+                  return true;
+              }
+            }
+
+            // Ignore variables, what contains type in name
+            // (e.g. `auto iCounter = GetSomeInteger()`,
+            //       `auto hWnd = GetWindowHandle()`,
+            //       `auto dwTimer = GetTickCount()`).
+            static constexpr auto KPrefixes = {"m_", "ms_", "_", "m", ""};
+            const auto VarName = D->getNameAsString();
+            const auto TypeName = maybeDesugar(AST, D->getType()).getAsString();
+            std::string TypeNameLower = TypeName;
+            std::transform(TypeName.begin(), TypeName.end(),
+                           TypeNameLower.begin(), ::tolower);
+            for (const auto *Prefix : KPrefixes) {
+              const auto PrefixLength = strlen(Prefix);
+              if (VarName.size() <= PrefixLength)
+                continue;
+              if (VarName.find(Prefix) != 0)
+                continue;
+
+              const std::string_view VarNameNoPrefix = &VarName[strlen(Prefix)];
+              if (VarNameNoPrefix.size() > TypeName.length()) {
+                if (VarNameNoPrefix.find(TypeName) == 0 &&
+                    (VarNameNoPrefix[TypeName.length()] == '_' ||
+                     (islower(VarNameNoPrefix[TypeName.length() - 1]) &&
+                      isupper(VarNameNoPrefix[TypeName.length()]))))
+                  return true;
+
+                if (VarNameNoPrefix.find(TypeNameLower) == 0 &&
+                    (VarNameNoPrefix[TypeName.length()] == '_' ||
+                     isupper(VarNameNoPrefix[TypeName.length()])))
+                  return true;
+              }
+
+              std::string_view TypeNameShort = "";
+              auto TypeNameShortLength = 0u;
+              for (auto I = 0u;
+                   I < VarNameNoPrefix.size() && islower(VarNameNoPrefix[I]);
+                   ++I)
+                ++TypeNameShortLength;
+              if (TypeNameShortLength > 0) {
+                TypeNameShort = VarNameNoPrefix.substr(0, TypeNameShortLength);
+                if (std::string_view{TypeNameLower}.find(TypeNameShort) == 0)
+                  return true;
+              }
+            }
+          }
           // Our current approach is to place the hint on the variable
           // and accordingly print the full type
           // (e.g. for `const auto& x = 42`, print `const int&`).