From aa2aff78e082f14e4bc418f68b27817f90e3f07a Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Wed, 21 Feb 2018 22:16:26 +0000 Subject: [formcalc] Cleanup if expression parsing. This CL simplifies the if expression parsing. The elseif construct has been split into its own list of IfExpressions and no longer gets stuffed into the elseExpression. A loop was added into the output methods for the elseif expressions, which also means we can go from having: if () { } else { if () { } else { } } to if () { } else if () { } else { } Which is a bit nicer. Change-Id: I6edf75215500d6a32a8d7218d477b6960f03de51 Reviewed-on: https://pdfium-review.googlesource.com/27571 Reviewed-by: Ryan Harrison Commit-Queue: dsinclair --- xfa/fxfa/fm2js/cxfa_fmexpression.cpp | 28 +++++----- xfa/fxfa/fm2js/cxfa_fmexpression.h | 9 ++-- xfa/fxfa/fm2js/cxfa_fmparser.cpp | 89 +++++++++++-------------------- xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp | 7 +-- 4 files changed, 55 insertions(+), 78 deletions(-) diff --git a/xfa/fxfa/fm2js/cxfa_fmexpression.cpp b/xfa/fxfa/fm2js/cxfa_fmexpression.cpp index a4dee6353b..db93a38e50 100644 --- a/xfa/fxfa/fm2js/cxfa_fmexpression.cpp +++ b/xfa/fxfa/fm2js/cxfa_fmexpression.cpp @@ -220,11 +220,15 @@ bool CXFA_FMDoExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) { CXFA_FMIfExpression::CXFA_FMIfExpression( std::unique_ptr pExpression, std::unique_ptr pIfExpression, + std::vector> pElseIfExpressions, std::unique_ptr pElseExpression) : CXFA_FMExpression(), m_pExpression(std::move(pExpression)), m_pIfExpression(std::move(pIfExpression)), - m_pElseExpression(std::move(pElseExpression)) {} + m_pElseIfExpressions(std::move(pElseIfExpressions)), + m_pElseExpression(std::move(pElseExpression)) { + ASSERT(m_pExpression); +} CXFA_FMIfExpression::~CXFA_FMIfExpression() = default; @@ -236,15 +240,10 @@ bool CXFA_FMIfExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) { if (type == ReturnType::kImplied) js << L"pfm_ret = 0;\n"; - js << L"if ("; - if (m_pExpression) { - js << L"pfm_rt.get_val("; - if (!m_pExpression->ToJavaScript(js, ReturnType::kInfered)) - return false; - - js << L")"; - } - js << L")\n"; + js << L"if (pfm_rt.get_val("; + if (!m_pExpression->ToJavaScript(js, ReturnType::kInfered)) + return false; + js << L"))\n"; if (CXFA_IsTooBig(js)) return false; @@ -256,11 +255,16 @@ bool CXFA_FMIfExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) { return false; } + for (auto& expr : m_pElseIfExpressions) { + js << L"else "; + if (!expr->ToJavaScript(js, ReturnType::kInfered)) + return false; + } + if (m_pElseExpression) { - js << L"else\n{\n"; + js << L"else "; if (!m_pElseExpression->ToJavaScript(js, type)) return false; - js << L"}\n"; } return !CXFA_IsTooBig(js); } diff --git a/xfa/fxfa/fm2js/cxfa_fmexpression.h b/xfa/fxfa/fm2js/cxfa_fmexpression.h index 88f2d6e4ed..5024432df9 100644 --- a/xfa/fxfa/fm2js/cxfa_fmexpression.h +++ b/xfa/fxfa/fm2js/cxfa_fmexpression.h @@ -91,9 +91,11 @@ class CXFA_FMDoExpression : public CXFA_FMExpression { class CXFA_FMIfExpression : public CXFA_FMExpression { public: - CXFA_FMIfExpression(std::unique_ptr pExpression, - std::unique_ptr pIfExpression, - std::unique_ptr pElseExpression); + CXFA_FMIfExpression( + std::unique_ptr pExpression, + std::unique_ptr pIfExpression, + std::vector> pElseIfExpressions, + std::unique_ptr pElseExpression); ~CXFA_FMIfExpression() override; bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override; @@ -101,6 +103,7 @@ class CXFA_FMIfExpression : public CXFA_FMExpression { private: std::unique_ptr m_pExpression; std::unique_ptr m_pIfExpression; + std::vector> m_pElseIfExpressions; std::unique_ptr m_pElseExpression; }; diff --git a/xfa/fxfa/fm2js/cxfa_fmparser.cpp b/xfa/fxfa/fm2js/cxfa_fmparser.cpp index ccd107bb0b..9beda2c564 100644 --- a/xfa/fxfa/fm2js/cxfa_fmparser.cpp +++ b/xfa/fxfa/fm2js/cxfa_fmparser.cpp @@ -943,73 +943,46 @@ std::unique_ptr CXFA_FMParser::ParseIfExpression() { if (HasError() || !IncrementParseDepthAndCheck()) return nullptr; - // This should be CheckThenNext(TOKif) but we come in here for elseif as well. - if (!NextToken()) + if (!CheckThenNext(TOKif)) return nullptr; - std::unique_ptr pExpression = ParseParenExpression(); - if (m_token.m_type != TOKthen) { - m_error = true; - return nullptr; - } - if (!NextToken()) + std::unique_ptr pCondition = ParseParenExpression(); + if (!CheckThenNext(TOKthen)) return nullptr; - auto exprs = ParseExpressionList(); - if (exprs.empty()) { - m_error = true; - return nullptr; - } - if (m_token.m_type != TOKelseif && m_token.m_type != TOKelse && - m_token.m_type != TOKendif) { - m_error = true; - return nullptr; - } - auto pIfExpression = - pdfium::MakeUnique(std::move(exprs)); + auto pIfExpressions = + pdfium::MakeUnique(ParseExpressionList()); - std::unique_ptr pElseExpression; - switch (m_token.m_type) { - case TOKeof: - case TOKendif: - if (!CheckThenNext(TOKendif)) - return nullptr; - break; - case TOKif: - pElseExpression = ParseIfExpression(); - if (!pElseExpression || !CheckThenNext(TOKendif)) { - m_error = true; - return nullptr; - } - break; - case TOKelseif: - pElseExpression = ParseIfExpression(); - if (!pElseExpression) { - m_error = true; - return nullptr; - } - break; - case TOKelse: { - if (!NextToken()) - return nullptr; + std::vector> pElseIfExpressions; + while (m_token.m_type == TOKelseif) { + if (!NextToken()) + return nullptr; - auto else_exprs = ParseExpressionList(); - if (else_exprs.empty() || !CheckThenNext(TOKendif)) { - m_error = true; - return nullptr; - } + auto elseIfCondition = ParseParenExpression(); + if (!CheckThenNext(TOKthen)) + return nullptr; - pElseExpression = - pdfium::MakeUnique(std::move(else_exprs)); - break; - } - default: - m_error = true; + auto elseIfExprs = ParseExpressionList(); + pElseIfExpressions.push_back(pdfium::MakeUnique( + std::move(elseIfCondition), + pdfium::MakeUnique(std::move(elseIfExprs)), + std::vector>(), nullptr)); + } + + std::unique_ptr pElseExpression; + if (m_token.m_type == TOKelse) { + if (!NextToken()) return nullptr; + + pElseExpression = + pdfium::MakeUnique(ParseExpressionList()); } - return pdfium::MakeUnique(std::move(pExpression), - std::move(pIfExpression), - std::move(pElseExpression)); + if (!CheckThenNext(TOKendif)) + return nullptr; + + return pdfium::MakeUnique( + std::move(pCondition), std::move(pIfExpressions), + std::move(pElseIfExpressions), std::move(pElseExpression)); } // While := 'while' '(' SimpleExpression ')' 'do' ExpressionList 'endwhile' diff --git a/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp b/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp index 53ad0ee02b..e939cd954f 100644 --- a/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp +++ b/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp @@ -92,8 +92,7 @@ TEST(CXFA_FMParserTest, Parse) { L"pfm_rt.dot_acc(border, \"border\", \"fill\", 0, 0), \"\", " L"\"color\", 0, 0), \"\", \"value\", 0, 0), \"255,64,64\");\n" L"}\n" - L"}\nelse\n{\n" - L"if (pfm_rt.get_val(pfm_rt.neq_op(this, pfm_rt.neg_op(2))))\n" + L"}\nelse if (pfm_rt.get_val(pfm_rt.neq_op(this, pfm_rt.neg_op(2))))\n" L"{\n" L"if (pfm_rt.is_obj(pfm_rt.dot_acc(pfm_rt.dot_acc(pfm_rt.dot_acc(border, " L"\"border\", \"fill\", 0, 0), \"\", \"color\", 0, 0), \"\", \"value\", " @@ -104,7 +103,7 @@ TEST(CXFA_FMParserTest, Parse) { L"0, 0), \"128,128,128\");\n" L"}\n" L"}\n" - L"else\n{\n{\n" + L"else {\n" L"if (pfm_rt.is_obj(pfm_rt.dot_acc(pfm_rt.dot_acc(pfm_rt.dot_acc(" L"border, \"border\", \"fill\", 0, 0), \"\", \"color\", 0, 0), \"\", " L"\"value\", 0, 0)))\n{\n" @@ -113,8 +112,6 @@ TEST(CXFA_FMParserTest, Parse) { L"\"color\", 0, 0), \"\", \"value\", 0, 0), \"20,170,13\");\n" L"}\n" L"}\n" - L"}\n" - L"}\n" L"pfm_ret = this;\n" L"return pfm_rt.get_val(pfm_ret);\n" L"}\n).call(this);\n"; -- cgit v1.2.3