Home | History | Annotate | Download | only in fm2js
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "xfa/fxfa/fm2js/xfa_expression.h"
      8 
      9 #include <utility>
     10 
     11 #include "core/fxcrt/fx_basic.h"
     12 
     13 namespace {
     14 
     15 const FX_WCHAR RUNTIMEBLOCKTEMPARRAY[] =
     16     L"foxit_xfa_formcalc_runtime_block_temp_array";
     17 
     18 const FX_WCHAR RUNTIMEBLOCKTEMPARRAYINDEX[] =
     19     L"foxit_xfa_formcalc_runtime_block_temp_array_index";
     20 
     21 }  // namespace
     22 
     23 CXFA_FMExpression::CXFA_FMExpression(uint32_t line)
     24     : m_type(XFA_FM_EXPTYPE_UNKNOWN), m_line(line) {}
     25 
     26 CXFA_FMExpression::CXFA_FMExpression(uint32_t line, XFA_FM_EXPTYPE type)
     27     : m_type(type), m_line(line) {}
     28 
     29 void CXFA_FMExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
     30 
     31 void CXFA_FMExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {}
     32 
     33 CXFA_FMFunctionDefinition::CXFA_FMFunctionDefinition(
     34     uint32_t line,
     35     bool isGlobal,
     36     const CFX_WideStringC& wsName,
     37     std::vector<CFX_WideStringC>&& arguments,
     38     std::vector<std::unique_ptr<CXFA_FMExpression>>&& expressions)
     39     : CXFA_FMExpression(line, XFA_FM_EXPTYPE_FUNC),
     40       m_wsName(wsName),
     41       m_pArguments(std::move(arguments)),
     42       m_pExpressions(std::move(expressions)),
     43       m_isGlobal(isGlobal) {}
     44 
     45 CXFA_FMFunctionDefinition::~CXFA_FMFunctionDefinition() {}
     46 
     47 void CXFA_FMFunctionDefinition::ToJavaScript(CFX_WideTextBuf& javascript) {
     48   if (m_isGlobal && m_pExpressions.empty()) {
     49     javascript << L"// comments only";
     50     return;
     51   }
     52   if (m_isGlobal) {
     53     javascript << L"(\n";
     54   }
     55   javascript << L"function ";
     56   if (m_wsName.GetAt(0) == L'!') {
     57     CFX_WideString tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1);
     58     javascript << tempName;
     59   } else {
     60     javascript << m_wsName;
     61   }
     62   javascript << L"(";
     63   bool bNeedComma = false;
     64   for (const auto& identifier : m_pArguments) {
     65     if (bNeedComma)
     66       javascript << L", ";
     67     if (identifier.GetAt(0) == L'!') {
     68       CFX_WideString tempIdentifier =
     69           EXCLAMATION_IN_IDENTIFIER + identifier.Mid(1);
     70       javascript << tempIdentifier;
     71     } else {
     72       javascript << identifier;
     73     }
     74     bNeedComma = true;
     75   }
     76   javascript << L")\n{\n";
     77   javascript << L"var ";
     78   javascript << RUNTIMEFUNCTIONRETURNVALUE;
     79   javascript << L" = null;\n";
     80   for (const auto& expr : m_pExpressions) {
     81     if (expr == m_pExpressions.back())
     82       expr->ToImpliedReturnJS(javascript);
     83     else
     84       expr->ToJavaScript(javascript);
     85   }
     86   javascript << L"return ";
     87   if (m_isGlobal) {
     88     javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
     89     javascript << L"(";
     90     javascript << RUNTIMEFUNCTIONRETURNVALUE;
     91     javascript << L")";
     92   } else {
     93     javascript << RUNTIMEFUNCTIONRETURNVALUE;
     94   }
     95   javascript << L";\n}\n";
     96   if (m_isGlobal) {
     97     javascript << L").call(this);\n";
     98   }
     99 }
    100 
    101 void CXFA_FMFunctionDefinition::ToImpliedReturnJS(CFX_WideTextBuf&) {}
    102 
    103 CXFA_FMVarExpression::CXFA_FMVarExpression(
    104     uint32_t line,
    105     const CFX_WideStringC& wsName,
    106     std::unique_ptr<CXFA_FMExpression> pInit)
    107     : CXFA_FMExpression(line, XFA_FM_EXPTYPE_VAR),
    108       m_wsName(wsName),
    109       m_pInit(std::move(pInit)) {}
    110 
    111 CXFA_FMVarExpression::~CXFA_FMVarExpression() {}
    112 
    113 void CXFA_FMVarExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    114   javascript << L"var ";
    115   CFX_WideString tempName(m_wsName);
    116   if (m_wsName.GetAt(0) == L'!') {
    117     tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1);
    118   }
    119   javascript << tempName;
    120   javascript << L" = ";
    121   if (m_pInit) {
    122     m_pInit->ToJavaScript(javascript);
    123     javascript << tempName;
    124     javascript << L" = ";
    125     javascript << XFA_FM_EXPTypeToString(VARFILTER);
    126     javascript << L"(";
    127     javascript << tempName;
    128     javascript << L");\n";
    129   } else {
    130     javascript << L"\"\";\n";
    131   }
    132 }
    133 
    134 void CXFA_FMVarExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
    135   javascript << L"var ";
    136   CFX_WideString tempName(m_wsName);
    137   if (m_wsName.GetAt(0) == L'!') {
    138     tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1);
    139   }
    140   javascript << tempName;
    141   javascript << L" = ";
    142   if (m_pInit) {
    143     m_pInit->ToJavaScript(javascript);
    144     javascript << tempName;
    145     javascript << L" = ";
    146     javascript << XFA_FM_EXPTypeToString(VARFILTER);
    147     javascript << L"(";
    148     javascript << tempName;
    149     javascript << L");\n";
    150   } else {
    151     javascript << L"\"\";\n";
    152   }
    153   javascript << RUNTIMEFUNCTIONRETURNVALUE;
    154   javascript << L" = ";
    155   javascript << tempName;
    156   javascript << L";\n";
    157 }
    158 
    159 CXFA_FMExpExpression::CXFA_FMExpExpression(
    160     uint32_t line,
    161     std::unique_ptr<CXFA_FMSimpleExpression> pExpression)
    162     : CXFA_FMExpression(line, XFA_FM_EXPTYPE_EXP),
    163       m_pExpression(std::move(pExpression)) {}
    164 
    165 CXFA_FMExpExpression::~CXFA_FMExpExpression() {}
    166 
    167 void CXFA_FMExpExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    168   if (m_pExpression->GetOperatorToken() == TOKassign) {
    169     m_pExpression->ToJavaScript(javascript);
    170   } else {
    171     m_pExpression->ToJavaScript(javascript);
    172     javascript << L";\n";
    173   }
    174 }
    175 
    176 void CXFA_FMExpExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
    177   if (m_pExpression->GetOperatorToken() == TOKassign) {
    178     m_pExpression->ToImpliedReturnJS(javascript);
    179   } else {
    180     if (m_pExpression->GetOperatorToken() == TOKstar ||
    181         m_pExpression->GetOperatorToken() == TOKdotstar ||
    182         m_pExpression->GetOperatorToken() == TOKdotscream ||
    183         m_pExpression->GetOperatorToken() == TOKdotdot ||
    184         m_pExpression->GetOperatorToken() == TOKdot) {
    185       javascript << RUNTIMEFUNCTIONRETURNVALUE;
    186       javascript << L" = ";
    187       javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    188       javascript << L"(";
    189       m_pExpression->ToJavaScript(javascript);
    190       javascript << L");\n";
    191     } else {
    192       javascript << RUNTIMEFUNCTIONRETURNVALUE;
    193       javascript << L" = ";
    194       m_pExpression->ToJavaScript(javascript);
    195       javascript << L";\n";
    196     }
    197   }
    198 }
    199 
    200 CXFA_FMBlockExpression::CXFA_FMBlockExpression(
    201     uint32_t line,
    202     std::vector<std::unique_ptr<CXFA_FMExpression>>&& pExpressionList)
    203     : CXFA_FMExpression(line, XFA_FM_EXPTYPE_BLOCK),
    204       m_ExpressionList(std::move(pExpressionList)) {}
    205 
    206 CXFA_FMBlockExpression::~CXFA_FMBlockExpression() {}
    207 
    208 void CXFA_FMBlockExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    209   javascript << L"{\n";
    210   for (const auto& expr : m_ExpressionList)
    211     expr->ToJavaScript(javascript);
    212   javascript << L"}\n";
    213 }
    214 
    215 void CXFA_FMBlockExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
    216   javascript << L"{\n";
    217   for (const auto& expr : m_ExpressionList) {
    218     if (expr == m_ExpressionList.back())
    219       expr->ToImpliedReturnJS(javascript);
    220     else
    221       expr->ToJavaScript(javascript);
    222   }
    223   javascript << L"}\n";
    224 }
    225 
    226 CXFA_FMDoExpression::CXFA_FMDoExpression(
    227     uint32_t line,
    228     std::unique_ptr<CXFA_FMExpression> pList)
    229     : CXFA_FMExpression(line), m_pList(std::move(pList)) {}
    230 
    231 CXFA_FMDoExpression::~CXFA_FMDoExpression() {}
    232 
    233 void CXFA_FMDoExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    234   m_pList->ToJavaScript(javascript);
    235 }
    236 
    237 void CXFA_FMDoExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
    238   m_pList->ToImpliedReturnJS(javascript);
    239 }
    240 
    241 CXFA_FMIfExpression::CXFA_FMIfExpression(
    242     uint32_t line,
    243     std::unique_ptr<CXFA_FMSimpleExpression> pExpression,
    244     std::unique_ptr<CXFA_FMExpression> pIfExpression,
    245     std::unique_ptr<CXFA_FMExpression> pElseExpression)
    246     : CXFA_FMExpression(line, XFA_FM_EXPTYPE_IF),
    247       m_pExpression(std::move(pExpression)),
    248       m_pIfExpression(std::move(pIfExpression)),
    249       m_pElseExpression(std::move(pElseExpression)) {}
    250 
    251 CXFA_FMIfExpression::~CXFA_FMIfExpression() {}
    252 
    253 void CXFA_FMIfExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    254   javascript << L"if (";
    255   if (m_pExpression) {
    256     javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    257     javascript << L"(";
    258     m_pExpression->ToJavaScript(javascript);
    259     javascript << L")";
    260   }
    261   javascript << L")\n";
    262   if (m_pIfExpression) {
    263     m_pIfExpression->ToJavaScript(javascript);
    264   }
    265   if (m_pElseExpression) {
    266     if (m_pElseExpression->GetExpType() == XFA_FM_EXPTYPE_IF) {
    267       javascript << L"else\n";
    268       javascript << L"{\n";
    269       m_pElseExpression->ToJavaScript(javascript);
    270       javascript << L"}\n";
    271     } else {
    272       javascript << L"else\n";
    273       m_pElseExpression->ToJavaScript(javascript);
    274     }
    275   }
    276 }
    277 
    278 void CXFA_FMIfExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
    279   javascript << RUNTIMEFUNCTIONRETURNVALUE;
    280   javascript << L" = 0;\n";
    281   javascript << L"if (";
    282   if (m_pExpression) {
    283     javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    284     javascript << L"(";
    285     m_pExpression->ToJavaScript(javascript);
    286     javascript << L")";
    287   }
    288   javascript << L")\n";
    289   if (m_pIfExpression) {
    290     m_pIfExpression->ToImpliedReturnJS(javascript);
    291   }
    292   if (m_pElseExpression) {
    293     if (m_pElseExpression->GetExpType() == XFA_FM_EXPTYPE_IF) {
    294       javascript << L"else\n";
    295       javascript << L"{\n";
    296       m_pElseExpression->ToImpliedReturnJS(javascript);
    297       javascript << L"}\n";
    298     } else {
    299       javascript << L"else\n";
    300       m_pElseExpression->ToImpliedReturnJS(javascript);
    301     }
    302   }
    303 }
    304 
    305 CXFA_FMLoopExpression::~CXFA_FMLoopExpression() {}
    306 
    307 void CXFA_FMLoopExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
    308 
    309 void CXFA_FMLoopExpression::ToImpliedReturnJS(CFX_WideTextBuf&) {}
    310 
    311 CXFA_FMWhileExpression::CXFA_FMWhileExpression(
    312     uint32_t line,
    313     std::unique_ptr<CXFA_FMSimpleExpression> pCondition,
    314     std::unique_ptr<CXFA_FMExpression> pExpression)
    315     : CXFA_FMLoopExpression(line),
    316       m_pCondition(std::move(pCondition)),
    317       m_pExpression(std::move(pExpression)) {}
    318 
    319 CXFA_FMWhileExpression::~CXFA_FMWhileExpression() {}
    320 
    321 void CXFA_FMWhileExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    322   javascript << L"while (";
    323   m_pCondition->ToJavaScript(javascript);
    324   javascript << L")\n";
    325   m_pExpression->ToJavaScript(javascript);
    326 }
    327 
    328 void CXFA_FMWhileExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
    329   javascript << RUNTIMEFUNCTIONRETURNVALUE;
    330   javascript << L" = 0;\n";
    331   javascript << L"while (";
    332   m_pCondition->ToJavaScript(javascript);
    333   javascript << L")\n";
    334   m_pExpression->ToImpliedReturnJS(javascript);
    335 }
    336 
    337 CXFA_FMBreakExpression::CXFA_FMBreakExpression(uint32_t line)
    338     : CXFA_FMExpression(line, XFA_FM_EXPTYPE_BREAK) {}
    339 
    340 CXFA_FMBreakExpression::~CXFA_FMBreakExpression() {}
    341 
    342 void CXFA_FMBreakExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    343   javascript << RUNTIMEFUNCTIONRETURNVALUE;
    344   javascript << L" = 0;\n";
    345   javascript << L"break;\n";
    346 }
    347 
    348 void CXFA_FMBreakExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
    349   javascript << RUNTIMEFUNCTIONRETURNVALUE;
    350   javascript << L" = 0;\n";
    351   javascript << L"break;\n";
    352 }
    353 
    354 CXFA_FMContinueExpression::CXFA_FMContinueExpression(uint32_t line)
    355     : CXFA_FMExpression(line, XFA_FM_EXPTYPE_CONTINUE) {}
    356 
    357 CXFA_FMContinueExpression::~CXFA_FMContinueExpression() {}
    358 
    359 void CXFA_FMContinueExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    360   javascript << RUNTIMEFUNCTIONRETURNVALUE;
    361   javascript << L" = 0;\n";
    362   javascript << L"continue;\n";
    363 }
    364 
    365 void CXFA_FMContinueExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
    366   javascript << RUNTIMEFUNCTIONRETURNVALUE;
    367   javascript << L" = 0;\n";
    368   javascript << L"continue;\n";
    369 }
    370 
    371 CXFA_FMForExpression::CXFA_FMForExpression(
    372     uint32_t line,
    373     const CFX_WideStringC& wsVariant,
    374     std::unique_ptr<CXFA_FMSimpleExpression> pAssignment,
    375     std::unique_ptr<CXFA_FMSimpleExpression> pAccessor,
    376     int32_t iDirection,
    377     std::unique_ptr<CXFA_FMSimpleExpression> pStep,
    378     std::unique_ptr<CXFA_FMExpression> pList)
    379     : CXFA_FMLoopExpression(line),
    380       m_wsVariant(wsVariant),
    381       m_pAssignment(std::move(pAssignment)),
    382       m_pAccessor(std::move(pAccessor)),
    383       m_iDirection(iDirection),
    384       m_pStep(std::move(pStep)),
    385       m_pList(std::move(pList)) {}
    386 
    387 CXFA_FMForExpression::~CXFA_FMForExpression() {}
    388 
    389 void CXFA_FMForExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    390   javascript << L"{\nvar ";
    391   CFX_WideString tempVariant;
    392   if (m_wsVariant.GetAt(0) == L'!') {
    393     tempVariant = EXCLAMATION_IN_IDENTIFIER + m_wsVariant.Mid(1);
    394     javascript << tempVariant;
    395   } else {
    396     tempVariant = m_wsVariant;
    397     javascript << m_wsVariant;
    398   }
    399   javascript << L" = null;\n";
    400   javascript << L"for (";
    401   javascript << tempVariant;
    402   javascript << L" = ";
    403   javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    404   javascript << L"(";
    405   m_pAssignment->ToJavaScript(javascript);
    406   javascript << L"); ";
    407   javascript << tempVariant;
    408   if (m_iDirection == 1) {
    409     javascript << L" <= ";
    410     javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    411     javascript << L"(";
    412     m_pAccessor->ToJavaScript(javascript);
    413     javascript << L"); ";
    414     javascript << tempVariant;
    415     javascript << L" += ";
    416   } else {
    417     javascript << L" >= ";
    418     javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    419     javascript << L"(";
    420     m_pAccessor->ToJavaScript(javascript);
    421     javascript << L"); ";
    422     javascript << tempVariant;
    423     javascript << L" -= ";
    424   }
    425   if (m_pStep) {
    426     javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    427     javascript << L"(";
    428     m_pStep->ToJavaScript(javascript);
    429     javascript << L")";
    430   } else {
    431     javascript << L"1";
    432   }
    433   javascript << L")\n";
    434   m_pList->ToJavaScript(javascript);
    435   javascript << L"}\n";
    436 }
    437 
    438 void CXFA_FMForExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
    439   javascript << RUNTIMEFUNCTIONRETURNVALUE;
    440   javascript << L" = 0;\n";
    441   javascript << L"{\nvar ";
    442   CFX_WideString tempVariant;
    443   if (m_wsVariant.GetAt(0) == L'!') {
    444     tempVariant = EXCLAMATION_IN_IDENTIFIER + m_wsVariant.Mid(1);
    445     javascript << tempVariant;
    446   } else {
    447     tempVariant = m_wsVariant;
    448     javascript << m_wsVariant;
    449   }
    450   javascript << L" = null;\n";
    451   javascript << L"for (";
    452   javascript << tempVariant;
    453   javascript << L" = ";
    454   javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    455   javascript << L"(";
    456   m_pAssignment->ToJavaScript(javascript);
    457   javascript << L"); ";
    458   javascript << tempVariant;
    459   if (m_iDirection == 1) {
    460     javascript << L" <= ";
    461     javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    462     javascript << L"(";
    463     m_pAccessor->ToJavaScript(javascript);
    464     javascript << L"); ";
    465     javascript << tempVariant;
    466     javascript << L" += ";
    467   } else {
    468     javascript << L" >= ";
    469     javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    470     javascript << L"(";
    471     m_pAccessor->ToJavaScript(javascript);
    472     javascript << L"); ";
    473     javascript << tempVariant;
    474     javascript << L" -= ";
    475   }
    476   if (m_pStep) {
    477     javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
    478     javascript << L"(";
    479     m_pStep->ToJavaScript(javascript);
    480     javascript << L")";
    481   } else {
    482     javascript << L"1";
    483   }
    484   javascript << L")\n";
    485   m_pList->ToImpliedReturnJS(javascript);
    486   javascript << L"}\n";
    487 }
    488 
    489 CXFA_FMForeachExpression::CXFA_FMForeachExpression(
    490     uint32_t line,
    491     const CFX_WideStringC& wsIdentifier,
    492     std::vector<std::unique_ptr<CXFA_FMSimpleExpression>>&& pAccessors,
    493     std::unique_ptr<CXFA_FMExpression> pList)
    494     : CXFA_FMLoopExpression(line),
    495       m_wsIdentifier(wsIdentifier),
    496       m_pAccessors(std::move(pAccessors)),
    497       m_pList(std::move(pList)) {}
    498 
    499 CXFA_FMForeachExpression::~CXFA_FMForeachExpression() {}
    500 
    501 void CXFA_FMForeachExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    502   javascript << L"{\n";
    503   javascript << L"var ";
    504   if (m_wsIdentifier.GetAt(0) == L'!') {
    505     CFX_WideString tempIdentifier =
    506         EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
    507     javascript << tempIdentifier;
    508   } else {
    509     javascript << m_wsIdentifier;
    510   }
    511   javascript << L" = null;\n";
    512   javascript << L"var ";
    513   javascript << RUNTIMEBLOCKTEMPARRAY;
    514   javascript << L" = ";
    515   javascript << XFA_FM_EXPTypeToString(CONCATFMOBJECT);
    516   javascript << L"(";
    517 
    518   for (const auto& expr : m_pAccessors) {
    519     expr->ToJavaScript(javascript);
    520     if (expr != m_pAccessors.back())
    521       javascript << L", ";
    522   }
    523   javascript << L");\n";
    524   javascript << L"var ";
    525   javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
    526   javascript << (L" = 0;\n");
    527   javascript << L"while(";
    528   javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
    529   javascript << L" < ";
    530   javascript << RUNTIMEBLOCKTEMPARRAY;
    531   javascript << L".length)\n{\n";
    532   if (m_wsIdentifier.GetAt(0) == L'!') {
    533     CFX_WideString tempIdentifier =
    534         EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
    535     javascript << tempIdentifier;
    536   } else {
    537     javascript << m_wsIdentifier;
    538   }
    539   javascript << L" = ";
    540   javascript << RUNTIMEBLOCKTEMPARRAY;
    541   javascript << L"[";
    542   javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
    543   javascript << L"++];\n";
    544   m_pList->ToJavaScript(javascript);
    545   javascript << L"}\n";
    546   javascript << L"}\n";
    547 }
    548 
    549 void CXFA_FMForeachExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
    550   javascript << RUNTIMEFUNCTIONRETURNVALUE;
    551   javascript << L" = 0;\n";
    552   javascript << L"{\n";
    553   javascript << L"var ";
    554   if (m_wsIdentifier.GetAt(0) == L'!') {
    555     CFX_WideString tempIdentifier =
    556         EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
    557     javascript << tempIdentifier;
    558   } else {
    559     javascript << m_wsIdentifier;
    560   }
    561   javascript << L" = null;\n";
    562   javascript << L"var ";
    563   javascript << RUNTIMEBLOCKTEMPARRAY;
    564   javascript << L" = ";
    565   javascript << XFA_FM_EXPTypeToString(CONCATFMOBJECT);
    566   javascript << L"(";
    567   for (const auto& expr : m_pAccessors) {
    568     expr->ToJavaScript(javascript);
    569     if (expr != m_pAccessors.back())
    570       javascript << L", ";
    571   }
    572   javascript << L");\n";
    573   javascript << L"var ";
    574   javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
    575   javascript << L" = 0;\n";
    576   javascript << L"while(";
    577   javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
    578   javascript << L" < ";
    579   javascript << RUNTIMEBLOCKTEMPARRAY;
    580   javascript << L".length)\n{\n";
    581   if (m_wsIdentifier.GetAt(0) == L'!') {
    582     CFX_WideString tempIdentifier =
    583         EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
    584     javascript << tempIdentifier;
    585   } else {
    586     javascript << m_wsIdentifier;
    587   }
    588   javascript << L" = ";
    589   javascript << RUNTIMEBLOCKTEMPARRAY;
    590   javascript << L"[";
    591   javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
    592   javascript << L"++];\n";
    593   m_pList->ToImpliedReturnJS(javascript);
    594   javascript << L"}\n";
    595   javascript << L"}\n";
    596 }
    597