Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cxfa_fmexpression.cpp
Go to the documentation of this file.
1// Copyright 2014 The PDFium Authors
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/formcalc/cxfa_fmexpression.h"
8
9#include <algorithm>
10#include <utility>
11
12#include "core/fxcrt/autorestorer.h"
13#include "core/fxcrt/fx_extension.h"
14#include "core/fxcrt/widetext_buffer.h"
15#include "fxjs/gc/container_trace.h"
16#include "third_party/base/check.h"
17#include "v8/include/cppgc/visitor.h"
18#include "xfa/fxfa/formcalc/cxfa_fmtojavascriptdepth.h"
19
20namespace {
21
22const wchar_t kLessEqual[] = L" <= ";
23const wchar_t kGreaterEqual[] = L" >= ";
24const wchar_t kPlusEqual[] = L" += ";
25const wchar_t kMinusEqual[] = L" -= ";
26
27const wchar_t* const kBuiltInFuncs[] = {
28 L"Abs", L"Apr", L"At", L"Avg",
29 L"Ceil", L"Choose", L"Concat", L"Count",
30 L"Cterm", L"Date", L"Date2Num", L"DateFmt",
31 L"Decode", L"Encode", L"Eval", L"Exists",
32 L"Floor", L"Format", L"FV", L"Get",
33 L"HasValue", L"If", L"Ipmt", L"IsoDate2Num",
34 L"IsoTime2Num", L"Left", L"Len", L"LocalDateFmt",
35 L"LocalTimeFmt", L"Lower", L"Ltrim", L"Max",
36 L"Min", L"Mod", L"NPV", L"Num2Date",
37 L"Num2GMTime", L"Num2Time", L"Oneof", L"Parse",
38 L"Pmt", L"Post", L"PPmt", L"Put",
39 L"PV", L"Rate", L"Ref", L"Replace",
40 L"Right", L"Round", L"Rtrim", L"Space",
41 L"Str", L"Stuff", L"Substr", L"Sum",
42 L"Term", L"Time", L"Time2Num", L"TimeFmt",
43 L"UnitType", L"UnitValue", L"Upper", L"Uuid",
44 L"Within", L"WordNum",
45};
46
47const size_t kBuiltInFuncsMaxLen = 12;
48
49struct XFA_FMSOMMethod {
50 const wchar_t* m_wsSomMethodName; // Ok, POD struct.
51 uint32_t m_dParameters;
52};
53
54const XFA_FMSOMMethod kFMSomMethods[] = {
55 {L"absPage", 0x01},
56 {L"absPageInBatch", 0x01},
57 {L"absPageSpan", 0x01},
58 {L"append", 0x01},
59 {L"clear", 0x01},
60 {L"formNodes", 0x01},
61 {L"h", 0x01},
62 {L"insert", 0x03},
63 {L"isRecordGroup", 0x01},
64 {L"page", 0x01},
65 {L"pageSpan", 0x01},
66 {L"remove", 0x01},
67 {L"saveFilteredXML", 0x01},
68 {L"setElement", 0x01},
69 {L"sheet", 0x01},
70 {L"sheetInBatch", 0x01},
71 {L"sign", 0x61},
72 {L"verify", 0x0d},
73 {L"w", 0x01},
74 {L"x", 0x01},
75 {L"y", 0x01},
76};
77
78WideString IdentifierToName(const WideString& ident) {
79 if (ident.IsEmpty() || ident[0] != L'!')
80 return ident;
81 return L"pfm__excl__" + ident.Last(ident.GetLength() - 1);
82}
83
84} // namespace
85
87
89
90void CXFA_FMExpression::Trace(cppgc::Visitor* visitor) const {}
91
93
95
101
103
104void CXFA_FMChainableExpression::Trace(cppgc::Visitor* visitor) const {
105 CXFA_FMSimpleExpression::Trace(visitor);
106 visitor->Trace(m_pExp1);
107 visitor->Trace(m_pExp2);
108}
109
110CXFA_FMNullExpression::CXFA_FMNullExpression()
112
113CXFA_FMNullExpression::~CXFA_FMNullExpression() = default;
114
115bool CXFA_FMNullExpression::ToJavaScript(WideTextBuffer* js,
116 ReturnType type) const {
117 CXFA_FMToJavaScriptDepth depthManager;
118 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
119 return false;
120
121 *js << "null";
122 return !CXFA_IsTooBig(*js);
123}
124
125CXFA_FMNumberExpression::CXFA_FMNumberExpression(WideString wsNumber)
126 : CXFA_FMSimpleExpression(TOKnumber), m_wsNumber(std::move(wsNumber)) {}
127
128CXFA_FMNumberExpression::~CXFA_FMNumberExpression() = default;
129
130bool CXFA_FMNumberExpression::ToJavaScript(WideTextBuffer* js,
131 ReturnType type) const {
132 CXFA_FMToJavaScriptDepth depthManager;
133 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
134 return false;
135
136 *js << m_wsNumber;
137 return !CXFA_IsTooBig(*js);
138}
139
140CXFA_FMStringExpression::CXFA_FMStringExpression(WideString wsString)
141 : CXFA_FMSimpleExpression(TOKstring), m_wsString(std::move(wsString)) {}
142
143CXFA_FMStringExpression::~CXFA_FMStringExpression() = default;
144
145bool CXFA_FMStringExpression::ToJavaScript(WideTextBuffer* js,
146 ReturnType type) const {
147 CXFA_FMToJavaScriptDepth depthManager;
148 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
149 return false;
150
151 WideString tempStr(m_wsString);
152 if (tempStr.GetLength() <= 2) {
153 *js << tempStr;
154 return !CXFA_IsTooBig(*js);
155 }
156
157 *js << "\"";
158 for (size_t i = 1; i < tempStr.GetLength() - 1; i++) {
159 wchar_t oneChar = tempStr[i];
160 switch (oneChar) {
161 case L'\"':
162 ++i;
163 *js << "\\\"";
164 break;
165 case 0x0d:
166 break;
167 case 0x0a:
168 *js << "\\n";
169 break;
170 default:
171 js->AppendChar(oneChar);
172 break;
173 }
174 }
175 *js << "\"";
176 return !CXFA_IsTooBig(*js);
177}
178
179CXFA_FMIdentifierExpression::CXFA_FMIdentifierExpression(
180 WideString wsIdentifier)
182 m_wsIdentifier(std::move(wsIdentifier)) {}
183
184CXFA_FMIdentifierExpression::~CXFA_FMIdentifierExpression() = default;
185
186bool CXFA_FMIdentifierExpression::ToJavaScript(WideTextBuffer* js,
187 ReturnType type) const {
188 CXFA_FMToJavaScriptDepth depthManager;
189 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
190 return false;
191
192 if (m_wsIdentifier.EqualsASCII("$"))
193 *js << "this";
194 else if (m_wsIdentifier.EqualsASCII("!"))
195 *js << "xfa.datasets";
196 else if (m_wsIdentifier.EqualsASCII("$data"))
197 *js << "xfa.datasets.data";
198 else if (m_wsIdentifier.EqualsASCII("$event"))
199 *js << "xfa.event";
200 else if (m_wsIdentifier.EqualsASCII("$form"))
201 *js << "xfa.form";
202 else if (m_wsIdentifier.EqualsASCII("$host"))
203 *js << "xfa.host";
204 else if (m_wsIdentifier.EqualsASCII("$layout"))
205 *js << "xfa.layout";
206 else if (m_wsIdentifier.EqualsASCII("$template"))
207 *js << "xfa.template";
208 else if (m_wsIdentifier[0] == L'!')
209 *js << "pfm__excl__" << m_wsIdentifier.Last(m_wsIdentifier.GetLength() - 1);
210 else
211 *js << m_wsIdentifier;
212
213 return !CXFA_IsTooBig(*js);
214}
215
216CXFA_FMAssignExpression::CXFA_FMAssignExpression(XFA_FM_TOKEN op,
219 : CXFA_FMChainableExpression(op, pExp1, pExp2) {}
220
221CXFA_FMAssignExpression::~CXFA_FMAssignExpression() = default;
222
223bool CXFA_FMAssignExpression::ToJavaScript(WideTextBuffer* js,
224 ReturnType type) const {
225 CXFA_FMToJavaScriptDepth depthManager;
226 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
227 return false;
228
229 WideTextBuffer tempExp1;
232 return false;
233
234 *js << "if (pfm_rt.is_obj(" << tempExp1 << "))\n{\n";
235 if (type == ReturnType::kImplied)
236 *js << "pfm_ret = ";
237
238 WideTextBuffer tempExp2;
241 return false;
242
243 *js << "pfm_rt.asgn_val_op(" << tempExp1 << ", " << tempExp2 << ");\n}\n";
244
246 !tempExp1.AsStringView().EqualsASCII("this")) {
247 *js << "else\n{\n";
248 if (type == ReturnType::kImplied)
249 *js << "pfm_ret = ";
250
251 *js << tempExp1 << " = pfm_rt.asgn_val_op";
252 *js << "(" << tempExp1 << ", " << tempExp2 << ");\n";
253 *js << "}\n";
254 }
255 return !CXFA_IsTooBig(*js);
256}
257
263
265
266bool CXFA_FMBinExpression::ToJavaScript(WideTextBuffer* js,
267 ReturnType type) const {
268 CXFA_FMToJavaScriptDepth depthManager;
269 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
270 return false;
271
272 *js << "pfm_rt." << m_OpName << "(";
273 if (!GetFirstExpression()->ToJavaScript(js, ReturnType::kInferred))
274 return false;
275 *js << ", ";
276 if (!GetSecondExpression()->ToJavaScript(js, ReturnType::kInferred))
277 return false;
278 *js << ")";
279 return !CXFA_IsTooBig(*js);
280}
281
282CXFA_FMLogicalOrExpression::CXFA_FMLogicalOrExpression(
283 XFA_FM_TOKEN op,
286 : CXFA_FMBinExpression(L"log_or_op", op, pExp1, pExp2) {}
287
288CXFA_FMLogicalOrExpression::~CXFA_FMLogicalOrExpression() = default;
289
290CXFA_FMLogicalAndExpression::CXFA_FMLogicalAndExpression(
291 XFA_FM_TOKEN op,
294 : CXFA_FMBinExpression(L"log_and_op", op, pExp1, pExp2) {}
295
296CXFA_FMLogicalAndExpression::~CXFA_FMLogicalAndExpression() = default;
297
298CXFA_FMEqualExpression::CXFA_FMEqualExpression(XFA_FM_TOKEN op,
301 : CXFA_FMBinExpression(L"eq_op", op, pExp1, pExp2) {}
302
303CXFA_FMEqualExpression::~CXFA_FMEqualExpression() = default;
304
305CXFA_FMNotEqualExpression::CXFA_FMNotEqualExpression(
306 XFA_FM_TOKEN op,
309 : CXFA_FMBinExpression(L"neq_op", op, pExp1, pExp2) {}
310
311CXFA_FMNotEqualExpression::~CXFA_FMNotEqualExpression() = default;
312
313CXFA_FMGtExpression::CXFA_FMGtExpression(XFA_FM_TOKEN op,
316 : CXFA_FMBinExpression(L"gt_op", op, pExp1, pExp2) {}
317
318CXFA_FMGtExpression::~CXFA_FMGtExpression() = default;
319
320CXFA_FMGeExpression::CXFA_FMGeExpression(XFA_FM_TOKEN op,
323 : CXFA_FMBinExpression(L"ge_op", op, pExp1, pExp2) {}
324
325CXFA_FMGeExpression::~CXFA_FMGeExpression() = default;
326
327CXFA_FMLtExpression::CXFA_FMLtExpression(XFA_FM_TOKEN op,
330 : CXFA_FMBinExpression(L"lt_op", op, pExp1, pExp2) {}
331
332CXFA_FMLtExpression::~CXFA_FMLtExpression() = default;
333
334CXFA_FMLeExpression::CXFA_FMLeExpression(XFA_FM_TOKEN op,
337 : CXFA_FMBinExpression(L"le_op", op, pExp1, pExp2) {}
338
339CXFA_FMLeExpression::~CXFA_FMLeExpression() = default;
340
341CXFA_FMPlusExpression::CXFA_FMPlusExpression(XFA_FM_TOKEN op,
344 : CXFA_FMBinExpression(L"plus_op", op, pExp1, pExp2) {}
345
346CXFA_FMPlusExpression::~CXFA_FMPlusExpression() = default;
347
348CXFA_FMMinusExpression::CXFA_FMMinusExpression(XFA_FM_TOKEN op,
351 : CXFA_FMBinExpression(L"minus_op", op, pExp1, pExp2) {}
352
353CXFA_FMMinusExpression::~CXFA_FMMinusExpression() = default;
354
355CXFA_FMMulExpression::CXFA_FMMulExpression(XFA_FM_TOKEN op,
358 : CXFA_FMBinExpression(L"mul_op", op, pExp1, pExp2) {}
359
360CXFA_FMMulExpression::~CXFA_FMMulExpression() = default;
361
362CXFA_FMDivExpression::CXFA_FMDivExpression(XFA_FM_TOKEN op,
365 : CXFA_FMBinExpression(L"div_op", op, pExp1, pExp2) {}
366
367CXFA_FMDivExpression::~CXFA_FMDivExpression() = default;
368
373
375
376void CXFA_FMUnaryExpression::Trace(cppgc::Visitor* visitor) const {
377 CXFA_FMSimpleExpression::Trace(visitor);
378 visitor->Trace(m_pExp);
379}
380
381bool CXFA_FMUnaryExpression::ToJavaScript(WideTextBuffer* js,
382 ReturnType type) const {
383 CXFA_FMToJavaScriptDepth depthManager;
384 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
385 return false;
386
387 *js << "pfm_rt." << m_OpName << "(";
388 if (!m_pExp->ToJavaScript(js, ReturnType::kInferred))
389 return false;
390 *js << ")";
391 return !CXFA_IsTooBig(*js);
392}
393
394CXFA_FMPosExpression::CXFA_FMPosExpression(CXFA_FMSimpleExpression* pExp)
395 : CXFA_FMUnaryExpression(L"pos_op", TOKplus, pExp) {}
396
397CXFA_FMPosExpression::~CXFA_FMPosExpression() = default;
398
399CXFA_FMNegExpression::CXFA_FMNegExpression(CXFA_FMSimpleExpression* pExp)
400 : CXFA_FMUnaryExpression(L"neg_op", TOKminus, pExp) {}
401
402CXFA_FMNegExpression::~CXFA_FMNegExpression() = default;
403
404CXFA_FMNotExpression::CXFA_FMNotExpression(CXFA_FMSimpleExpression* pExp)
405 : CXFA_FMUnaryExpression(L"log_not_op", TOKksnot, pExp) {}
406
407CXFA_FMNotExpression::~CXFA_FMNotExpression() = default;
408
409CXFA_FMCallExpression::CXFA_FMCallExpression(
411 std::vector<cppgc::Member<CXFA_FMSimpleExpression>>&& pArguments,
412 bool bIsSomMethod)
414 m_pExp(pExp),
415 m_Arguments(std::move(pArguments)),
416 m_bIsSomMethod(bIsSomMethod) {}
417
418CXFA_FMCallExpression::~CXFA_FMCallExpression() = default;
419
420void CXFA_FMCallExpression::Trace(cppgc::Visitor* visitor) const {
421 CXFA_FMSimpleExpression::Trace(visitor);
422 visitor->Trace(m_pExp);
423 ContainerTrace(visitor, m_Arguments);
424}
425
426bool CXFA_FMCallExpression::IsBuiltInFunc(WideTextBuffer* funcName) const {
427 if (funcName->GetLength() > kBuiltInFuncsMaxLen)
428 return false;
429
430 WideString str = funcName->MakeString();
431 const wchar_t* const* pMatchResult =
432 std::lower_bound(std::begin(kBuiltInFuncs), std::end(kBuiltInFuncs), str,
433 [](const wchar_t* iter, const WideString& val) -> bool {
434 return val.CompareNoCase(iter) > 0;
435 });
436 if (pMatchResult != std::end(kBuiltInFuncs) &&
437 !str.CompareNoCase(*pMatchResult)) {
438 funcName->Clear();
439 *funcName << *pMatchResult;
440 return true;
441 }
442 return false;
443}
444
445uint32_t CXFA_FMCallExpression::IsMethodWithObjParam(
446 const WideString& methodName) const {
447 const XFA_FMSOMMethod* result = std::lower_bound(
448 std::begin(kFMSomMethods), std::end(kFMSomMethods), methodName,
449 [](const XFA_FMSOMMethod iter, const WideString& val) {
450 return val.Compare(iter.m_wsSomMethodName) > 0;
451 });
452 if (result != std::end(kFMSomMethods) &&
453 methodName == result->m_wsSomMethodName) {
454 return result->m_dParameters;
455 }
456 return 0;
457}
458
459bool CXFA_FMCallExpression::ToJavaScript(WideTextBuffer* js,
460 ReturnType type) const {
461 CXFA_FMToJavaScriptDepth depthManager;
462 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
463 return false;
464
465 WideTextBuffer funcName;
466 if (!m_pExp->ToJavaScript(&funcName, ReturnType::kInferred))
467 return false;
468
469 if (m_bIsSomMethod) {
470 *js << funcName << "(";
471 uint32_t methodPara = IsMethodWithObjParam(funcName.MakeString());
472 if (methodPara > 0) {
473 for (size_t i = 0; i < m_Arguments.size(); ++i) {
474 // Currently none of our expressions use objects for a parameter over
475 // the 6th. Make sure we don't overflow the shift when doing this
476 // check. If we ever need more the 32 object params we can revisit.
477 *js << "pfm_rt.get_";
478 if (i < 32 && (methodPara & (0x01 << i)) > 0)
479 *js << "jsobj";
480 else
481 *js << "val";
482
483 *js << "(";
484 if (!m_Arguments[i]->ToJavaScript(js, ReturnType::kInferred))
485 return false;
486 *js << ")";
487 if (i + 1 < m_Arguments.size())
488 *js << ", ";
489 }
490 } else {
491 for (const auto& expr : m_Arguments) {
492 *js << "pfm_rt.get_val(";
493 if (!expr->ToJavaScript(js, ReturnType::kInferred))
494 return false;
495 *js << ")";
496 if (expr != m_Arguments.back())
497 *js << ", ";
498 }
499 }
500 *js << ")";
501 return !CXFA_IsTooBig(*js);
502 }
503
504 bool isEvalFunc = false;
505 bool isExistsFunc = false;
506 if (!IsBuiltInFunc(&funcName)) {
507 // If a function is not a SomMethod or a built-in then the input was
508 // invalid, so failing. The scanner/lexer should catch this, but currently
509 // doesn't. This failure will bubble up to the top-level and cause the
510 // transpile to fail.
511 return false;
512 }
513
514 if (funcName.AsStringView().EqualsASCII("Eval")) {
515 isEvalFunc = true;
516 *js << "eval.call(this, pfm_rt.Translate";
517 } else {
518 if (funcName.AsStringView().EqualsASCII("Exists"))
519 isExistsFunc = true;
520
521 *js << "pfm_rt." << funcName;
522 }
523
524 *js << "(";
525 if (isExistsFunc) {
526 *js << "\n(\nfunction ()\n{\ntry\n{\n";
527 if (!m_Arguments.empty()) {
528 *js << "return ";
529 if (!m_Arguments[0]->ToJavaScript(js, ReturnType::kInferred))
530 return false;
531 *js << ";\n}\n";
532 } else {
533 *js << "return 0;\n}\n";
534 }
535 *js << "catch(accessExceptions)\n";
536 *js << "{\nreturn 0;\n}\n}\n).call(this)\n";
537 } else {
538 for (const auto& expr : m_Arguments) {
539 if (!expr->ToJavaScript(js, ReturnType::kInferred))
540 return false;
541 if (expr != m_Arguments.back())
542 *js << ", ";
543 }
544 }
545 *js << ")";
546 if (isEvalFunc)
547 *js << ")";
548
549 return !CXFA_IsTooBig(*js);
550}
551
552CXFA_FMDotAccessorExpression::CXFA_FMDotAccessorExpression(
553 CXFA_FMSimpleExpression* pAccessor,
554 XFA_FM_TOKEN op,
555 WideString wsIdentifier,
556 CXFA_FMSimpleExpression* pIndexExp)
557 : CXFA_FMChainableExpression(op, pAccessor, pIndexExp),
558 m_wsIdentifier(std::move(wsIdentifier)) {}
559
560CXFA_FMDotAccessorExpression::~CXFA_FMDotAccessorExpression() = default;
561
562bool CXFA_FMDotAccessorExpression::ToJavaScript(WideTextBuffer* js,
563 ReturnType type) const {
564 CXFA_FMToJavaScriptDepth depthManager;
565 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
566 return false;
567
568 *js << "pfm_rt.dot_acc(";
569
571 if (exp1) {
572 // Write directly to the buffer with each recursion. Creating
573 // and copying temporaries here becomes expensive when there
574 // is deep recursion, even though we may need to re-create the
575 // same thing again below. See https://crbug.com/1274018.
577 return false;
578 } else {
579 *js << "null";
580 }
581 *js << ", \"";
582 if (exp1 && exp1->GetOperatorToken() == TOKidentifier) {
584 return false;
585 }
586 *js << "\", ";
588 *js << "\"#" << m_wsIdentifier << "\", ";
589 else if (GetOperatorToken() == TOKdotstar)
590 *js << "\"*\", ";
591 else if (GetOperatorToken() == TOKcall)
592 *js << "\"\", ";
593 else
594 *js << "\"" << m_wsIdentifier << "\", ";
595
598 return false;
599
600 *js << ")";
601 return !CXFA_IsTooBig(*js);
602}
603
604CXFA_FMIndexExpression::CXFA_FMIndexExpression(
605 AccessorIndex accessorIndex,
606 CXFA_FMSimpleExpression* pIndexExp,
607 bool bIsStarIndex)
609 m_pExp(pIndexExp),
610 m_accessorIndex(accessorIndex),
611 m_bIsStarIndex(bIsStarIndex) {}
612
613CXFA_FMIndexExpression::~CXFA_FMIndexExpression() = default;
614
615void CXFA_FMIndexExpression::Trace(cppgc::Visitor* visitor) const {
616 CXFA_FMSimpleExpression::Trace(visitor);
617 visitor->Trace(m_pExp);
618}
619
620bool CXFA_FMIndexExpression::ToJavaScript(WideTextBuffer* js,
621 ReturnType type) const {
622 CXFA_FMToJavaScriptDepth depthManager;
623 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
624 return false;
625
626 switch (m_accessorIndex) {
628 *js << "0";
629 break;
631 *js << "1";
632 break;
634 *js << "2";
635 break;
637 *js << "3";
638 break;
639 }
640 if (m_bIsStarIndex)
641 return !CXFA_IsTooBig(*js);
642
643 *js << ", ";
644 if (m_pExp) {
645 if (!m_pExp->ToJavaScript(js, ReturnType::kInferred))
646 return false;
647 } else {
648 *js << "0";
649 }
650 return !CXFA_IsTooBig(*js);
651}
652
653CXFA_FMDotDotAccessorExpression::CXFA_FMDotDotAccessorExpression(
654 CXFA_FMSimpleExpression* pAccessor,
655 XFA_FM_TOKEN op,
656 WideString wsIdentifier,
657 CXFA_FMSimpleExpression* pIndexExp)
658 : CXFA_FMChainableExpression(op, pAccessor, pIndexExp),
659 m_wsIdentifier(std::move(wsIdentifier)) {}
660
661CXFA_FMDotDotAccessorExpression::~CXFA_FMDotDotAccessorExpression() = default;
662
663bool CXFA_FMDotDotAccessorExpression::ToJavaScript(WideTextBuffer* js,
664 ReturnType type) const {
665 CXFA_FMToJavaScriptDepth depthManager;
666 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
667 return false;
668
670 *js << "pfm_rt.dotdot_acc(";
672 return false;
673 *js << ", "
674 << "\"";
677 return false;
678 }
679
681 *js << "\", \"" << m_wsIdentifier << "\", ";
683 return false;
684 *js << ")";
685 return !CXFA_IsTooBig(*js);
686}
687
688CXFA_FMMethodCallExpression::CXFA_FMMethodCallExpression(
689 CXFA_FMSimpleExpression* pAccessorExp1,
690 CXFA_FMSimpleExpression* pCallExp)
691 : CXFA_FMChainableExpression(TOKdot, pAccessorExp1, pCallExp) {}
692
693CXFA_FMMethodCallExpression::~CXFA_FMMethodCallExpression() = default;
694
695bool CXFA_FMMethodCallExpression::ToJavaScript(WideTextBuffer* js,
696 ReturnType type) const {
697 CXFA_FMToJavaScriptDepth depthManager;
698 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
699 return false;
700
701 *js << "(function() {\n";
702 *js << " return pfm_method_runner(";
703 if (!GetFirstExpression()->ToJavaScript(js, ReturnType::kInferred))
704 return false;
705
706 *js << ", function(obj) {\n";
707 *js << " return obj.";
708 if (!GetSecondExpression()->ToJavaScript(js, ReturnType::kInferred))
709 return false;
710
711 *js << ";\n";
712 *js << " });\n";
713 *js << "}).call(this)";
714 return !CXFA_IsTooBig(*js);
715}
716
717CXFA_FMFunctionDefinition::CXFA_FMFunctionDefinition(
718 WideString wsName,
719 std::vector<WideString>&& arguments,
720 std::vector<cppgc::Member<CXFA_FMExpression>>&& expressions)
721 : m_wsName(std::move(wsName)),
722 m_pArguments(std::move(arguments)),
723 m_pExpressions(std::move(expressions)) {
724 DCHECK(!m_wsName.IsEmpty());
725}
726
727CXFA_FMFunctionDefinition::~CXFA_FMFunctionDefinition() = default;
728
729void CXFA_FMFunctionDefinition::Trace(cppgc::Visitor* visitor) const {
730 CXFA_FMExpression::Trace(visitor);
731 ContainerTrace(visitor, m_pExpressions);
732}
733
734bool CXFA_FMFunctionDefinition::ToJavaScript(WideTextBuffer* js,
735 ReturnType type) const {
736 CXFA_FMToJavaScriptDepth depthManager;
737 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
738 return false;
739
740 if (m_wsName.IsEmpty())
741 return false;
742
743 *js << "function " << IdentifierToName(m_wsName) << "(";
744 for (const auto& identifier : m_pArguments) {
745 if (identifier != m_pArguments.front())
746 *js << ", ";
747
748 *js << IdentifierToName(identifier);
749 }
750 *js << ") {\n";
751
752 *js << "var pfm_ret = null;\n";
753 for (const auto& expr : m_pExpressions) {
754 ReturnType ret_type = expr == m_pExpressions.back() ? ReturnType::kImplied
755 : ReturnType::kInferred;
756 if (!expr->ToJavaScript(js, ret_type))
757 return false;
758 }
759
760 *js << "return pfm_ret;\n";
761 *js << "}\n";
762
763 return !CXFA_IsTooBig(*js);
764}
765
766CXFA_FMAST::CXFA_FMAST(
767 std::vector<cppgc::Member<CXFA_FMExpression>> expressions)
768 : expressions_(std::move(expressions)) {}
769
770CXFA_FMAST::~CXFA_FMAST() = default;
771
772void CXFA_FMAST::Trace(cppgc::Visitor* visitor) const {
773 ContainerTrace(visitor, expressions_);
774}
775
777 WideTextBuffer js;
778 if (expressions_.empty()) {
779 js << "// comments only";
780 return js;
781 }
782
783 js << "(function() {\n";
784 js << "let pfm_method_runner = function(obj, cb) {\n";
785 js << " if (pfm_rt.is_ary(obj)) {\n";
786 js << " let pfm_method_return = null;\n";
787 js << " for (var idx = obj.length -1; idx > 1; idx--) {\n";
788 js << " pfm_method_return = cb(obj[idx]);\n";
789 js << " }\n";
790 js << " return pfm_method_return;\n";
791 js << " }\n";
792 js << " return cb(obj);\n";
793 js << "};\n";
794 js << "var pfm_ret = null;\n";
795 for (const auto& expr : expressions_) {
796 CXFA_FMAssignExpression::ReturnType ret_type =
797 expr == expressions_.back()
798 ? CXFA_FMAssignExpression::ReturnType::kImplied
799 : CXFA_FMAssignExpression::ReturnType::kInferred;
800 if (!expr->ToJavaScript(&js, ret_type))
801 return absl::nullopt;
802 }
803 js << "return pfm_rt.get_val(pfm_ret);\n";
804 js << "}).call(this);";
805
806 if (CXFA_IsTooBig(js))
807 return absl::nullopt;
808
809 return js;
810}
811
812CXFA_FMVarExpression::CXFA_FMVarExpression(WideString wsName,
814 : m_wsName(std::move(wsName)), m_pInit(pInit) {}
815
816CXFA_FMVarExpression::~CXFA_FMVarExpression() = default;
817
818void CXFA_FMVarExpression::Trace(cppgc::Visitor* visitor) const {
819 CXFA_FMExpression::Trace(visitor);
820 visitor->Trace(m_pInit);
821}
822
823bool CXFA_FMVarExpression::ToJavaScript(WideTextBuffer* js,
824 ReturnType type) const {
825 CXFA_FMToJavaScriptDepth depthManager;
826 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
827 return false;
828
829 WideString tempName = IdentifierToName(m_wsName);
830 *js << "var " << tempName << " = ";
831 if (m_pInit) {
832 if (!m_pInit->ToJavaScript(js, ReturnType::kInferred))
833 return false;
834
835 *js << ";\n";
836 *js << tempName << " = pfm_rt.var_filter(" << tempName << ");\n";
837 } else {
838 *js << "\"\";\n";
839 }
840
841 if (type == ReturnType::kImplied)
842 *js << "pfm_ret = " << tempName << ";\n";
843
844 return !CXFA_IsTooBig(*js);
845}
846
847CXFA_FMExpExpression::CXFA_FMExpExpression(CXFA_FMSimpleExpression* pExpression)
848 : m_pExpression(pExpression) {}
849
850CXFA_FMExpExpression::~CXFA_FMExpExpression() = default;
851
852void CXFA_FMExpExpression::Trace(cppgc::Visitor* visitor) const {
853 CXFA_FMExpression::Trace(visitor);
854 visitor->Trace(m_pExpression);
855}
856
857bool CXFA_FMExpExpression::ToJavaScript(WideTextBuffer* js,
858 ReturnType type) const {
859 CXFA_FMToJavaScriptDepth depthManager;
860 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
861 return false;
862
863 if (type == ReturnType::kInferred) {
864 bool ret = m_pExpression->ToJavaScript(js, ReturnType::kInferred);
865 if (m_pExpression->GetOperatorToken() != TOKassign)
866 *js << ";\n";
867
868 return ret;
869 }
870
871 if (m_pExpression->GetOperatorToken() == TOKassign)
872 return m_pExpression->ToJavaScript(js, ReturnType::kImplied);
873
874 if (m_pExpression->GetOperatorToken() == TOKstar ||
875 m_pExpression->GetOperatorToken() == TOKdotstar ||
876 m_pExpression->GetOperatorToken() == TOKdotscream ||
877 m_pExpression->GetOperatorToken() == TOKdotdot ||
878 m_pExpression->GetOperatorToken() == TOKdot) {
879 *js << "pfm_ret = pfm_rt.get_val(";
880 if (!m_pExpression->ToJavaScript(js, ReturnType::kInferred))
881 return false;
882
883 *js << ");\n";
884 return !CXFA_IsTooBig(*js);
885 }
886
887 *js << "pfm_ret = ";
888 if (!m_pExpression->ToJavaScript(js, ReturnType::kInferred))
889 return false;
890
891 *js << ";\n";
892 return !CXFA_IsTooBig(*js);
893}
894
895CXFA_FMBlockExpression::CXFA_FMBlockExpression(
896 std::vector<cppgc::Member<CXFA_FMExpression>>&& pExpressionList)
897 : m_ExpressionList(std::move(pExpressionList)) {}
898
899CXFA_FMBlockExpression::~CXFA_FMBlockExpression() = default;
900
901void CXFA_FMBlockExpression::Trace(cppgc::Visitor* visitor) const {
902 CXFA_FMExpression::Trace(visitor);
903 ContainerTrace(visitor, m_ExpressionList);
904}
905
906bool CXFA_FMBlockExpression::ToJavaScript(WideTextBuffer* js,
907 ReturnType type) const {
908 CXFA_FMToJavaScriptDepth depthManager;
909 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
910 return false;
911
912 *js << "{\n";
913 for (const auto& expr : m_ExpressionList) {
914 if (type == ReturnType::kInferred) {
915 if (!expr->ToJavaScript(js, ReturnType::kInferred))
916 return false;
917 } else {
918 ReturnType ret_type = expr == m_ExpressionList.back()
919 ? ReturnType::kImplied
920 : ReturnType::kInferred;
921 if (!expr->ToJavaScript(js, ret_type))
922 return false;
923 }
924 }
925 *js << "}\n";
926
927 return !CXFA_IsTooBig(*js);
928}
929
930CXFA_FMDoExpression::CXFA_FMDoExpression(CXFA_FMExpression* pList)
931 : m_pList(pList) {}
932
933CXFA_FMDoExpression::~CXFA_FMDoExpression() = default;
934
935void CXFA_FMDoExpression::Trace(cppgc::Visitor* visitor) const {
936 CXFA_FMExpression::Trace(visitor);
937 visitor->Trace(m_pList);
938}
939
940bool CXFA_FMDoExpression::ToJavaScript(WideTextBuffer* js,
941 ReturnType type) const {
942 CXFA_FMToJavaScriptDepth depthManager;
943 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
944 return false;
945
946 return m_pList->ToJavaScript(js, type);
947}
948
949CXFA_FMIfExpression::CXFA_FMIfExpression(
950 CXFA_FMSimpleExpression* pExpression,
951 CXFA_FMExpression* pIfExpression,
952 std::vector<cppgc::Member<CXFA_FMIfExpression>>&& pElseIfExpressions,
953 CXFA_FMExpression* pElseExpression)
954 : m_pExpression(pExpression),
955 m_pIfExpression(pIfExpression),
956 m_pElseIfExpressions(std::move(pElseIfExpressions)),
957 m_pElseExpression(pElseExpression) {
958 DCHECK(m_pExpression);
959}
960
961CXFA_FMIfExpression::~CXFA_FMIfExpression() = default;
962
963void CXFA_FMIfExpression::Trace(cppgc::Visitor* visitor) const {
964 CXFA_FMExpression::Trace(visitor);
965 visitor->Trace(m_pExpression);
966 visitor->Trace(m_pIfExpression);
967 ContainerTrace(visitor, m_pElseIfExpressions);
968 visitor->Trace(m_pElseExpression);
969}
970
971bool CXFA_FMIfExpression::ToJavaScript(WideTextBuffer* js,
972 ReturnType type) const {
973 CXFA_FMToJavaScriptDepth depthManager;
974 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
975 return false;
976
977 if (type == ReturnType::kImplied)
978 *js << "pfm_ret = 0;\n";
979
980 *js << "if (pfm_rt.get_val(";
981 if (!m_pExpression->ToJavaScript(js, ReturnType::kInferred))
982 return false;
983 *js << "))\n";
984
985 if (CXFA_IsTooBig(*js))
986 return false;
987
988 if (m_pIfExpression) {
989 if (!m_pIfExpression->ToJavaScript(js, type))
990 return false;
991 if (CXFA_IsTooBig(*js))
992 return false;
993 }
994
995 for (auto& expr : m_pElseIfExpressions) {
996 *js << "else ";
997 if (!expr->ToJavaScript(js, ReturnType::kInferred))
998 return false;
999 }
1000
1001 if (m_pElseExpression) {
1002 *js << "else ";
1003 if (!m_pElseExpression->ToJavaScript(js, type))
1004 return false;
1005 }
1006 return !CXFA_IsTooBig(*js);
1007}
1008
1009CXFA_FMWhileExpression::CXFA_FMWhileExpression(
1010 CXFA_FMSimpleExpression* pCondition,
1011 CXFA_FMExpression* pExpression)
1012 : m_pCondition(pCondition), m_pExpression(pExpression) {}
1013
1014CXFA_FMWhileExpression::~CXFA_FMWhileExpression() = default;
1015
1016void CXFA_FMWhileExpression::Trace(cppgc::Visitor* visitor) const {
1017 CXFA_FMExpression::Trace(visitor);
1018 visitor->Trace(m_pCondition);
1019 visitor->Trace(m_pExpression);
1020}
1021
1022bool CXFA_FMWhileExpression::ToJavaScript(WideTextBuffer* js,
1023 ReturnType type) const {
1024 CXFA_FMToJavaScriptDepth depthManager;
1025 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
1026 return false;
1027
1028 if (type == ReturnType::kImplied)
1029 *js << "pfm_ret = 0;\n";
1030
1031 *js << "while (";
1032 if (!m_pCondition->ToJavaScript(js, ReturnType::kInferred))
1033 return false;
1034
1035 *js << ")\n";
1036 if (CXFA_IsTooBig(*js))
1037 return false;
1038
1039 if (!m_pExpression->ToJavaScript(js, type))
1040 return false;
1041
1042 return !CXFA_IsTooBig(*js);
1043}
1044
1045CXFA_FMBreakExpression::CXFA_FMBreakExpression() = default;
1046
1047CXFA_FMBreakExpression::~CXFA_FMBreakExpression() = default;
1048
1049bool CXFA_FMBreakExpression::ToJavaScript(WideTextBuffer* js,
1050 ReturnType type) const {
1051 CXFA_FMToJavaScriptDepth depthManager;
1052 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
1053 return false;
1054
1055 *js << "pfm_ret = 0;\nbreak;\n";
1056 return !CXFA_IsTooBig(*js);
1057}
1058
1059CXFA_FMContinueExpression::CXFA_FMContinueExpression() = default;
1060
1061CXFA_FMContinueExpression::~CXFA_FMContinueExpression() = default;
1062
1063bool CXFA_FMContinueExpression::ToJavaScript(WideTextBuffer* js,
1064 ReturnType type) const {
1065 CXFA_FMToJavaScriptDepth depthManager;
1066 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
1067 return false;
1068
1069 *js << "pfm_ret = 0;\ncontinue;\n";
1070 return !CXFA_IsTooBig(*js);
1071}
1072
1073CXFA_FMForExpression::CXFA_FMForExpression(WideString wsVariant,
1074 CXFA_FMSimpleExpression* pAssignment,
1075 CXFA_FMSimpleExpression* pAccessor,
1076 int32_t iDirection,
1078 CXFA_FMExpression* pList)
1079 : m_wsVariant(std::move(wsVariant)),
1080 m_bDirection(iDirection == 1),
1081 m_pAssignment(pAssignment),
1082 m_pAccessor(pAccessor),
1083 m_pStep(pStep),
1084 m_pList(pList) {}
1085
1086CXFA_FMForExpression::~CXFA_FMForExpression() = default;
1087
1088void CXFA_FMForExpression::Trace(cppgc::Visitor* visitor) const {
1089 CXFA_FMExpression::Trace(visitor);
1090 visitor->Trace(m_pAssignment);
1091 visitor->Trace(m_pAccessor);
1092 visitor->Trace(m_pStep);
1093 visitor->Trace(m_pList);
1094}
1095
1096bool CXFA_FMForExpression::ToJavaScript(WideTextBuffer* js,
1097 ReturnType type) const {
1098 CXFA_FMToJavaScriptDepth depthManager;
1099 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
1100 return false;
1101
1102 if (type == ReturnType::kImplied)
1103 *js << "pfm_ret = 0;\n";
1104
1105 *js << "{\n";
1106
1107 WideString tmpName = IdentifierToName(m_wsVariant);
1108 *js << "var " << tmpName << " = null;\n";
1109
1110 *js << "for (" << tmpName << " = pfm_rt.get_val(";
1111 if (!m_pAssignment->ToJavaScript(js, ReturnType::kInferred))
1112 return false;
1113 *js << "); ";
1114
1115 *js << tmpName << (m_bDirection ? kLessEqual : kGreaterEqual);
1116 *js << "pfm_rt.get_val(";
1117 if (!m_pAccessor->ToJavaScript(js, ReturnType::kInferred))
1118 return false;
1119 *js << "); ";
1120
1121 *js << tmpName << (m_bDirection ? kPlusEqual : kMinusEqual);
1122 if (m_pStep) {
1123 *js << "pfm_rt.get_val(";
1124 if (!m_pStep->ToJavaScript(js, ReturnType::kInferred))
1125 return false;
1126 *js << ")";
1127 } else {
1128 *js << "1";
1129 }
1130 *js << ")\n";
1131 if (CXFA_IsTooBig(*js))
1132 return false;
1133
1134 if (!m_pList->ToJavaScript(js, type))
1135 return false;
1136
1137 *js << "}\n";
1138 return !CXFA_IsTooBig(*js);
1139}
1140
1141CXFA_FMForeachExpression::CXFA_FMForeachExpression(
1142 WideString wsIdentifier,
1143 std::vector<cppgc::Member<CXFA_FMSimpleExpression>>&& pAccessors,
1144 CXFA_FMExpression* pList)
1145 : m_wsIdentifier(std::move(wsIdentifier)),
1146 m_pAccessors(std::move(pAccessors)),
1147 m_pList(pList) {}
1148
1149CXFA_FMForeachExpression::~CXFA_FMForeachExpression() = default;
1150
1151void CXFA_FMForeachExpression::Trace(cppgc::Visitor* visitor) const {
1152 CXFA_FMExpression::Trace(visitor);
1153 ContainerTrace(visitor, m_pAccessors);
1154 visitor->Trace(m_pList);
1155}
1156
1157bool CXFA_FMForeachExpression::ToJavaScript(WideTextBuffer* js,
1158 ReturnType type) const {
1159 CXFA_FMToJavaScriptDepth depthManager;
1160 if (CXFA_IsTooBig(*js) || !depthManager.IsWithinMaxDepth())
1161 return false;
1162
1163 if (type == ReturnType::kImplied)
1164 *js << "pfm_ret = 0;\n";
1165
1166 *js << "{\n";
1167
1168 WideString tmpName = IdentifierToName(m_wsIdentifier);
1169 *js << "var " << tmpName << " = null;\n";
1170 *js << "var pfm_ary = pfm_rt.concat_obj(";
1171 for (const auto& expr : m_pAccessors) {
1172 if (!expr->ToJavaScript(js, ReturnType::kInferred))
1173 return false;
1174 if (expr != m_pAccessors.back())
1175 *js << ", ";
1176 }
1177 *js << ");\n";
1178
1179 *js << "var pfm_ary_idx = 0;\n";
1180 *js << "while(pfm_ary_idx < pfm_ary.length)\n{\n";
1181 *js << tmpName << " = pfm_ary[pfm_ary_idx++];\n";
1182 if (!m_pList->ToJavaScript(js, type))
1183 return false;
1184
1185 *js << "}\n"; // while
1186 *js << "}\n"; // block
1187 return !CXFA_IsTooBig(*js);
1188}
1189
1190bool CXFA_IsTooBig(const WideTextBuffer& js) {
1191 return js.GetSize() >= 256 * 1024 * 1024;
1192}
absl::optional< WideTextBuffer > ToJavaScript() const
void Trace(cppgc::Visitor *visitor) const
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMAssignExpression() override
~CXFA_FMBinExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
CXFA_FMBinExpression(const WideString &opName, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2)
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
void Trace(cppgc::Visitor *visitor) const override
~CXFA_FMBlockExpression() override
~CXFA_FMBreakExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMCallExpression() override
uint32_t IsMethodWithObjParam(const WideString &methodName) const
bool IsBuiltInFunc(WideTextBuffer *funcName) const
void Trace(cppgc::Visitor *visitor) const override
void Trace(cppgc::Visitor *visitor) const override
~CXFA_FMChainableExpression() override
CXFA_FMSimpleExpression * GetSecondExpression() const
CXFA_FMChainableExpression(XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2)
CXFA_FMSimpleExpression * GetFirstExpression() const
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMContinueExpression() override
~CXFA_FMDivExpression() override
~CXFA_FMDoExpression() override
void Trace(cppgc::Visitor *visitor) const override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMDotAccessorExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMEqualExpression() override
void Trace(cppgc::Visitor *visitor) const override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMExpExpression() override
virtual void Trace(cppgc::Visitor *visitor) const
virtual ~CXFA_FMExpression()
virtual bool ToJavaScript(WideTextBuffer *js, ReturnType type) const =0
~CXFA_FMForExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
void Trace(cppgc::Visitor *visitor) const override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
void Trace(cppgc::Visitor *visitor) const override
~CXFA_FMForeachExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
void Trace(cppgc::Visitor *visitor) const override
~CXFA_FMFunctionDefinition() override
~CXFA_FMGeExpression() override
~CXFA_FMGtExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMIdentifierExpression() override
~CXFA_FMIfExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
void Trace(cppgc::Visitor *visitor) const override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMIndexExpression() override
void Trace(cppgc::Visitor *visitor) const override
~CXFA_FMLeExpression() override
~CXFA_FMLogicalAndExpression() override
~CXFA_FMLogicalOrExpression() override
~CXFA_FMLtExpression() override
~CXFA_FMMethodCallExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMMinusExpression() override
~CXFA_FMMulExpression() override
~CXFA_FMNegExpression() override
~CXFA_FMNotEqualExpression() override
~CXFA_FMNotExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMNullExpression() override
~CXFA_FMNumberExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMPlusExpression() override
~CXFA_FMPosExpression() override
CXFA_FMSimpleExpression(XFA_FM_TOKEN op)
~CXFA_FMSimpleExpression() override
XFA_FM_TOKEN GetOperatorToken() const
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMStringExpression() override
~CXFA_FMUnaryExpression() override
CXFA_FMUnaryExpression(const WideString &opName, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp)
void Trace(cppgc::Visitor *visitor) const override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMVarExpression() override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
void Trace(cppgc::Visitor *visitor) const override
void Trace(cppgc::Visitor *visitor) const override
bool ToJavaScript(WideTextBuffer *js, ReturnType type) const override
~CXFA_FMWhileExpression() override
bool operator==(const wchar_t *ptr) const
CharType operator[](const size_t index) const
Definition widestring.h:146
bool IsEmpty() const
Definition widestring.h:118
int CompareNoCase(const wchar_t *str) const
int Compare(const wchar_t *str) const
void AppendChar(wchar_t wch)
WideString MakeString() const
WideStringView AsStringView() const
bool CXFA_IsTooBig(const WideTextBuffer &js)
XFA_FM_TOKEN
@ TOKdotstar
@ TOKminus
@ TOKnumber
@ TOKcall
@ TOKlbracket
@ TOKplus
@ TOKnull
@ TOKksnot
@ TOKidentifier
@ TOKstring
@ TOKdotscream
@ TOKdot