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 #ifndef XFA_FXFA_FORMCALC_CXFA_FMEXPRESSION_H_ 8 #define XFA_FXFA_FORMCALC_CXFA_FMEXPRESSION_H_ 9 10 #include <vector> 11 12 #include "core/fxcrt/widestring.h" 13 #include "core/fxcrt/widetext_buffer.h" 14 #include "fxjs/gc/heap.h" 15 #include "third_party/abseil-cpp/absl/types/optional.h" 16 #include "v8/include/cppgc/garbage-collected.h" 17 #include "v8/include/cppgc/member.h" 18 #include "xfa/fxfa/formcalc/cxfa_fmlexer.h" 19 20 class CXFA_FMExpression : public cppgc::GarbageCollected<CXFA_FMExpression> { 21 public: 22 enum class ReturnType { kImplied, kInferred }; 23 24 virtual ~CXFA_FMExpression(); 25 virtual void Trace(cppgc::Visitor* visitor) const; 26 27 virtual bool ToJavaScript(WideTextBuffer* js, ReturnType type) const = 0; 28 29 protected: 30 CXFA_FMExpression(); 31 }; 32 33 class CXFA_FMSimpleExpression : public CXFA_FMExpression { 34 public: 35 ~CXFA_FMSimpleExpression() override; 36 GetOperatorToken()37 XFA_FM_TOKEN GetOperatorToken() const { return m_op; } 38 39 protected: 40 explicit CXFA_FMSimpleExpression(XFA_FM_TOKEN op); 41 42 private: 43 const XFA_FM_TOKEN m_op; 44 }; 45 46 class CXFA_FMChainableExpression : public CXFA_FMSimpleExpression { 47 public: 48 ~CXFA_FMChainableExpression() override; 49 void Trace(cppgc::Visitor* visitor) const override; 50 51 protected: 52 CXFA_FMChainableExpression(XFA_FM_TOKEN op, 53 CXFA_FMSimpleExpression* pExp1, 54 CXFA_FMSimpleExpression* pExp2); 55 GetFirstExpression()56 CXFA_FMSimpleExpression* GetFirstExpression() const { return m_pExp1; } GetSecondExpression()57 CXFA_FMSimpleExpression* GetSecondExpression() const { return m_pExp2; } 58 59 private: 60 cppgc::Member<CXFA_FMSimpleExpression> m_pExp1; 61 cppgc::Member<CXFA_FMSimpleExpression> m_pExp2; 62 }; 63 64 class CXFA_FMNullExpression final : public CXFA_FMSimpleExpression { 65 public: 66 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 67 ~CXFA_FMNullExpression() override; 68 69 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 70 71 private: 72 CXFA_FMNullExpression(); 73 }; 74 75 class CXFA_FMNumberExpression final : public CXFA_FMSimpleExpression { 76 public: 77 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 78 ~CXFA_FMNumberExpression() override; 79 80 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 81 82 private: 83 explicit CXFA_FMNumberExpression(WideString wsNumber); 84 85 WideString m_wsNumber; 86 }; 87 88 class CXFA_FMStringExpression final : public CXFA_FMSimpleExpression { 89 public: 90 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 91 ~CXFA_FMStringExpression() override; 92 93 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 94 95 private: 96 explicit CXFA_FMStringExpression(WideString wsString); 97 98 WideString m_wsString; 99 }; 100 101 class CXFA_FMIdentifierExpression final : public CXFA_FMSimpleExpression { 102 public: 103 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 104 ~CXFA_FMIdentifierExpression() override; 105 106 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 107 108 private: 109 explicit CXFA_FMIdentifierExpression(WideString wsIdentifier); 110 111 WideString m_wsIdentifier; 112 }; 113 114 class CXFA_FMAssignExpression final : public CXFA_FMChainableExpression { 115 public: 116 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 117 ~CXFA_FMAssignExpression() override; 118 119 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 120 121 private: 122 CXFA_FMAssignExpression(XFA_FM_TOKEN op, 123 CXFA_FMSimpleExpression* pExp1, 124 CXFA_FMSimpleExpression* pExp2); 125 }; 126 127 class CXFA_FMBinExpression : public CXFA_FMChainableExpression { 128 public: 129 ~CXFA_FMBinExpression() override; 130 131 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 132 133 protected: 134 CXFA_FMBinExpression(const WideString& opName, 135 XFA_FM_TOKEN op, 136 CXFA_FMSimpleExpression* pExp1, 137 CXFA_FMSimpleExpression* pExp2); 138 139 private: 140 WideString m_OpName; 141 }; 142 143 class CXFA_FMLogicalOrExpression final : public CXFA_FMBinExpression { 144 public: 145 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 146 ~CXFA_FMLogicalOrExpression() override; 147 148 private: 149 CXFA_FMLogicalOrExpression(XFA_FM_TOKEN op, 150 CXFA_FMSimpleExpression* pExp1, 151 CXFA_FMSimpleExpression* pExp2); 152 }; 153 154 class CXFA_FMLogicalAndExpression final : public CXFA_FMBinExpression { 155 public: 156 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 157 ~CXFA_FMLogicalAndExpression() override; 158 159 private: 160 CXFA_FMLogicalAndExpression(XFA_FM_TOKEN op, 161 CXFA_FMSimpleExpression* pExp1, 162 CXFA_FMSimpleExpression* pExp2); 163 }; 164 165 class CXFA_FMEqualExpression final : public CXFA_FMBinExpression { 166 public: 167 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 168 ~CXFA_FMEqualExpression() override; 169 170 private: 171 CXFA_FMEqualExpression(XFA_FM_TOKEN op, 172 CXFA_FMSimpleExpression* pExp1, 173 CXFA_FMSimpleExpression* pExp2); 174 }; 175 176 class CXFA_FMNotEqualExpression final : public CXFA_FMBinExpression { 177 public: 178 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 179 ~CXFA_FMNotEqualExpression() override; 180 181 private: 182 CXFA_FMNotEqualExpression(XFA_FM_TOKEN op, 183 CXFA_FMSimpleExpression* pExp1, 184 CXFA_FMSimpleExpression* pExp2); 185 }; 186 187 class CXFA_FMGtExpression final : public CXFA_FMBinExpression { 188 public: 189 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 190 ~CXFA_FMGtExpression() override; 191 192 private: 193 CXFA_FMGtExpression(XFA_FM_TOKEN op, 194 CXFA_FMSimpleExpression* pExp1, 195 CXFA_FMSimpleExpression* pExp2); 196 }; 197 198 class CXFA_FMGeExpression final : public CXFA_FMBinExpression { 199 public: 200 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 201 ~CXFA_FMGeExpression() override; 202 203 private: 204 CXFA_FMGeExpression(XFA_FM_TOKEN op, 205 CXFA_FMSimpleExpression* pExp1, 206 CXFA_FMSimpleExpression* pExp2); 207 }; 208 209 class CXFA_FMLtExpression final : public CXFA_FMBinExpression { 210 public: 211 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 212 ~CXFA_FMLtExpression() override; 213 214 private: 215 CXFA_FMLtExpression(XFA_FM_TOKEN op, 216 CXFA_FMSimpleExpression* pExp1, 217 CXFA_FMSimpleExpression* pExp2); 218 }; 219 220 class CXFA_FMLeExpression final : public CXFA_FMBinExpression { 221 public: 222 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 223 ~CXFA_FMLeExpression() override; 224 225 private: 226 CXFA_FMLeExpression(XFA_FM_TOKEN op, 227 CXFA_FMSimpleExpression* pExp1, 228 CXFA_FMSimpleExpression* pExp2); 229 }; 230 231 class CXFA_FMPlusExpression final : public CXFA_FMBinExpression { 232 public: 233 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 234 ~CXFA_FMPlusExpression() override; 235 236 private: 237 CXFA_FMPlusExpression(XFA_FM_TOKEN op, 238 CXFA_FMSimpleExpression* pExp1, 239 CXFA_FMSimpleExpression* pExp2); 240 }; 241 242 class CXFA_FMMinusExpression final : public CXFA_FMBinExpression { 243 public: 244 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 245 ~CXFA_FMMinusExpression() override; 246 247 private: 248 CXFA_FMMinusExpression(XFA_FM_TOKEN op, 249 CXFA_FMSimpleExpression* pExp1, 250 CXFA_FMSimpleExpression* pExp2); 251 }; 252 253 class CXFA_FMMulExpression final : public CXFA_FMBinExpression { 254 public: 255 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 256 ~CXFA_FMMulExpression() override; 257 258 private: 259 CXFA_FMMulExpression(XFA_FM_TOKEN op, 260 CXFA_FMSimpleExpression* pExp1, 261 CXFA_FMSimpleExpression* pExp2); 262 }; 263 264 class CXFA_FMDivExpression final : public CXFA_FMBinExpression { 265 public: 266 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 267 ~CXFA_FMDivExpression() override; 268 269 private: 270 CXFA_FMDivExpression(XFA_FM_TOKEN op, 271 CXFA_FMSimpleExpression* pExp1, 272 CXFA_FMSimpleExpression* pExp2); 273 }; 274 275 class CXFA_FMUnaryExpression : public CXFA_FMSimpleExpression { 276 public: 277 ~CXFA_FMUnaryExpression() override; 278 279 void Trace(cppgc::Visitor* visitor) const override; 280 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 281 282 protected: 283 CXFA_FMUnaryExpression(const WideString& opName, 284 XFA_FM_TOKEN op, 285 CXFA_FMSimpleExpression* pExp); 286 287 private: 288 WideString m_OpName; 289 cppgc::Member<CXFA_FMSimpleExpression> m_pExp; 290 }; 291 292 class CXFA_FMPosExpression final : public CXFA_FMUnaryExpression { 293 public: 294 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 295 ~CXFA_FMPosExpression() override; 296 297 private: 298 explicit CXFA_FMPosExpression(CXFA_FMSimpleExpression* pExp); 299 }; 300 301 class CXFA_FMNegExpression final : public CXFA_FMUnaryExpression { 302 public: 303 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 304 ~CXFA_FMNegExpression() override; 305 306 private: 307 explicit CXFA_FMNegExpression(CXFA_FMSimpleExpression* pExp); 308 }; 309 310 class CXFA_FMNotExpression final : public CXFA_FMUnaryExpression { 311 public: 312 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 313 ~CXFA_FMNotExpression() override; 314 315 private: 316 explicit CXFA_FMNotExpression(CXFA_FMSimpleExpression* pExp); 317 }; 318 319 class CXFA_FMCallExpression final : public CXFA_FMSimpleExpression { 320 public: 321 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 322 ~CXFA_FMCallExpression() override; 323 324 void Trace(cppgc::Visitor* visitor) const override; 325 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 326 327 bool IsBuiltInFunc(WideTextBuffer* funcName) const; 328 uint32_t IsMethodWithObjParam(const WideString& methodName) const; 329 330 private: 331 CXFA_FMCallExpression( 332 CXFA_FMSimpleExpression* pExp, 333 std::vector<cppgc::Member<CXFA_FMSimpleExpression>>&& pArguments, 334 bool bIsSomMethod); 335 336 cppgc::Member<CXFA_FMSimpleExpression> m_pExp; 337 std::vector<cppgc::Member<CXFA_FMSimpleExpression>> m_Arguments; 338 bool m_bIsSomMethod; 339 }; 340 341 class CXFA_FMDotAccessorExpression final : public CXFA_FMChainableExpression { 342 public: 343 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 344 ~CXFA_FMDotAccessorExpression() override; 345 346 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 347 348 private: 349 CXFA_FMDotAccessorExpression(CXFA_FMSimpleExpression* pAccessor, 350 XFA_FM_TOKEN op, 351 WideString wsIdentifier, 352 CXFA_FMSimpleExpression* pIndexExp); 353 354 WideString m_wsIdentifier; 355 }; 356 357 class CXFA_FMIndexExpression final : public CXFA_FMSimpleExpression { 358 public: 359 enum class AccessorIndex : uint8_t { 360 kNoIndex, 361 kNoRelativeIndex, 362 kPositiveIndex, 363 kNegativeIndex 364 }; 365 366 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 367 ~CXFA_FMIndexExpression() override; 368 369 void Trace(cppgc::Visitor* visitor) const override; 370 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 371 372 private: 373 CXFA_FMIndexExpression(AccessorIndex accessorIndex, 374 CXFA_FMSimpleExpression* pIndexExp, 375 bool bIsStarIndex); 376 377 cppgc::Member<CXFA_FMSimpleExpression> m_pExp; 378 AccessorIndex m_accessorIndex; 379 bool m_bIsStarIndex; 380 }; 381 382 class CXFA_FMDotDotAccessorExpression final 383 : public CXFA_FMChainableExpression { 384 public: 385 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 386 ~CXFA_FMDotDotAccessorExpression() override; 387 388 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 389 390 private: 391 CXFA_FMDotDotAccessorExpression(CXFA_FMSimpleExpression* pAccessor, 392 XFA_FM_TOKEN op, 393 WideString wsIdentifier, 394 CXFA_FMSimpleExpression* pIndexExp); 395 396 WideString m_wsIdentifier; 397 }; 398 399 class CXFA_FMMethodCallExpression final : public CXFA_FMChainableExpression { 400 public: 401 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 402 ~CXFA_FMMethodCallExpression() override; 403 404 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 405 406 private: 407 CXFA_FMMethodCallExpression(CXFA_FMSimpleExpression* pAccessorExp1, 408 CXFA_FMSimpleExpression* pCallExp); 409 }; 410 411 class CXFA_FMFunctionDefinition final : public CXFA_FMExpression { 412 public: 413 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 414 ~CXFA_FMFunctionDefinition() override; 415 416 void Trace(cppgc::Visitor* visitor) const override; 417 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 418 419 private: 420 CXFA_FMFunctionDefinition( 421 WideString wsName, 422 std::vector<WideString>&& arguments, 423 std::vector<cppgc::Member<CXFA_FMExpression>>&& expressions); 424 425 const WideString m_wsName; 426 std::vector<WideString> const m_pArguments; 427 std::vector<cppgc::Member<CXFA_FMExpression>> const m_pExpressions; 428 }; 429 430 class CXFA_FMVarExpression final : public CXFA_FMExpression { 431 public: 432 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 433 ~CXFA_FMVarExpression() override; 434 435 void Trace(cppgc::Visitor* visitor) const override; 436 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 437 438 private: 439 CXFA_FMVarExpression(WideString wsName, CXFA_FMSimpleExpression* pInit); 440 441 WideString const m_wsName; 442 cppgc::Member<CXFA_FMSimpleExpression> const m_pInit; 443 }; 444 445 class CXFA_FMExpExpression final : public CXFA_FMExpression { 446 public: 447 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 448 ~CXFA_FMExpExpression() override; 449 450 void Trace(cppgc::Visitor* visitor) const override; 451 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 452 453 private: 454 explicit CXFA_FMExpExpression(CXFA_FMSimpleExpression* pExpression); 455 456 cppgc::Member<CXFA_FMSimpleExpression> const m_pExpression; 457 }; 458 459 class CXFA_FMBlockExpression final : public CXFA_FMExpression { 460 public: 461 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 462 ~CXFA_FMBlockExpression() override; 463 464 void Trace(cppgc::Visitor* visitor) const override; 465 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 466 467 private: 468 CXFA_FMBlockExpression( 469 std::vector<cppgc::Member<CXFA_FMExpression>>&& pExpressionList); 470 471 std::vector<cppgc::Member<CXFA_FMExpression>> const m_ExpressionList; 472 }; 473 474 class CXFA_FMDoExpression final : public CXFA_FMExpression { 475 public: 476 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 477 ~CXFA_FMDoExpression() override; 478 479 void Trace(cppgc::Visitor* visitor) const override; 480 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 481 482 private: 483 explicit CXFA_FMDoExpression(CXFA_FMExpression* pList); 484 485 cppgc::Member<CXFA_FMExpression> const m_pList; 486 }; 487 488 class CXFA_FMIfExpression final : public CXFA_FMExpression { 489 public: 490 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 491 ~CXFA_FMIfExpression() override; 492 493 void Trace(cppgc::Visitor* visitor) const override; 494 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 495 496 private: 497 CXFA_FMIfExpression( 498 CXFA_FMSimpleExpression* pExpression, 499 CXFA_FMExpression* pIfExpression, 500 std::vector<cppgc::Member<CXFA_FMIfExpression>>&& pElseIfExpressions, 501 CXFA_FMExpression* pElseExpression); 502 503 cppgc::Member<CXFA_FMSimpleExpression> const m_pExpression; 504 cppgc::Member<CXFA_FMExpression> const m_pIfExpression; 505 std::vector<cppgc::Member<CXFA_FMIfExpression>> const m_pElseIfExpressions; 506 cppgc::Member<CXFA_FMExpression> const m_pElseExpression; 507 }; 508 509 class CXFA_FMWhileExpression final : public CXFA_FMExpression { 510 public: 511 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 512 ~CXFA_FMWhileExpression() override; 513 514 void Trace(cppgc::Visitor* visitor) const override; 515 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 516 517 private: 518 CXFA_FMWhileExpression(CXFA_FMSimpleExpression* pCodition, 519 CXFA_FMExpression* pExpression); 520 521 cppgc::Member<CXFA_FMSimpleExpression> const m_pCondition; 522 cppgc::Member<CXFA_FMExpression> const m_pExpression; 523 }; 524 525 class CXFA_FMBreakExpression final : public CXFA_FMExpression { 526 public: 527 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 528 ~CXFA_FMBreakExpression() override; 529 530 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 531 532 private: 533 CXFA_FMBreakExpression(); 534 }; 535 536 class CXFA_FMContinueExpression final : public CXFA_FMExpression { 537 public: 538 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 539 ~CXFA_FMContinueExpression() override; 540 541 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 542 543 private: 544 CXFA_FMContinueExpression(); 545 }; 546 547 class CXFA_FMForExpression final : public CXFA_FMExpression { 548 public: 549 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 550 ~CXFA_FMForExpression() override; 551 552 void Trace(cppgc::Visitor* visitor) const override; 553 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 554 555 private: 556 CXFA_FMForExpression(WideString wsVariant, 557 CXFA_FMSimpleExpression* pAssignment, 558 CXFA_FMSimpleExpression* pAccessor, 559 int32_t iDirection, 560 CXFA_FMSimpleExpression* pStep, 561 CXFA_FMExpression* pList); 562 563 const WideString m_wsVariant; 564 const bool m_bDirection; 565 cppgc::Member<CXFA_FMSimpleExpression> const m_pAssignment; 566 cppgc::Member<CXFA_FMSimpleExpression> const m_pAccessor; 567 cppgc::Member<CXFA_FMSimpleExpression> const m_pStep; 568 cppgc::Member<CXFA_FMExpression> const m_pList; 569 }; 570 571 class CXFA_FMForeachExpression final : public CXFA_FMExpression { 572 public: 573 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 574 ~CXFA_FMForeachExpression() override; 575 576 void Trace(cppgc::Visitor* visitor) const override; 577 bool ToJavaScript(WideTextBuffer* js, ReturnType type) const override; 578 579 private: 580 // Takes ownership of |pAccessors|. 581 CXFA_FMForeachExpression( 582 WideString wsIdentifier, 583 std::vector<cppgc::Member<CXFA_FMSimpleExpression>>&& pAccessors, 584 CXFA_FMExpression* pList); 585 586 const WideString m_wsIdentifier; 587 std::vector<cppgc::Member<CXFA_FMSimpleExpression>> const m_pAccessors; 588 cppgc::Member<CXFA_FMExpression> const m_pList; 589 }; 590 591 class CXFA_FMAST : public cppgc::GarbageCollected<CXFA_FMAST> { 592 public: 593 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 594 ~CXFA_FMAST(); 595 596 void Trace(cppgc::Visitor* visitor) const; 597 absl::optional<WideTextBuffer> ToJavaScript() const; 598 599 private: 600 explicit CXFA_FMAST( 601 std::vector<cppgc::Member<CXFA_FMExpression>> expressions); 602 603 std::vector<cppgc::Member<CXFA_FMExpression>> const expressions_; 604 }; 605 606 bool CXFA_IsTooBig(const WideTextBuffer& js); 607 608 #endif // XFA_FXFA_FORMCALC_CXFA_FMEXPRESSION_H_ 609