Cleanup FormCalc inheritance

This CL cleans up the FormCalc inheritance. The binary and unary items
all share ToJavaScript methods now.

Change-Id: I7bf0978449395fa2eb90b954cf2118d7aa3f71c6
Reviewed-on: https://pdfium-review.googlesource.com/27290
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/xfa/fxfa/fm2js/cxfa_fmexpression.h b/xfa/fxfa/fm2js/cxfa_fmexpression.h
index 5140ed3..28f82aa 100644
--- a/xfa/fxfa/fm2js/cxfa_fmexpression.h
+++ b/xfa/fxfa/fm2js/cxfa_fmexpression.h
@@ -44,7 +44,6 @@
 
 class CXFA_FMFunctionDefinition : public CXFA_FMExpression {
  public:
-  // Takes ownership of |arguments| and |expressions|.
   CXFA_FMFunctionDefinition(
       uint32_t line,
       bool isGlobal,
diff --git a/xfa/fxfa/fm2js/cxfa_fmparser.cpp b/xfa/fxfa/fm2js/cxfa_fmparser.cpp
index 948d9eb..d023159 100644
--- a/xfa/fxfa/fm2js/cxfa_fmparser.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmparser.cpp
@@ -365,7 +365,7 @@
         if (!e2)
           return nullptr;
 
-        e1 = pdfium::MakeUnique<CXFA_FMEqualityExpression>(
+        e1 = pdfium::MakeUnique<CXFA_FMEqualExpression>(
             line, TOKeq, std::move(e1), std::move(e2));
         continue;
       case TOKne:
@@ -377,7 +377,7 @@
         if (!e2)
           return nullptr;
 
-        e1 = pdfium::MakeUnique<CXFA_FMEqualityExpression>(
+        e1 = pdfium::MakeUnique<CXFA_FMNotEqualExpression>(
             line, TOKne, std::move(e1), std::move(e2));
         continue;
       default:
@@ -411,8 +411,8 @@
         if (!e2)
           return nullptr;
 
-        e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
-            line, TOKlt, std::move(e1), std::move(e2));
+        e1 = pdfium::MakeUnique<CXFA_FMLtExpression>(line, TOKlt, std::move(e1),
+                                                     std::move(e2));
         continue;
       case TOKgt:
       case TOKksgt:
@@ -423,8 +423,8 @@
         if (!e2)
           return nullptr;
 
-        e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
-            line, TOKgt, std::move(e1), std::move(e2));
+        e1 = pdfium::MakeUnique<CXFA_FMGtExpression>(line, TOKgt, std::move(e1),
+                                                     std::move(e2));
         continue;
       case TOKle:
       case TOKksle:
@@ -435,8 +435,8 @@
         if (!e2)
           return nullptr;
 
-        e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
-            line, TOKle, std::move(e1), std::move(e2));
+        e1 = pdfium::MakeUnique<CXFA_FMLeExpression>(line, TOKle, std::move(e1),
+                                                     std::move(e2));
         continue;
       case TOKge:
       case TOKksge:
@@ -447,8 +447,8 @@
         if (!e2)
           return nullptr;
 
-        e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
-            line, TOKge, std::move(e1), std::move(e2));
+        e1 = pdfium::MakeUnique<CXFA_FMGeExpression>(line, TOKge, std::move(e1),
+                                                     std::move(e2));
         continue;
       default:
         break;
@@ -480,7 +480,7 @@
         if (!e2)
           return nullptr;
 
-        e1 = pdfium::MakeUnique<CXFA_FMAdditiveExpression>(
+        e1 = pdfium::MakeUnique<CXFA_FMPlusExpression>(
             line, TOKplus, std::move(e1), std::move(e2));
         continue;
       case TOKminus:
@@ -491,7 +491,7 @@
         if (!e2)
           return nullptr;
 
-        e1 = pdfium::MakeUnique<CXFA_FMAdditiveExpression>(
+        e1 = pdfium::MakeUnique<CXFA_FMMinusExpression>(
             line, TOKminus, std::move(e1), std::move(e2));
         continue;
       default:
@@ -524,7 +524,7 @@
         if (!e2)
           return nullptr;
 
-        e1 = pdfium::MakeUnique<CXFA_FMMultiplicativeExpression>(
+        e1 = pdfium::MakeUnique<CXFA_FMMulExpression>(
             line, TOKmul, std::move(e1), std::move(e2));
         continue;
       case TOKdiv:
@@ -535,7 +535,7 @@
         if (!e2)
           return nullptr;
 
-        e1 = pdfium::MakeUnique<CXFA_FMMultiplicativeExpression>(
+        e1 = pdfium::MakeUnique<CXFA_FMDivExpression>(
             line, TOKdiv, std::move(e1), std::move(e2));
         continue;
       default:
diff --git a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp
index ec61511..36adfb1 100644
--- a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp
@@ -184,15 +184,7 @@
   return !CXFA_IsTooBig(js);
 }
 
-CXFA_FMUnaryExpression::CXFA_FMUnaryExpression(
-    uint32_t line,
-    XFA_FM_TOKEN op,
-    std::unique_ptr<CXFA_FMSimpleExpression> pExp)
-    : CXFA_FMSimpleExpression(line, op), m_pExp(std::move(pExp)) {}
-
-CXFA_FMUnaryExpression::~CXFA_FMUnaryExpression() = default;
-
-CXFA_FMBinExpression::CXFA_FMBinExpression(
+CXFA_FMAssignExpression::CXFA_FMAssignExpression(
     uint32_t line,
     XFA_FM_TOKEN op,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
@@ -201,14 +193,7 @@
       m_pExp1(std::move(pExp1)),
       m_pExp2(std::move(pExp2)) {}
 
-CXFA_FMBinExpression::~CXFA_FMBinExpression() = default;
-
-CXFA_FMAssignExpression::CXFA_FMAssignExpression(
-    uint32_t line,
-    XFA_FM_TOKEN op,
-    std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
-    std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
-    : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {}
+CXFA_FMAssignExpression::~CXFA_FMAssignExpression() = default;
 
 bool CXFA_FMAssignExpression::ToJavaScript(CFX_WideTextBuf& js,
                                            ReturnType type) {
@@ -243,15 +228,20 @@
   return !CXFA_IsTooBig(js);
 }
 
-CXFA_FMLogicalOrExpression::CXFA_FMLogicalOrExpression(
+CXFA_FMBinExpression::CXFA_FMBinExpression(
+    const WideString& opName,
     uint32_t line,
     XFA_FM_TOKEN op,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
-    : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {}
+    : CXFA_FMSimpleExpression(line, op),
+      m_OpName(opName),
+      m_pExp1(std::move(pExp1)),
+      m_pExp2(std::move(pExp2)) {}
 
-bool CXFA_FMLogicalOrExpression::ToJavaScript(CFX_WideTextBuf& js,
-                                              ReturnType type) {
+CXFA_FMBinExpression::~CXFA_FMBinExpression() = default;
+
+bool CXFA_FMBinExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) {
   CXFA_FMToJavaScriptDepth depthManager;
   if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
     return false;
@@ -264,255 +254,189 @@
   if (!m_pExp2->ToJavaScript(exp2_txt, ReturnType::kInfered))
     return false;
 
-  js << L"pfm_rt.log_or_op(" << exp1_txt << L", " << exp2_txt << L")";
+  js << L"pfm_rt." << m_OpName << L"(" << exp1_txt << L", " << exp2_txt << L")";
   return !CXFA_IsTooBig(js);
 }
 
+CXFA_FMLogicalOrExpression::CXFA_FMLogicalOrExpression(
+    uint32_t line,
+    XFA_FM_TOKEN op,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
+    : CXFA_FMBinExpression(L"log_or_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
+
 CXFA_FMLogicalAndExpression::CXFA_FMLogicalAndExpression(
     uint32_t line,
     XFA_FM_TOKEN op,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
-    : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {}
+    : CXFA_FMBinExpression(L"log_and_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
 
-bool CXFA_FMLogicalAndExpression::ToJavaScript(CFX_WideTextBuf& js,
-                                               ReturnType type) {
-  CXFA_FMToJavaScriptDepth depthManager;
-  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
-    return false;
-
-  CFX_WideTextBuf exp1_txt;
-  if (!m_pExp1->ToJavaScript(exp1_txt, ReturnType::kInfered))
-    return false;
-
-  CFX_WideTextBuf exp2_txt;
-  if (!m_pExp2->ToJavaScript(exp2_txt, ReturnType::kInfered))
-    return false;
-
-  js << L"pfm_rt.log_and_op(" << exp1_txt << L", " << exp2_txt << L")";
-  return !CXFA_IsTooBig(js);
-}
-
-CXFA_FMEqualityExpression::CXFA_FMEqualityExpression(
+CXFA_FMEqualExpression::CXFA_FMEqualExpression(
     uint32_t line,
     XFA_FM_TOKEN op,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
-    : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {}
+    : CXFA_FMBinExpression(L"eq_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
 
-bool CXFA_FMEqualityExpression::ToJavaScript(CFX_WideTextBuf& js,
-                                             ReturnType type) {
-  CXFA_FMToJavaScriptDepth depthManager;
-  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
-    return false;
-
-  switch (m_op) {
-    case TOKeq:
-    case TOKkseq:
-      js << L"pfm_rt.eq_op";
-      break;
-    case TOKne:
-    case TOKksne:
-      js << L"pfm_rt.neq_op";
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-
-  CFX_WideTextBuf exp1_txt;
-  if (!m_pExp1->ToJavaScript(exp1_txt, ReturnType::kInfered))
-    return false;
-
-  CFX_WideTextBuf exp2_txt;
-  if (!m_pExp2->ToJavaScript(exp2_txt, ReturnType::kInfered))
-    return false;
-
-  js << L"(" << exp1_txt << L", " << exp2_txt << L")";
-  return !CXFA_IsTooBig(js);
-}
-
-CXFA_FMRelationalExpression::CXFA_FMRelationalExpression(
+CXFA_FMNotEqualExpression::CXFA_FMNotEqualExpression(
     uint32_t line,
     XFA_FM_TOKEN op,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
-    : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {}
+    : CXFA_FMBinExpression(L"neq_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
 
-bool CXFA_FMRelationalExpression::ToJavaScript(CFX_WideTextBuf& js,
-                                               ReturnType type) {
-  CXFA_FMToJavaScriptDepth depthManager;
-  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
-    return false;
-
-  switch (m_op) {
-    case TOKlt:
-    case TOKkslt:
-      js << L"pfm_rt.lt_op";
-      break;
-    case TOKgt:
-    case TOKksgt:
-      js << L"pfm_rt.gt_op";
-      break;
-    case TOKle:
-    case TOKksle:
-      js << L"pfm_rt.le_op";
-      break;
-    case TOKge:
-    case TOKksge:
-      js << L"pfm_rt.ge_op";
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-
-  CFX_WideTextBuf exp1_txt;
-  if (!m_pExp1->ToJavaScript(exp1_txt, ReturnType::kInfered))
-    return false;
-
-  CFX_WideTextBuf exp2_txt;
-  if (!m_pExp2->ToJavaScript(exp2_txt, ReturnType::kInfered))
-    return false;
-
-  js << L"(" << exp1_txt << L", " << exp2_txt << L")";
-  return !CXFA_IsTooBig(js);
-}
-
-CXFA_FMAdditiveExpression::CXFA_FMAdditiveExpression(
+CXFA_FMGtExpression::CXFA_FMGtExpression(
     uint32_t line,
     XFA_FM_TOKEN op,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
-    : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {}
+    : CXFA_FMBinExpression(L"gt_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
 
-bool CXFA_FMAdditiveExpression::ToJavaScript(CFX_WideTextBuf& js,
-                                             ReturnType type) {
-  CXFA_FMToJavaScriptDepth depthManager;
-  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
-    return false;
-
-  switch (m_op) {
-    case TOKplus:
-      js << L"pfm_rt.plus_op";
-      break;
-    case TOKminus:
-      js << L"pfm_rt.minus_op";
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-
-  CFX_WideTextBuf exp1_txt;
-  if (!m_pExp1->ToJavaScript(exp1_txt, ReturnType::kInfered))
-    return false;
-
-  CFX_WideTextBuf exp2_txt;
-  if (!m_pExp2->ToJavaScript(exp2_txt, ReturnType::kInfered))
-    return false;
-
-  js << L"(" << exp1_txt << L", " << exp2_txt << L")";
-  return !CXFA_IsTooBig(js);
-}
-
-CXFA_FMMultiplicativeExpression::CXFA_FMMultiplicativeExpression(
+CXFA_FMGeExpression::CXFA_FMGeExpression(
     uint32_t line,
     XFA_FM_TOKEN op,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
-    : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {}
+    : CXFA_FMBinExpression(L"ge_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
 
-bool CXFA_FMMultiplicativeExpression::ToJavaScript(CFX_WideTextBuf& js,
-                                                   ReturnType type) {
+CXFA_FMLtExpression::CXFA_FMLtExpression(
+    uint32_t line,
+    XFA_FM_TOKEN op,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
+    : CXFA_FMBinExpression(L"lt_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
+
+CXFA_FMLeExpression::CXFA_FMLeExpression(
+    uint32_t line,
+    XFA_FM_TOKEN op,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
+    : CXFA_FMBinExpression(L"le_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
+
+CXFA_FMPlusExpression::CXFA_FMPlusExpression(
+    uint32_t line,
+    XFA_FM_TOKEN op,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
+    : CXFA_FMBinExpression(L"plus_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
+
+CXFA_FMMinusExpression::CXFA_FMMinusExpression(
+    uint32_t line,
+    XFA_FM_TOKEN op,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
+    : CXFA_FMBinExpression(L"minus_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
+
+CXFA_FMMulExpression::CXFA_FMMulExpression(
+    uint32_t line,
+    XFA_FM_TOKEN op,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
+    : CXFA_FMBinExpression(L"mul_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
+
+CXFA_FMDivExpression::CXFA_FMDivExpression(
+    uint32_t line,
+    XFA_FM_TOKEN op,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
+    : CXFA_FMBinExpression(L"div_op",
+                           line,
+                           op,
+                           std::move(pExp1),
+                           std::move(pExp2)) {}
+
+CXFA_FMUnaryExpression::CXFA_FMUnaryExpression(
+    const WideString& opName,
+    uint32_t line,
+    XFA_FM_TOKEN op,
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp)
+    : CXFA_FMSimpleExpression(line, op),
+      m_OpName(opName),
+      m_pExp(std::move(pExp)) {}
+
+CXFA_FMUnaryExpression::~CXFA_FMUnaryExpression() = default;
+
+bool CXFA_FMUnaryExpression::ToJavaScript(CFX_WideTextBuf& js,
+                                          ReturnType type) {
   CXFA_FMToJavaScriptDepth depthManager;
   if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
     return false;
 
-  switch (m_op) {
-    case TOKmul:
-      js << L"pfm_rt.mul_op";
-      break;
-    case TOKdiv:
-      js << L"pfm_rt.div_op";
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-
-  CFX_WideTextBuf exp1_txt;
-  if (!m_pExp1->ToJavaScript(exp1_txt, ReturnType::kInfered))
+  CFX_WideTextBuf exp_txt;
+  if (!m_pExp->ToJavaScript(exp_txt, ReturnType::kInfered))
     return false;
 
-  CFX_WideTextBuf exp2_txt;
-  if (!m_pExp2->ToJavaScript(exp2_txt, ReturnType::kInfered))
-    return false;
-
-  js << L"(" << exp1_txt << L", " << exp2_txt << L")";
+  js << L"pfm_rt." << m_OpName.c_str() << L"(" << exp_txt << L")";
   return !CXFA_IsTooBig(js);
 }
 
 CXFA_FMPosExpression::CXFA_FMPosExpression(
     uint32_t line,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp)
-    : CXFA_FMUnaryExpression(line, TOKplus, std::move(pExp)) {}
-
-bool CXFA_FMPosExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) {
-  CXFA_FMToJavaScriptDepth depthManager;
-  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
-    return false;
-
-  CFX_WideTextBuf exp_txt;
-  if (!m_pExp->ToJavaScript(exp_txt, ReturnType::kInfered))
-    return false;
-
-  js << L"pfm_rt.pos_op(" << exp_txt << L")";
-  return !CXFA_IsTooBig(js);
-}
+    : CXFA_FMUnaryExpression(L"pos_op", line, TOKplus, std::move(pExp)) {}
 
 CXFA_FMNegExpression::CXFA_FMNegExpression(
     uint32_t line,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp)
-    : CXFA_FMUnaryExpression(line, TOKminus, std::move(pExp)) {}
-
-bool CXFA_FMNegExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) {
-  CXFA_FMToJavaScriptDepth depthManager;
-  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
-    return false;
-
-  CFX_WideTextBuf exp_txt;
-  if (!m_pExp->ToJavaScript(exp_txt, ReturnType::kInfered))
-    return false;
-
-  js << L"pfm_rt.neg_op(" << exp_txt << L")";
-  return !CXFA_IsTooBig(js);
-}
+    : CXFA_FMUnaryExpression(L"neg_op", line, TOKminus, std::move(pExp)) {}
 
 CXFA_FMNotExpression::CXFA_FMNotExpression(
     uint32_t line,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp)
-    : CXFA_FMUnaryExpression(line, TOKksnot, std::move(pExp)) {}
-
-bool CXFA_FMNotExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) {
-  CXFA_FMToJavaScriptDepth depthManager;
-  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
-    return false;
-
-  CFX_WideTextBuf exp_txt;
-  if (!m_pExp->ToJavaScript(exp_txt, ReturnType::kInfered))
-    return false;
-
-  js << L"pfm_rt.log_not_op(" << exp_txt << L")";
-  return !CXFA_IsTooBig(js);
-}
+    : CXFA_FMUnaryExpression(L"log_not_op", line, TOKksnot, std::move(pExp)) {}
 
 CXFA_FMCallExpression::CXFA_FMCallExpression(
     uint32_t line,
     std::unique_ptr<CXFA_FMSimpleExpression> pExp,
     std::vector<std::unique_ptr<CXFA_FMSimpleExpression>>&& pArguments,
     bool bIsSomMethod)
-    : CXFA_FMUnaryExpression(line, TOKcall, std::move(pExp)),
+    : CXFA_FMSimpleExpression(line, TOKcall),
+      m_pExp(std::move(pExp)),
       m_bIsSomMethod(bIsSomMethod),
       m_Arguments(std::move(pArguments)) {}
 
@@ -650,11 +574,10 @@
     XFA_FM_TOKEN op,
     WideStringView wsIdentifier,
     std::unique_ptr<CXFA_FMSimpleExpression> pIndexExp)
-    : CXFA_FMBinExpression(line,
-                           op,
-                           std::move(pAccessor),
-                           std::move(pIndexExp)),
-      m_wsIdentifier(wsIdentifier) {}
+    : CXFA_FMSimpleExpression(line, op),
+      m_wsIdentifier(wsIdentifier),
+      m_pExp1(std::move(pAccessor)),
+      m_pExp2(std::move(pIndexExp)) {}
 
 CXFA_FMDotAccessorExpression::~CXFA_FMDotAccessorExpression() {}
 
@@ -702,10 +625,13 @@
     XFA_FM_AccessorIndex accessorIndex,
     std::unique_ptr<CXFA_FMSimpleExpression> pIndexExp,
     bool bIsStarIndex)
-    : CXFA_FMUnaryExpression(line, TOKlbracket, std::move(pIndexExp)),
+    : CXFA_FMSimpleExpression(line, TOKlbracket),
+      m_pExp(std::move(pIndexExp)),
       m_accessorIndex(accessorIndex),
       m_bIsStarIndex(bIsStarIndex) {}
 
+CXFA_FMIndexExpression::~CXFA_FMIndexExpression() = default;
+
 bool CXFA_FMIndexExpression::ToJavaScript(CFX_WideTextBuf& js,
                                           ReturnType type) {
   CXFA_FMToJavaScriptDepth depthManager;
@@ -747,11 +673,10 @@
     XFA_FM_TOKEN op,
     WideStringView wsIdentifier,
     std::unique_ptr<CXFA_FMSimpleExpression> pIndexExp)
-    : CXFA_FMBinExpression(line,
-                           op,
-                           std::move(pAccessor),
-                           std::move(pIndexExp)),
-      m_wsIdentifier(wsIdentifier) {}
+    : CXFA_FMSimpleExpression(line, op),
+      m_wsIdentifier(wsIdentifier),
+      m_pExp1(std::move(pAccessor)),
+      m_pExp2(std::move(pIndexExp)) {}
 
 CXFA_FMDotDotAccessorExpression::~CXFA_FMDotDotAccessorExpression() {}
 
@@ -781,10 +706,11 @@
     uint32_t line,
     std::unique_ptr<CXFA_FMSimpleExpression> pAccessorExp1,
     std::unique_ptr<CXFA_FMSimpleExpression> pCallExp)
-    : CXFA_FMBinExpression(line,
-                           TOKdot,
-                           std::move(pAccessorExp1),
-                           std::move(pCallExp)) {}
+    : CXFA_FMSimpleExpression(line, TOKdot),
+      m_pExp1(std::move(pAccessorExp1)),
+      m_pExp2(std::move(pCallExp)) {}
+
+CXFA_FMMethodCallExpression::~CXFA_FMMethodCallExpression() = default;
 
 bool CXFA_FMMethodCallExpression::ToJavaScript(CFX_WideTextBuf& js,
                                                ReturnType type) {
diff --git a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h
index bc41c74..8aceb97 100644
--- a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h
+++ b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h
@@ -78,43 +78,40 @@
   WideStringView m_wsIdentifier;
 };
 
-class CXFA_FMUnaryExpression : public CXFA_FMSimpleExpression {
+class CXFA_FMAssignExpression : public CXFA_FMSimpleExpression {
  public:
-  ~CXFA_FMUnaryExpression() override;
+  CXFA_FMAssignExpression(uint32_t line,
+                          XFA_FM_TOKEN op,
+                          std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+                          std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+  ~CXFA_FMAssignExpression() override;
 
- protected:
-  CXFA_FMUnaryExpression(uint32_t line,
-                         XFA_FM_TOKEN op,
-                         std::unique_ptr<CXFA_FMSimpleExpression> pExp);
+  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
 
-  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp;
+ private:
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
 };
 
 class CXFA_FMBinExpression : public CXFA_FMSimpleExpression {
  public:
   ~CXFA_FMBinExpression() override;
 
+  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
+
  protected:
-  CXFA_FMBinExpression(uint32_t line,
+  CXFA_FMBinExpression(const WideString& opName,
+                       uint32_t line,
                        XFA_FM_TOKEN op,
                        std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
                        std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
 
+ private:
+  WideString m_OpName;
   std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
   std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
 };
 
-class CXFA_FMAssignExpression : public CXFA_FMBinExpression {
- public:
-  CXFA_FMAssignExpression(uint32_t line,
-                          XFA_FM_TOKEN op,
-                          std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
-                          std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
-  ~CXFA_FMAssignExpression() override {}
-
-  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
-};
-
 class CXFA_FMLogicalOrExpression : public CXFA_FMBinExpression {
  public:
   CXFA_FMLogicalOrExpression(uint32_t line,
@@ -122,8 +119,6 @@
                              std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
                              std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
   ~CXFA_FMLogicalOrExpression() override {}
-
-  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
 };
 
 class CXFA_FMLogicalAndExpression : public CXFA_FMBinExpression {
@@ -133,53 +128,113 @@
                               std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
                               std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
   ~CXFA_FMLogicalAndExpression() override {}
-
-  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
 };
 
-class CXFA_FMEqualityExpression : public CXFA_FMBinExpression {
+class CXFA_FMEqualExpression : public CXFA_FMBinExpression {
  public:
-  CXFA_FMEqualityExpression(uint32_t line,
+  CXFA_FMEqualExpression(uint32_t line,
+                         XFA_FM_TOKEN op,
+                         std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+                         std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+  ~CXFA_FMEqualExpression() override {}
+};
+
+class CXFA_FMNotEqualExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMNotEqualExpression(uint32_t line,
                             XFA_FM_TOKEN op,
                             std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
                             std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
-  ~CXFA_FMEqualityExpression() override {}
-
-  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
+  ~CXFA_FMNotEqualExpression() override {}
 };
 
-class CXFA_FMRelationalExpression : public CXFA_FMBinExpression {
+class CXFA_FMGtExpression : public CXFA_FMBinExpression {
  public:
-  CXFA_FMRelationalExpression(uint32_t line,
-                              XFA_FM_TOKEN op,
-                              std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
-                              std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
-  ~CXFA_FMRelationalExpression() override {}
-
-  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
+  CXFA_FMGtExpression(uint32_t line,
+                      XFA_FM_TOKEN op,
+                      std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+                      std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+  ~CXFA_FMGtExpression() override {}
 };
 
-class CXFA_FMAdditiveExpression : public CXFA_FMBinExpression {
+class CXFA_FMGeExpression : public CXFA_FMBinExpression {
  public:
-  CXFA_FMAdditiveExpression(uint32_t line,
-                            XFA_FM_TOKEN op,
-                            std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
-                            std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
-  ~CXFA_FMAdditiveExpression() override {}
-
-  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
+  CXFA_FMGeExpression(uint32_t line,
+                      XFA_FM_TOKEN op,
+                      std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+                      std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+  ~CXFA_FMGeExpression() override {}
 };
 
-class CXFA_FMMultiplicativeExpression : public CXFA_FMBinExpression {
+class CXFA_FMLtExpression : public CXFA_FMBinExpression {
  public:
-  CXFA_FMMultiplicativeExpression(
-      uint32_t line,
-      XFA_FM_TOKEN op,
-      std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
-      std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
-  ~CXFA_FMMultiplicativeExpression() override {}
+  CXFA_FMLtExpression(uint32_t line,
+                      XFA_FM_TOKEN op,
+                      std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+                      std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+  ~CXFA_FMLtExpression() override {}
+};
+
+class CXFA_FMLeExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMLeExpression(uint32_t line,
+                      XFA_FM_TOKEN op,
+                      std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+                      std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+  ~CXFA_FMLeExpression() override {}
+};
+
+class CXFA_FMPlusExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMPlusExpression(uint32_t line,
+                        XFA_FM_TOKEN op,
+                        std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+                        std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+  ~CXFA_FMPlusExpression() override {}
+};
+
+class CXFA_FMMinusExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMMinusExpression(uint32_t line,
+                         XFA_FM_TOKEN op,
+                         std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+                         std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+  ~CXFA_FMMinusExpression() override {}
+};
+
+class CXFA_FMMulExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMMulExpression(uint32_t line,
+                       XFA_FM_TOKEN op,
+                       std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+                       std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+  ~CXFA_FMMulExpression() override {}
+};
+
+class CXFA_FMDivExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMDivExpression(uint32_t line,
+                       XFA_FM_TOKEN op,
+                       std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+                       std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+  ~CXFA_FMDivExpression() override {}
+};
+
+class CXFA_FMUnaryExpression : public CXFA_FMSimpleExpression {
+ public:
+  ~CXFA_FMUnaryExpression() override;
 
   bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
+
+ protected:
+  CXFA_FMUnaryExpression(const WideString& opName,
+                         uint32_t line,
+                         XFA_FM_TOKEN op,
+                         std::unique_ptr<CXFA_FMSimpleExpression> pExp);
+
+ private:
+  WideString m_OpName;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp;
 };
 
 class CXFA_FMPosExpression : public CXFA_FMUnaryExpression {
@@ -187,8 +242,6 @@
   CXFA_FMPosExpression(uint32_t line,
                        std::unique_ptr<CXFA_FMSimpleExpression> pExp);
   ~CXFA_FMPosExpression() override {}
-
-  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
 };
 
 class CXFA_FMNegExpression : public CXFA_FMUnaryExpression {
@@ -196,8 +249,6 @@
   CXFA_FMNegExpression(uint32_t line,
                        std::unique_ptr<CXFA_FMSimpleExpression> pExp);
   ~CXFA_FMNegExpression() override {}
-
-  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
 };
 
 class CXFA_FMNotExpression : public CXFA_FMUnaryExpression {
@@ -205,11 +256,9 @@
   CXFA_FMNotExpression(uint32_t line,
                        std::unique_ptr<CXFA_FMSimpleExpression> pExp);
   ~CXFA_FMNotExpression() override {}
-
-  bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
 };
 
-class CXFA_FMCallExpression : public CXFA_FMUnaryExpression {
+class CXFA_FMCallExpression : public CXFA_FMSimpleExpression {
  public:
   CXFA_FMCallExpression(
       uint32_t line,
@@ -223,11 +272,12 @@
   bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
 
  private:
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp;
   bool m_bIsSomMethod;
   std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> m_Arguments;
 };
 
-class CXFA_FMDotAccessorExpression : public CXFA_FMBinExpression {
+class CXFA_FMDotAccessorExpression : public CXFA_FMSimpleExpression {
  public:
   CXFA_FMDotAccessorExpression(
       uint32_t line,
@@ -241,24 +291,27 @@
 
  private:
   WideStringView m_wsIdentifier;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
 };
 
-class CXFA_FMIndexExpression : public CXFA_FMUnaryExpression {
+class CXFA_FMIndexExpression : public CXFA_FMSimpleExpression {
  public:
   CXFA_FMIndexExpression(uint32_t line,
                          XFA_FM_AccessorIndex accessorIndex,
                          std::unique_ptr<CXFA_FMSimpleExpression> pIndexExp,
                          bool bIsStarIndex);
-  ~CXFA_FMIndexExpression() override {}
+  ~CXFA_FMIndexExpression() override;
 
   bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
 
  private:
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp;
   XFA_FM_AccessorIndex m_accessorIndex;
   bool m_bIsStarIndex;
 };
 
-class CXFA_FMDotDotAccessorExpression : public CXFA_FMBinExpression {
+class CXFA_FMDotDotAccessorExpression : public CXFA_FMSimpleExpression {
  public:
   CXFA_FMDotDotAccessorExpression(
       uint32_t line,
@@ -272,17 +325,23 @@
 
  private:
   WideStringView m_wsIdentifier;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
 };
 
-class CXFA_FMMethodCallExpression : public CXFA_FMBinExpression {
+class CXFA_FMMethodCallExpression : public CXFA_FMSimpleExpression {
  public:
   CXFA_FMMethodCallExpression(
       uint32_t line,
       std::unique_ptr<CXFA_FMSimpleExpression> pAccessorExp1,
       std::unique_ptr<CXFA_FMSimpleExpression> pCallExp);
-  ~CXFA_FMMethodCallExpression() override {}
+  ~CXFA_FMMethodCallExpression() override;
 
   bool ToJavaScript(CFX_WideTextBuf& javascript, ReturnType type) override;
+
+ private:
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
 };
 
 bool CXFA_IsTooBig(const CFX_WideTextBuf& javascript);