linter.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "linter.h"
  2. #include "check_runner.h"
  3. #include <yql/essentials/ast/yql_ast.h>
  4. #include <yql/essentials/ast/yql_expr.h>
  5. #include <util/string/split.h>
  6. #include <functional>
  7. namespace NYql {
  8. namespace NFastCheck {
  9. namespace {
  10. class TCheckRunnerFactory : public ICheckRunnerFactory {
  11. public:
  12. using TRunnerFactoryFunction = std::function<std::unique_ptr<ICheckRunner>()>;
  13. TCheckRunnerFactory() {
  14. Registry_.emplace("lexer", MakeLexerRunner);
  15. Registry_.emplace("parser", MakeParserRunner);
  16. Registry_.emplace("format", MakeFormatRunner);
  17. Registry_.emplace("translator", MakeTranslatorRunner);
  18. for (const auto& x : Registry_) {
  19. CheckNames_.emplace(x.first);
  20. }
  21. }
  22. const TSet<TString>& ListChecks() const {
  23. return CheckNames_;
  24. }
  25. std::unique_ptr<ICheckRunner> MakeRunner(const TString& checkName) const final {
  26. auto ptr = Registry_.FindPtr(checkName);
  27. if (!ptr) {
  28. return {};
  29. }
  30. return (*ptr)();
  31. }
  32. private:
  33. THashMap<TString, TRunnerFactoryFunction> Registry_;
  34. TSet<TString> CheckNames_;
  35. };
  36. TSet<TString> GetEnabledChecks(const TSet<TString>& allChecks, const TMaybe<TVector<TCheckFilter>>& filters) {
  37. auto usedFilters = filters.GetOrElse(TVector<TCheckFilter>(1, TCheckFilter{.Include = true, .CheckNameGlob = "*"}));
  38. TSet<TString> enabledChecks;
  39. for (const auto& f : usedFilters) {
  40. if (f.CheckNameGlob == "*") {
  41. if (f.Include) {
  42. enabledChecks = allChecks;
  43. } else {
  44. enabledChecks.clear();
  45. }
  46. } else {
  47. // TODO full support of glob (* and ?)
  48. Y_ENSURE(f.CheckNameGlob.find('*') == TString::npos);
  49. Y_ENSURE(f.CheckNameGlob.find('?') == TString::npos);
  50. if (f.Include) {
  51. if (allChecks.contains(f.CheckNameGlob)) {
  52. enabledChecks.insert(f.CheckNameGlob);
  53. }
  54. } else {
  55. enabledChecks.erase(f.CheckNameGlob);
  56. }
  57. }
  58. }
  59. return enabledChecks;
  60. }
  61. TCheckRunnerFactory& GetCheckRunnerFactory() {
  62. return *Singleton<TCheckRunnerFactory>();
  63. };
  64. }
  65. TVector<TCheckFilter> ParseChecks(const TString& checks) {
  66. TVector<TCheckFilter> res;
  67. for (TStringBuf one: StringSplitter(checks).SplitByString(",")) {
  68. TCheckFilter f;
  69. TStringBuf afterPrefix = one;
  70. if (one.AfterPrefix("-", afterPrefix)) {
  71. f.Include = false;
  72. }
  73. f.CheckNameGlob = afterPrefix;
  74. res.push_back(f);
  75. }
  76. return res;
  77. }
  78. TSet<TString> ListChecks(const TMaybe<TVector<TCheckFilter>>& filters) {
  79. return GetEnabledChecks(GetCheckRunnerFactory().ListChecks(), filters);
  80. }
  81. TChecksResponse RunChecks(const TChecksRequest& request) {
  82. auto enabledChecks = GetEnabledChecks(GetCheckRunnerFactory().ListChecks(), request.Filters);
  83. TChecksResponse res;
  84. for (const auto& c : enabledChecks) {
  85. auto checkRunner = GetCheckRunnerFactory().MakeRunner(c);
  86. if (checkRunner) {
  87. res.Checks.push_back(checkRunner->Run(request));
  88. }
  89. }
  90. return res;
  91. }
  92. }
  93. }