diff options
author | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
commit | 6ffe9e53658409f212834330e13564e4952558f6 (patch) | |
tree | 85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/clang16/lib/ASTMatchers/GtestMatchers.cpp | |
parent | 726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff) | |
download | ydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz |
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/clang16/lib/ASTMatchers/GtestMatchers.cpp')
-rw-r--r-- | contrib/libs/clang16/lib/ASTMatchers/GtestMatchers.cpp | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/contrib/libs/clang16/lib/ASTMatchers/GtestMatchers.cpp b/contrib/libs/clang16/lib/ASTMatchers/GtestMatchers.cpp new file mode 100644 index 0000000000..6e4c12f319 --- /dev/null +++ b/contrib/libs/clang16/lib/ASTMatchers/GtestMatchers.cpp @@ -0,0 +1,234 @@ +//===- GtestMatchers.cpp - AST Matchers for Gtest ---------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements several matchers for popular gtest macros. In general, +// AST matchers cannot match calls to macros. However, we can simulate such +// matches if the macro definition has identifiable elements that themselves can +// be matched. In that case, we can match on those elements and then check that +// the match occurs within an expansion of the desired macro. The more uncommon +// the identified elements, the more efficient this process will be. +// +//===----------------------------------------------------------------------===// + +#include "clang/ASTMatchers/GtestMatchers.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { +namespace ast_matchers { +namespace { + +enum class MacroType { + Expect, + Assert, + On, +}; + +} // namespace + +static DeclarationMatcher getComparisonDecl(GtestCmp Cmp) { + switch (Cmp) { + case GtestCmp::Eq: + return cxxMethodDecl(hasName("Compare"), + ofClass(cxxRecordDecl(isSameOrDerivedFrom( + hasName("::testing::internal::EqHelper"))))); + case GtestCmp::Ne: + return functionDecl(hasName("::testing::internal::CmpHelperNE")); + case GtestCmp::Ge: + return functionDecl(hasName("::testing::internal::CmpHelperGE")); + case GtestCmp::Gt: + return functionDecl(hasName("::testing::internal::CmpHelperGT")); + case GtestCmp::Le: + return functionDecl(hasName("::testing::internal::CmpHelperLE")); + case GtestCmp::Lt: + return functionDecl(hasName("::testing::internal::CmpHelperLT")); + } + llvm_unreachable("Unhandled GtestCmp enum"); +} + +static llvm::StringRef getMacroTypeName(MacroType Macro) { + switch (Macro) { + case MacroType::Expect: + return "EXPECT"; + case MacroType::Assert: + return "ASSERT"; + case MacroType::On: + return "ON"; + } + llvm_unreachable("Unhandled MacroType enum"); +} + +static llvm::StringRef getComparisonTypeName(GtestCmp Cmp) { + switch (Cmp) { + case GtestCmp::Eq: + return "EQ"; + case GtestCmp::Ne: + return "NE"; + case GtestCmp::Ge: + return "GE"; + case GtestCmp::Gt: + return "GT"; + case GtestCmp::Le: + return "LE"; + case GtestCmp::Lt: + return "LT"; + } + llvm_unreachable("Unhandled GtestCmp enum"); +} + +static std::string getMacroName(MacroType Macro, GtestCmp Cmp) { + return (getMacroTypeName(Macro) + "_" + getComparisonTypeName(Cmp)).str(); +} + +static std::string getMacroName(MacroType Macro, llvm::StringRef Operation) { + return (getMacroTypeName(Macro) + "_" + Operation).str(); +} + +// Under the hood, ON_CALL is expanded to a call to `InternalDefaultActionSetAt` +// to set a default action spec to the underlying function mocker, while +// EXPECT_CALL is expanded to a call to `InternalExpectedAt` to set a new +// expectation spec. +static llvm::StringRef getSpecSetterName(MacroType Macro) { + switch (Macro) { + case MacroType::On: + return "InternalDefaultActionSetAt"; + case MacroType::Expect: + return "InternalExpectedAt"; + default: + llvm_unreachable("Unhandled MacroType enum"); + } + llvm_unreachable("Unhandled MacroType enum"); +} + +// In general, AST matchers cannot match calls to macros. However, we can +// simulate such matches if the macro definition has identifiable elements that +// themselves can be matched. In that case, we can match on those elements and +// then check that the match occurs within an expansion of the desired +// macro. The more uncommon the identified elements, the more efficient this +// process will be. +// +// We use this approach to implement the derived matchers gtestAssert and +// gtestExpect. +static internal::BindableMatcher<Stmt> +gtestComparisonInternal(MacroType Macro, GtestCmp Cmp, StatementMatcher Left, + StatementMatcher Right) { + return callExpr(isExpandedFromMacro(getMacroName(Macro, Cmp)), + callee(getComparisonDecl(Cmp)), hasArgument(2, Left), + hasArgument(3, Right)); +} + +static internal::BindableMatcher<Stmt> +gtestThatInternal(MacroType Macro, StatementMatcher Actual, + StatementMatcher Matcher) { + return cxxOperatorCallExpr( + isExpandedFromMacro(getMacroName(Macro, "THAT")), + hasOverloadedOperatorName("()"), hasArgument(2, Actual), + hasArgument( + 0, expr(hasType(classTemplateSpecializationDecl(hasName( + "::testing::internal::PredicateFormatterFromMatcher"))), + ignoringImplicit( + callExpr(callee(functionDecl(hasName( + "::testing::internal::" + "MakePredicateFormatterFromMatcher"))), + hasArgument(0, ignoringImplicit(Matcher))))))); +} + +static internal::BindableMatcher<Stmt> +gtestCallInternal(MacroType Macro, StatementMatcher MockCall, MockArgs Args) { + // A ON_CALL or EXPECT_CALL macro expands to different AST structures + // depending on whether the mock method has arguments or not. + switch (Args) { + // For example, + // `ON_CALL(mock, TwoParamMethod)` is expanded to + // `mock.gmock_TwoArgsMethod(WithoutMatchers(), + // nullptr).InternalDefaultActionSetAt(...)`. + // EXPECT_CALL is the same except + // that it calls `InternalExpectedAt` instead of `InternalDefaultActionSetAt` + // in the end. + case MockArgs::None: + return cxxMemberCallExpr( + isExpandedFromMacro(getMacroName(Macro, "CALL")), + callee(functionDecl(hasName(getSpecSetterName(Macro)))), + onImplicitObjectArgument(ignoringImplicit(MockCall))); + // For example, + // `ON_CALL(mock, TwoParamMethod(m1, m2))` is expanded to + // `mock.gmock_TwoParamMethod(m1,m2)(WithoutMatchers(), + // nullptr).InternalDefaultActionSetAt(...)`. + // EXPECT_CALL is the same except that it calls `InternalExpectedAt` instead + // of `InternalDefaultActionSetAt` in the end. + case MockArgs::Some: + return cxxMemberCallExpr( + isExpandedFromMacro(getMacroName(Macro, "CALL")), + callee(functionDecl(hasName(getSpecSetterName(Macro)))), + onImplicitObjectArgument(ignoringImplicit(cxxOperatorCallExpr( + hasOverloadedOperatorName("()"), argumentCountIs(3), + hasArgument(0, ignoringImplicit(MockCall)))))); + } + llvm_unreachable("Unhandled MockArgs enum"); +} + +static internal::BindableMatcher<Stmt> +gtestCallInternal(MacroType Macro, StatementMatcher MockObject, + llvm::StringRef MockMethodName, MockArgs Args) { + return gtestCallInternal( + Macro, + cxxMemberCallExpr( + onImplicitObjectArgument(MockObject), + callee(functionDecl(hasName(("gmock_" + MockMethodName).str())))), + Args); +} + +internal::BindableMatcher<Stmt> gtestAssert(GtestCmp Cmp, StatementMatcher Left, + StatementMatcher Right) { + return gtestComparisonInternal(MacroType::Assert, Cmp, Left, Right); +} + +internal::BindableMatcher<Stmt> gtestExpect(GtestCmp Cmp, StatementMatcher Left, + StatementMatcher Right) { + return gtestComparisonInternal(MacroType::Expect, Cmp, Left, Right); +} + +internal::BindableMatcher<Stmt> gtestAssertThat(StatementMatcher Actual, + StatementMatcher Matcher) { + return gtestThatInternal(MacroType::Assert, Actual, Matcher); +} + +internal::BindableMatcher<Stmt> gtestExpectThat(StatementMatcher Actual, + StatementMatcher Matcher) { + return gtestThatInternal(MacroType::Expect, Actual, Matcher); +} + +internal::BindableMatcher<Stmt> gtestOnCall(StatementMatcher MockObject, + llvm::StringRef MockMethodName, + MockArgs Args) { + return gtestCallInternal(MacroType::On, MockObject, MockMethodName, Args); +} + +internal::BindableMatcher<Stmt> gtestOnCall(StatementMatcher MockCall, + MockArgs Args) { + return gtestCallInternal(MacroType::On, MockCall, Args); +} + +internal::BindableMatcher<Stmt> gtestExpectCall(StatementMatcher MockObject, + llvm::StringRef MockMethodName, + MockArgs Args) { + return gtestCallInternal(MacroType::Expect, MockObject, MockMethodName, Args); +} + +internal::BindableMatcher<Stmt> gtestExpectCall(StatementMatcher MockCall, + MockArgs Args) { + return gtestCallInternal(MacroType::Expect, MockCall, Args); +} + +} // end namespace ast_matchers +} // end namespace clang |