Extract whitespace-dependent format equivalence predicate Factor MacroCallCloseToEndLine/')' and MacroIdentifier/MacroIdItem matching into TokensAreWhitespaceDependentFormatEquivalent(), reusing it in LexicallyEquivalent and FormatEquivalent (PR review feedback).
diff --git a/verible/verilog/analysis/verilog-equivalence.cc b/verible/verilog/analysis/verilog-equivalence.cc index 026c197..97c8da2 100644 --- a/verible/verilog/analysis/verilog-equivalence.cc +++ b/verible/verilog/analysis/verilog-equivalence.cc
@@ -89,6 +89,26 @@ return IsUnlexed(verilog_tokentype(token.token_enum())); } +// True when left/right differ only because surrounding whitespace changed +// token classification (e.g. MacroCallCloseToEndLine vs ')', or +// MacroIdentifier vs MacroIdItem with unchanged spelling). +static bool TokensAreWhitespaceDependentFormatEquivalent(const TokenInfo &left, + const TokenInfo &right) { + if ((left.token_enum() == verilog_tokentype::MacroCallCloseToEndLine && + right.text() == ")") || + (right.token_enum() == verilog_tokentype::MacroCallCloseToEndLine && + left.text() == ")")) { + return true; + } + const auto is_line_ending_macro = [](int token_enum) { + return token_enum == verilog_tokentype::MacroIdentifier || + token_enum == verilog_tokentype::MacroIdItem; + }; + return is_line_ending_macro(left.token_enum()) && + is_line_ending_macro(right.token_enum()) && + left.text() == right.text(); +} + DiffStatus VerilogLexicallyEquivalent( std::string_view left, std::string_view right, const std::function<bool(const verible::TokenInfo &)> &remove_predicate, @@ -170,18 +190,8 @@ // Some token enums differ only by surrounding whitespace (e.g. whether a // macro or ')' ends a line). Treat those pairs as matching enums when the // spelling is unchanged so FormatEquivalent tolerates re-wrapping. - const bool whitespace_dependent_enum_match = - ((l->token_enum() == verilog_tokentype::MacroCallCloseToEndLine && - r->text() == ")") || - (r->token_enum() == verilog_tokentype::MacroCallCloseToEndLine && - l->text() == ")") || - ((l->token_enum() == verilog_tokentype::MacroIdentifier || - l->token_enum() == verilog_tokentype::MacroIdItem) && - (r->token_enum() == verilog_tokentype::MacroIdentifier || - r->token_enum() == verilog_tokentype::MacroIdItem) && - l->text() == r->text())); if (l->token_enum() != r->token_enum() && - !whitespace_dependent_enum_match) { + !TokensAreWhitespaceDependentFormatEquivalent(*l, *r)) { if (errstream != nullptr) { *errstream << "Mismatched token enums. got: "; token_printer(*l, *errstream); @@ -260,22 +270,7 @@ return IsWhitespace(verilog_tokentype(t.token_enum())); }, [=](const TokenInfo &l, const TokenInfo &r) { - // MacroCallCloseToEndLine should be considered equivalent to ')', as - // they are whitespace dependant - if (((r.token_enum() == verilog_tokentype::MacroCallCloseToEndLine) && - (l.text() == ")")) || - ((l.token_enum() == verilog_tokentype::MacroCallCloseToEndLine) && - (r.text() == ")"))) { - return true; - } - // MacroIdentifier vs MacroIdItem depends only on whether the macro - // ends the line (see POST_MACRO_ID in verilog.lex). Spelling-equal - // macros are format-equivalent across that reclassification. - if ((l.token_enum() == verilog_tokentype::MacroIdentifier || - l.token_enum() == verilog_tokentype::MacroIdItem) && - (r.token_enum() == verilog_tokentype::MacroIdentifier || - r.token_enum() == verilog_tokentype::MacroIdItem) && - l.text() == r.text()) { + if (TokensAreWhitespaceDependentFormatEquivalent(l, r)) { return true; } return l.EquivalentWithoutLocation(r);