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