File: base.cpp

package info (click to toggle)
watchman 4.9.0-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,992 kB
  • sloc: cpp: 27,459; python: 6,538; java: 3,404; php: 3,257; ansic: 2,803; javascript: 1,116; makefile: 671; ruby: 364; sh: 124; xml: 102; lisp: 4
file content (127 lines) | stat: -rw-r--r-- 3,197 bytes parent folder | download | duplicates (3)
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* Copyright 2013-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */

#include "watchman.h"

#include <vector>
#include "make_unique.h"

/* Basic boolean and compound expressions */

class NotExpr : public QueryExpr {
  std::unique_ptr<QueryExpr> expr;

 public:
  explicit NotExpr(std::unique_ptr<QueryExpr> other_expr)
      : expr(std::move(other_expr)) {}

  bool evaluate(w_query_ctx* ctx, const FileResult* file) override {
    return !expr->evaluate(ctx, file);
  }
  static std::unique_ptr<QueryExpr> parse(
      w_query* query,
      const json_ref& term) {
    /* rigidly require ["not", expr] */
    if (!json_is_array(term) || json_array_size(term) != 2) {
      throw QueryParseError("must use [\"not\", expr]");
    }

    const auto& other = term.at(1);
    auto other_expr = w_query_expr_parse(query, other);
    return watchman::make_unique<NotExpr>(std::move(other_expr));
  }
};

W_TERM_PARSER("not", NotExpr::parse)

class TrueExpr : public QueryExpr {
 public:
  bool evaluate(w_query_ctx*, const FileResult*) override {
    return true;
  }

  static std::unique_ptr<QueryExpr> parse(w_query*, const json_ref&) {
    return watchman::make_unique<TrueExpr>();
  }
};

W_TERM_PARSER("true", TrueExpr::parse)

class FalseExpr : public QueryExpr {
 public:
  bool evaluate(w_query_ctx*, const FileResult*) override {
    return false;
  }

  static std::unique_ptr<QueryExpr> parse(w_query*, const json_ref&) {
    return watchman::make_unique<FalseExpr>();
  }
};

W_TERM_PARSER("false", FalseExpr::parse)

class ListExpr : public QueryExpr {
  bool allof;
  std::vector<std::unique_ptr<QueryExpr>> exprs;

 public:
  ListExpr(bool isAll, std::vector<std::unique_ptr<QueryExpr>> exprs)
      : allof(isAll), exprs(std::move(exprs)) {}

  bool evaluate(w_query_ctx* ctx, const FileResult* file) override {
    for (auto& expr : exprs) {
      bool res = expr->evaluate(ctx, file);

      if (!res && allof) {
        return false;
      }

      if (res && !allof) {
        return true;
      }
    }
    return allof;
  }

  static std::unique_ptr<QueryExpr>
  parse(w_query* query, const json_ref& term, bool allof) {
    std::vector<std::unique_ptr<QueryExpr>> list;

    /* don't allow "allof" on its own */
    if (!json_is_array(term) || json_array_size(term) < 2) {
      if (allof) {
        throw QueryParseError("must use [\"allof\", expr...]");
      }
      throw QueryParseError("must use [\"anyof\", expr...]");
    }

    auto n = json_array_size(term) - 1;
    list.reserve(n);

    for (size_t i = 0; i < n; i++) {
      const auto& exp = term.at(i + 1);

      auto parsed = w_query_expr_parse(query, exp);
      list.emplace_back(std::move(parsed));
    }

    return watchman::make_unique<ListExpr>(allof, std::move(list));
  }

  static std::unique_ptr<QueryExpr> parseAllOf(
      w_query* query,
      const json_ref& term) {
    return parse(query, term, true);
  }
  static std::unique_ptr<QueryExpr> parseAnyOf(
      w_query* query,
      const json_ref& term) {
    return parse(query, term, false);
  }
};

W_TERM_PARSER("anyof", ListExpr::parseAnyOf)
W_TERM_PARSER("allof", ListExpr::parseAllOf)

/* vim:ts=2:sw=2:et:
 */