|
7 | 7 | //===----------------------------------------------------------------------===// |
8 | 8 |
|
9 | 9 | #include "ClangTidyOptions.h" |
| 10 | +#include "../clang-query/Query.h" |
| 11 | +#include "../clang-query/QueryParser.h" |
10 | 12 | #include "ClangTidyModuleRegistry.h" |
11 | 13 | #include "clang/Basic/LLVM.h" |
12 | 14 | #include "llvm/ADT/SmallString.h" |
@@ -126,6 +128,83 @@ void yamlize(IO &IO, ClangTidyOptions::OptionMap &Val, bool, |
126 | 128 | } |
127 | 129 | } |
128 | 130 |
|
| 131 | +std::vector<clang::ast_matchers::dynamic::DynTypedMatcher> |
| 132 | +processQuerySource(IO &IO, StringRef SourceRef, |
| 133 | + clang::query::QuerySession &QS) { |
| 134 | + namespace query = clang::query; |
| 135 | + std::vector<clang::ast_matchers::dynamic::DynTypedMatcher> Matchers; |
| 136 | + |
| 137 | + while (!SourceRef.empty()) { |
| 138 | + query::QueryRef Q = query::QueryParser::parse(SourceRef, QS); |
| 139 | + switch (Q->Kind) { |
| 140 | + case query::QK_Match: { |
| 141 | + const auto &MatchQuerry = llvm::cast<query::MatchQuery>(*Q); |
| 142 | + Matchers.push_back(MatchQuerry.Matcher); |
| 143 | + break; |
| 144 | + } |
| 145 | + case query::QK_Let: { |
| 146 | + const auto &LetQuerry = llvm::cast<query::LetQuery>(*Q); |
| 147 | + LetQuerry.run(llvm::errs(), QS); |
| 148 | + break; |
| 149 | + } |
| 150 | + case query::QK_Invalid: { |
| 151 | + const auto &InvalidQuerry = llvm::cast<query::InvalidQuery>(*Q); |
| 152 | + for (const auto &Line : llvm::split(InvalidQuerry.ErrStr, "\n")) { |
| 153 | + IO.setError(Line); |
| 154 | + } |
| 155 | + break; |
| 156 | + } |
| 157 | + // FIXME FileQuerry should also be supported, but what to do with relative |
| 158 | + // paths? |
| 159 | + case query::QK_File: |
| 160 | + case query::QK_DisableOutputKind: |
| 161 | + case query::QK_EnableOutputKind: |
| 162 | + case query::QK_SetOutputKind: |
| 163 | + case query::QK_SetTraversalKind: |
| 164 | + case query::QK_Help: |
| 165 | + case query::QK_NoOp: |
| 166 | + case query::QK_Quit: |
| 167 | + case query::QK_SetBool: { |
| 168 | + IO.setError("unsupported querry kind"); |
| 169 | + } |
| 170 | + } |
| 171 | + SourceRef = Q->RemainingContent; |
| 172 | + } |
| 173 | + |
| 174 | + return Matchers; |
| 175 | +} |
| 176 | + |
| 177 | +template <> |
| 178 | +void yamlize(IO &IO, ClangTidyOptions::QueryCheckMap &Val, bool, |
| 179 | + EmptyContext &Ctx) { |
| 180 | + IO.beginMapping(); |
| 181 | + if (IO.outputting()) { |
| 182 | + for (auto &[k, v] : Val) { |
| 183 | + IO.mapRequired(k.data(), v); |
| 184 | + } |
| 185 | + } else { |
| 186 | + for (StringRef Key : IO.keys()) { |
| 187 | + IO.mapRequired(Key.data(), Val[Key]); |
| 188 | + } |
| 189 | + } |
| 190 | + IO.endMapping(); |
| 191 | +} |
| 192 | + |
| 193 | +template <> |
| 194 | +void yamlize(IO &IO, ClangTidyOptions::QueryCheckValue &Val, bool, |
| 195 | + EmptyContext &Ctx) { |
| 196 | + if (IO.outputting()) { |
| 197 | + StringRef SourceRef = Val.Source; |
| 198 | + IO.blockScalarString(SourceRef); |
| 199 | + } else { |
| 200 | + StringRef SourceRef; |
| 201 | + IO.blockScalarString(SourceRef); |
| 202 | + Val.Source = SourceRef; |
| 203 | + clang::query::QuerySession QS({}); |
| 204 | + Val.Matchers = processQuerySource(IO, SourceRef, QS); |
| 205 | + } |
| 206 | +} |
| 207 | + |
129 | 208 | struct ChecksVariant { |
130 | 209 | std::optional<std::string> AsString; |
131 | 210 | std::optional<std::vector<std::string>> AsVector; |
@@ -181,6 +260,7 @@ template <> struct MappingTraits<ClangTidyOptions> { |
181 | 260 | IO.mapOptional("InheritParentConfig", Options.InheritParentConfig); |
182 | 261 | IO.mapOptional("UseColor", Options.UseColor); |
183 | 262 | IO.mapOptional("SystemHeaders", Options.SystemHeaders); |
| 263 | + IO.mapOptional("ClangQueryChecks", Options.ClangQueryChecks); |
184 | 264 | } |
185 | 265 | }; |
186 | 266 |
|
@@ -249,6 +329,10 @@ ClangTidyOptions &ClangTidyOptions::mergeWith(const ClangTidyOptions &Other, |
249 | 329 | ClangTidyValue(KeyValue.getValue().Value, |
250 | 330 | KeyValue.getValue().Priority + Order)); |
251 | 331 | } |
| 332 | + |
| 333 | + for (const auto &KeyValue : Other.ClangQueryChecks) { |
| 334 | + ClangQueryChecks.insert_or_assign(KeyValue.getKey(), KeyValue.getValue()); |
| 335 | + } |
252 | 336 | return *this; |
253 | 337 | } |
254 | 338 |
|
|
0 commit comments