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
CXFA_FMExpression(uint32_t line)23 CXFA_FMExpression::CXFA_FMExpression(uint32_t line)
24 : m_type(XFA_FM_EXPTYPE_UNKNOWN), m_line(line) {}
25
CXFA_FMExpression(uint32_t line,XFA_FM_EXPTYPE type)26 CXFA_FMExpression::CXFA_FMExpression(uint32_t line, XFA_FM_EXPTYPE type)
27 : m_type(type), m_line(line) {}
28
ToJavaScript(CFX_WideTextBuf & javascript)29 void CXFA_FMExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
30
ToImpliedReturnJS(CFX_WideTextBuf & javascript)31 void CXFA_FMExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {}
32
CXFA_FMFunctionDefinition(uint32_t line,bool isGlobal,const CFX_WideStringC & wsName,std::vector<CFX_WideStringC> && arguments,std::vector<std::unique_ptr<CXFA_FMExpression>> && expressions)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
~CXFA_FMFunctionDefinition()45 CXFA_FMFunctionDefinition::~CXFA_FMFunctionDefinition() {}
46
ToJavaScript(CFX_WideTextBuf & javascript)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
ToImpliedReturnJS(CFX_WideTextBuf &)101 void CXFA_FMFunctionDefinition::ToImpliedReturnJS(CFX_WideTextBuf&) {}
102
CXFA_FMVarExpression(uint32_t line,const CFX_WideStringC & wsName,std::unique_ptr<CXFA_FMExpression> pInit)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
~CXFA_FMVarExpression()111 CXFA_FMVarExpression::~CXFA_FMVarExpression() {}
112
ToJavaScript(CFX_WideTextBuf & javascript)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
ToImpliedReturnJS(CFX_WideTextBuf & javascript)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
CXFA_FMExpExpression(uint32_t line,std::unique_ptr<CXFA_FMSimpleExpression> pExpression)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
~CXFA_FMExpExpression()165 CXFA_FMExpExpression::~CXFA_FMExpExpression() {}
166
ToJavaScript(CFX_WideTextBuf & javascript)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
ToImpliedReturnJS(CFX_WideTextBuf & javascript)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
CXFA_FMBlockExpression(uint32_t line,std::vector<std::unique_ptr<CXFA_FMExpression>> && pExpressionList)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
~CXFA_FMBlockExpression()206 CXFA_FMBlockExpression::~CXFA_FMBlockExpression() {}
207
ToJavaScript(CFX_WideTextBuf & javascript)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
ToImpliedReturnJS(CFX_WideTextBuf & javascript)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
CXFA_FMDoExpression(uint32_t line,std::unique_ptr<CXFA_FMExpression> pList)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
~CXFA_FMDoExpression()231 CXFA_FMDoExpression::~CXFA_FMDoExpression() {}
232
ToJavaScript(CFX_WideTextBuf & javascript)233 void CXFA_FMDoExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
234 m_pList->ToJavaScript(javascript);
235 }
236
ToImpliedReturnJS(CFX_WideTextBuf & javascript)237 void CXFA_FMDoExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
238 m_pList->ToImpliedReturnJS(javascript);
239 }
240
CXFA_FMIfExpression(uint32_t line,std::unique_ptr<CXFA_FMSimpleExpression> pExpression,std::unique_ptr<CXFA_FMExpression> pIfExpression,std::unique_ptr<CXFA_FMExpression> pElseExpression)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
~CXFA_FMIfExpression()251 CXFA_FMIfExpression::~CXFA_FMIfExpression() {}
252
ToJavaScript(CFX_WideTextBuf & javascript)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
ToImpliedReturnJS(CFX_WideTextBuf & javascript)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
~CXFA_FMLoopExpression()305 CXFA_FMLoopExpression::~CXFA_FMLoopExpression() {}
306
ToJavaScript(CFX_WideTextBuf & javascript)307 void CXFA_FMLoopExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
308
ToImpliedReturnJS(CFX_WideTextBuf &)309 void CXFA_FMLoopExpression::ToImpliedReturnJS(CFX_WideTextBuf&) {}
310
CXFA_FMWhileExpression(uint32_t line,std::unique_ptr<CXFA_FMSimpleExpression> pCondition,std::unique_ptr<CXFA_FMExpression> pExpression)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
~CXFA_FMWhileExpression()319 CXFA_FMWhileExpression::~CXFA_FMWhileExpression() {}
320
ToJavaScript(CFX_WideTextBuf & javascript)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
ToImpliedReturnJS(CFX_WideTextBuf & javascript)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
CXFA_FMBreakExpression(uint32_t line)337 CXFA_FMBreakExpression::CXFA_FMBreakExpression(uint32_t line)
338 : CXFA_FMExpression(line, XFA_FM_EXPTYPE_BREAK) {}
339
~CXFA_FMBreakExpression()340 CXFA_FMBreakExpression::~CXFA_FMBreakExpression() {}
341
ToJavaScript(CFX_WideTextBuf & javascript)342 void CXFA_FMBreakExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
343 javascript << RUNTIMEFUNCTIONRETURNVALUE;
344 javascript << L" = 0;\n";
345 javascript << L"break;\n";
346 }
347
ToImpliedReturnJS(CFX_WideTextBuf & javascript)348 void CXFA_FMBreakExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
349 javascript << RUNTIMEFUNCTIONRETURNVALUE;
350 javascript << L" = 0;\n";
351 javascript << L"break;\n";
352 }
353
CXFA_FMContinueExpression(uint32_t line)354 CXFA_FMContinueExpression::CXFA_FMContinueExpression(uint32_t line)
355 : CXFA_FMExpression(line, XFA_FM_EXPTYPE_CONTINUE) {}
356
~CXFA_FMContinueExpression()357 CXFA_FMContinueExpression::~CXFA_FMContinueExpression() {}
358
ToJavaScript(CFX_WideTextBuf & javascript)359 void CXFA_FMContinueExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
360 javascript << RUNTIMEFUNCTIONRETURNVALUE;
361 javascript << L" = 0;\n";
362 javascript << L"continue;\n";
363 }
364
ToImpliedReturnJS(CFX_WideTextBuf & javascript)365 void CXFA_FMContinueExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
366 javascript << RUNTIMEFUNCTIONRETURNVALUE;
367 javascript << L" = 0;\n";
368 javascript << L"continue;\n";
369 }
370
CXFA_FMForExpression(uint32_t line,const CFX_WideStringC & wsVariant,std::unique_ptr<CXFA_FMSimpleExpression> pAssignment,std::unique_ptr<CXFA_FMSimpleExpression> pAccessor,int32_t iDirection,std::unique_ptr<CXFA_FMSimpleExpression> pStep,std::unique_ptr<CXFA_FMExpression> pList)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
~CXFA_FMForExpression()387 CXFA_FMForExpression::~CXFA_FMForExpression() {}
388
ToJavaScript(CFX_WideTextBuf & javascript)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
ToImpliedReturnJS(CFX_WideTextBuf & javascript)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
CXFA_FMForeachExpression(uint32_t line,const CFX_WideStringC & wsIdentifier,std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> && pAccessors,std::unique_ptr<CXFA_FMExpression> pList)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
~CXFA_FMForeachExpression()499 CXFA_FMForeachExpression::~CXFA_FMForeachExpression() {}
500
ToJavaScript(CFX_WideTextBuf & javascript)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
ToImpliedReturnJS(CFX_WideTextBuf & javascript)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