diff options
author | David Neto <dneto@google.com> | 2017-05-03 12:51:34 +0200 |
---|---|---|
committer | David Neto <dneto@google.com> | 2017-05-03 12:51:34 +0200 |
commit | 766bd82f05211f7d9cc59b678eb6188151a044ec (patch) | |
tree | 4e7b8eab1144a03e0a5c8794892469e631b68301 | |
parent | 42f27650258c5817f22e66355b93cd7908190ea8 (diff) | |
download | effcee-766bd82f05211f7d9cc59b678eb6188151a044ec.tar.gz |
Undefined variable never matches
-rw-r--r-- | effcee/check.cc | 10 | ||||
-rw-r--r-- | effcee/check.h | 4 | ||||
-rw-r--r-- | effcee/match_test.cc | 11 |
3 files changed, 23 insertions, 2 deletions
diff --git a/effcee/check.cc b/effcee/check.cc index d927994..28d9227 100644 --- a/effcee/check.cc +++ b/effcee/check.cc @@ -76,6 +76,11 @@ Check::Check(Type type, StringPiece param) : type_(type), param_(param) { parts_.push_back(make_unique<Check::Part>(Part::Type::Fixed, param)); } +bool Check::Part::MightMatch(const VarMapping& vars) const { + return type_ != Type::VarUse || + vars.find(VarUseName().as_string()) != vars.end(); +} + std::string Check::Part::Regex(const VarMapping& vars) const { switch (type_) { case Type::Fixed: @@ -90,7 +95,7 @@ std::string Check::Part::Regex(const VarMapping& vars) const { // Return the escaped form of the current value of the variable. return RE2::QuoteMeta((*where).second); } else { - // The variable is not yet set. + // The variable is not yet set. Should not get here. return ""; } } @@ -101,6 +106,9 @@ std::string Check::Part::Regex(const VarMapping& vars) const { bool Check::Matches(StringPiece* input, StringPiece* captured, VarMapping* vars) const { if (parts_.empty()) return false; + for (auto& part : parts_) { + if (!part->MightMatch(*vars)) return false; + } std::unordered_map<int, std::string> var_def_indices; diff --git a/effcee/check.h b/effcee/check.h index fec0d80..005d00c 100644 --- a/effcee/check.h +++ b/effcee/check.h @@ -74,6 +74,10 @@ class Check { expression_(expr), num_capturing_groups_(CountCapturingGroups()) {} + // Returns true if this part might match a target string. The only case where + // this is false is for a VarUse part where the variable is not yet defined. + bool MightMatch(const VarMapping& vars) const; + // Returns a regular expression to match this part, given a mapping of // variable names to values. If this part is a fixed string or variable use // then quoting has been applied. diff --git a/effcee/match_test.cc b/effcee/match_test.cc index 1824911..d1d0944 100644 --- a/effcee/match_test.cc +++ b/effcee/match_test.cc @@ -741,7 +741,7 @@ Begin } -// TODO: Statefulness: variable definitions and uses +// Statefulness: variable definitions and uses TEST(Match, VarDefFollowedByUse) { const auto result = @@ -749,4 +749,13 @@ TEST(Match, VarDefFollowedByUse) { EXPECT_TRUE(result) << result.message(); } +TEST(Match, UndefinedVarNeverMatches) { + const auto result = + Match("Hello HeXllo", "CHECK: He[[X]]llo"); + EXPECT_FALSE(result) << result.message(); +} + + +// TODO: DAG def after use + } // namespace |