arkanalyzer 1.0.86 → 1.0.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +69 -65
- package/README.md +56 -70
- package/config/arkanalyzer.json +7 -2
- package/docs/cppFrontend/ArkAnalyzer-cpp_usage_guide.md +245 -0
- package/docs/cppFrontend/cpp_frontend_build_guide.md +126 -0
- package/docs/cppFrontend/cpp_frontend_user_guide.md +175 -0
- package/docs/cppFrontend/img.png +0 -0
- package/docs/cppFrontend/img_1.png +0 -0
- package/docs/cppFrontend/img_10.png +0 -0
- package/docs/cppFrontend/img_11.png +0 -0
- package/docs/cppFrontend/img_12.png +0 -0
- package/docs/cppFrontend/img_13.png +0 -0
- package/docs/cppFrontend/img_14.png +0 -0
- package/docs/cppFrontend/img_15.png +0 -0
- package/docs/cppFrontend/img_16.png +0 -0
- package/docs/cppFrontend/img_17.png +0 -0
- package/docs/cppFrontend/img_18.png +0 -0
- package/docs/cppFrontend/img_19.png +0 -0
- package/docs/cppFrontend/img_2.png +0 -0
- package/docs/cppFrontend/img_20.png +0 -0
- package/docs/cppFrontend/img_21.png +0 -0
- package/docs/cppFrontend/img_22.png +0 -0
- package/docs/cppFrontend/img_23.png +0 -0
- package/docs/cppFrontend/img_3.png +0 -0
- package/docs/cppFrontend/img_4.png +0 -0
- package/docs/cppFrontend/img_5.png +0 -0
- package/docs/cppFrontend/img_6.png +0 -0
- package/docs/cppFrontend/img_7.png +0 -0
- package/docs/cppFrontend/img_8.png +0 -0
- package/docs/cppFrontend/img_9.png +0 -0
- package/docs/sig_programanalysis.en.md +66 -0
- package/docs/sig_programanalysis.md +73 -0
- package/lib/Config.d.ts +32 -1
- package/lib/Config.d.ts.map +1 -1
- package/lib/Config.js +76 -2
- package/lib/Scene.d.ts +25 -2
- package/lib/Scene.d.ts.map +1 -1
- package/lib/Scene.js +148 -40
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts +4 -3
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/AbstractAnalysis.js +17 -17
- package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts +6 -1
- package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/RapidTypeAnalysis.js +117 -14
- package/lib/callgraph/common/Statistics.d.ts +4 -2
- package/lib/callgraph/common/Statistics.d.ts.map +1 -1
- package/lib/callgraph/common/Statistics.js +14 -2
- package/lib/callgraph/model/CallGraph.d.ts +12 -8
- package/lib/callgraph/model/CallGraph.d.ts.map +1 -1
- package/lib/callgraph/model/CallGraph.js +53 -29
- package/lib/callgraph/model/builder/CallGraphBuilder.d.ts +1 -0
- package/lib/callgraph/model/builder/CallGraphBuilder.d.ts.map +1 -1
- package/lib/callgraph/model/builder/CallGraphBuilder.js +5 -1
- package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Pag.js +3 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +4 -2
- package/lib/cli/cli.d.ts +3 -0
- package/lib/cli/cli.d.ts.map +1 -0
- package/lib/cli/cli.js +82 -0
- package/lib/cli/commands/cg.d.ts +32 -0
- package/lib/cli/commands/cg.d.ts.map +1 -0
- package/lib/cli/commands/cg.js +401 -0
- package/lib/cli/commands/index.d.ts +6 -0
- package/lib/cli/commands/index.d.ts.map +1 -0
- package/lib/cli/commands/index.js +64 -0
- package/lib/cli/commands/ir.d.ts +26 -0
- package/lib/cli/commands/ir.d.ts.map +1 -0
- package/lib/cli/commands/ir.js +94 -0
- package/lib/core/base/Constant.d.ts +1 -1
- package/lib/core/base/Constant.d.ts.map +1 -1
- package/lib/core/base/Constant.js +1 -1
- package/lib/core/base/Expr.d.ts +29 -5
- package/lib/core/base/Expr.d.ts.map +1 -1
- package/lib/core/base/Expr.js +144 -22
- package/lib/core/base/Position.d.ts +14 -0
- package/lib/core/base/Position.d.ts.map +1 -1
- package/lib/core/base/Position.js +27 -0
- package/lib/core/base/Ref.d.ts +1 -0
- package/lib/core/base/Ref.d.ts.map +1 -1
- package/lib/core/base/Ref.js +4 -1
- package/lib/core/base/Type.d.ts +64 -24
- package/lib/core/base/Type.d.ts.map +1 -1
- package/lib/core/base/Type.js +144 -49
- package/lib/core/common/ArkError.d.ts +26 -2
- package/lib/core/common/ArkError.d.ts.map +1 -1
- package/lib/core/common/ArkError.js +56 -2
- package/lib/core/common/ArkIRTransformer.d.ts +11 -10
- package/lib/core/common/ArkIRTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkIRTransformer.js +1 -1
- package/lib/core/common/ArkValueTransformer.d.ts +14 -12
- package/lib/core/common/ArkValueTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkValueTransformer.js +1 -5
- package/lib/core/common/Const.d.ts +3 -0
- package/lib/core/common/Const.d.ts.map +1 -1
- package/lib/core/common/Const.js +4 -1
- package/lib/core/common/DummyMainCreater.d.ts +23 -13
- package/lib/core/common/DummyMainCreater.d.ts.map +1 -1
- package/lib/core/common/DummyMainCreater.js +66 -43
- package/lib/core/common/EtsConst.d.ts +11 -0
- package/lib/core/common/EtsConst.d.ts.map +1 -1
- package/lib/core/common/EtsConst.js +12 -1
- package/lib/core/common/IRInference.d.ts.map +1 -1
- package/lib/core/common/IRInference.js +5 -1
- package/lib/core/common/ModelUtils.d.ts +4 -7
- package/lib/core/common/ModelUtils.d.ts.map +1 -1
- package/lib/core/common/ModelUtils.js +77 -110
- package/lib/core/common/SdkUtils.d.ts +1 -1
- package/lib/core/common/SdkUtils.d.ts.map +1 -1
- package/lib/core/common/SdkUtils.js +14 -5
- package/lib/core/common/TypeInference.d.ts.map +1 -1
- package/lib/core/common/TypeInference.js +9 -3
- package/lib/core/graph/BaseExplicitGraph.d.ts +4 -4
- package/lib/core/graph/BaseExplicitGraph.d.ts.map +1 -1
- package/lib/core/graph/BaseExplicitGraph.js +15 -8
- package/lib/core/graph/BasicBlock.d.ts.map +1 -1
- package/lib/core/graph/Scc.d.ts.map +1 -1
- package/lib/core/graph/Scc.js +7 -2
- package/lib/core/graph/builder/CfgBuilder.d.ts +10 -7
- package/lib/core/graph/builder/CfgBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/CfgBuilder.js +12 -5
- package/lib/core/inference/Inference.d.ts.map +1 -1
- package/lib/core/inference/Inference.js +7 -0
- package/lib/core/inference/ModelInference.d.ts +1 -1
- package/lib/core/inference/ModelInference.d.ts.map +1 -1
- package/lib/core/inference/ValueInference.d.ts +3 -2
- package/lib/core/inference/ValueInference.d.ts.map +1 -1
- package/lib/core/inference/ValueInference.js +64 -12
- package/lib/core/inference/abc/AbcInference.d.ts +28 -2
- package/lib/core/inference/abc/AbcInference.d.ts.map +1 -1
- package/lib/core/inference/abc/AbcInference.js +105 -4
- package/lib/core/model/ArkBaseModel.d.ts +14 -1
- package/lib/core/model/ArkBaseModel.d.ts.map +1 -1
- package/lib/core/model/ArkBaseModel.js +61 -2
- package/lib/core/model/ArkBody.d.ts.map +1 -1
- package/lib/core/model/ArkBody.js +1 -3
- package/lib/core/model/ArkClass.d.ts +22 -2
- package/lib/core/model/ArkClass.d.ts.map +1 -1
- package/lib/core/model/ArkClass.js +59 -28
- package/lib/core/model/ArkField.d.ts.map +1 -1
- package/lib/core/model/ArkField.js +3 -1
- package/lib/core/model/ArkFile.d.ts +4 -1
- package/lib/core/model/ArkFile.d.ts.map +1 -1
- package/lib/core/model/ArkFile.js +44 -3
- package/lib/core/model/ArkImport.d.ts.map +1 -1
- package/lib/core/model/ArkImport.js +9 -1
- package/lib/core/model/ArkMethod.d.ts +5 -0
- package/lib/core/model/ArkMethod.d.ts.map +1 -1
- package/lib/core/model/ArkMethod.js +33 -1
- package/lib/core/model/ArkNamespace.d.ts +2 -0
- package/lib/core/model/ArkNamespace.d.ts.map +1 -1
- package/lib/core/model/ArkNamespace.js +11 -0
- package/lib/core/model/ArkSignature.d.ts +3 -3
- package/lib/core/model/ArkSignature.d.ts.map +1 -1
- package/lib/core/model/ArkSignature.js +14 -9
- package/lib/core/model/builder/ArkClassBuilder.d.ts +2 -0
- package/lib/core/model/builder/ArkClassBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkClassBuilder.js +3 -3
- package/lib/core/model/builder/ArkMethodBuilder.d.ts +4 -1
- package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkMethodBuilder.js +19 -6
- package/lib/core/model/builder/ArkNamespaceBuilder.d.ts +1 -0
- package/lib/core/model/builder/ArkNamespaceBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkNamespaceBuilder.js +2 -1
- package/lib/core/model/builder/BodyBuilder.d.ts +4 -0
- package/lib/core/model/builder/BodyBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/builderUtils.d.ts +1 -0
- package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
- package/lib/core/model/builder/builderUtils.js +7 -3
- package/lib/frontend/cppFrontend/ast/ArkCxxAstNode.d.ts +296 -0
- package/lib/frontend/cppFrontend/ast/ArkCxxAstNode.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/ast/ArkCxxAstNode.js +145 -0
- package/lib/frontend/cppFrontend/ast/astUtils.d.ts +51 -0
- package/lib/frontend/cppFrontend/ast/astUtils.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/ast/astUtils.js +470 -0
- package/lib/frontend/cppFrontend/ast/const.d.ts +30 -0
- package/lib/frontend/cppFrontend/ast/const.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/ast/const.js +134 -0
- package/lib/frontend/cppFrontend/base/Constant.d.ts +9 -0
- package/lib/frontend/cppFrontend/base/Constant.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/base/Constant.js +33 -0
- package/lib/frontend/cppFrontend/base/Expr.d.ts +174 -0
- package/lib/frontend/cppFrontend/base/Expr.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/base/Expr.js +530 -0
- package/lib/frontend/cppFrontend/base/Ref.d.ts +25 -0
- package/lib/frontend/cppFrontend/base/Ref.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/base/Ref.js +53 -0
- package/lib/frontend/cppFrontend/base/Trap.d.ts +8 -0
- package/lib/frontend/cppFrontend/base/Trap.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/base/Trap.js +28 -0
- package/lib/frontend/cppFrontend/base/Type.d.ts +264 -0
- package/lib/frontend/cppFrontend/base/Type.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/base/Type.js +600 -0
- package/lib/frontend/cppFrontend/common/ArkIRTransformer.d.ts +109 -0
- package/lib/frontend/cppFrontend/common/ArkIRTransformer.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/common/ArkIRTransformer.js +925 -0
- package/lib/frontend/cppFrontend/common/ArkValueTransformer.d.ts +477 -0
- package/lib/frontend/cppFrontend/common/ArkValueTransformer.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/common/ArkValueTransformer.js +2746 -0
- package/lib/frontend/cppFrontend/common/Builtin.d.ts +57 -0
- package/lib/frontend/cppFrontend/common/Builtin.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/common/Builtin.js +106 -0
- package/lib/frontend/cppFrontend/common/IRInference.d.ts +94 -0
- package/lib/frontend/cppFrontend/common/IRInference.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/common/IRInference.js +1087 -0
- package/lib/frontend/cppFrontend/common/IRUtils.d.ts +23 -0
- package/lib/frontend/cppFrontend/common/IRUtils.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/common/IRUtils.js +168 -0
- package/lib/frontend/cppFrontend/common/ModelUtils.d.ts +44 -0
- package/lib/frontend/cppFrontend/common/ModelUtils.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/common/ModelUtils.js +567 -0
- package/lib/frontend/cppFrontend/common/TypeInference.d.ts +278 -0
- package/lib/frontend/cppFrontend/common/TypeInference.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/common/TypeInference.js +1354 -0
- package/lib/frontend/cppFrontend/common/ValueUtil.d.ts +16 -0
- package/lib/frontend/cppFrontend/common/ValueUtil.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/common/ValueUtil.js +61 -0
- package/lib/frontend/cppFrontend/graph/builder/CfgBuilder.d.ts +182 -0
- package/lib/frontend/cppFrontend/graph/builder/CfgBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/graph/builder/CfgBuilder.js +1435 -0
- package/lib/frontend/cppFrontend/graph/builder/ConditionBuilder.d.ts +21 -0
- package/lib/frontend/cppFrontend/graph/builder/ConditionBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/graph/builder/ConditionBuilder.js +303 -0
- package/lib/frontend/cppFrontend/graph/builder/IfBuilder.d.ts +15 -0
- package/lib/frontend/cppFrontend/graph/builder/IfBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/graph/builder/IfBuilder.js +161 -0
- package/lib/frontend/cppFrontend/graph/builder/LoopBuilder.d.ts +21 -0
- package/lib/frontend/cppFrontend/graph/builder/LoopBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/graph/builder/LoopBuilder.js +261 -0
- package/lib/frontend/cppFrontend/graph/builder/SwitchBuilder.d.ts +12 -0
- package/lib/frontend/cppFrontend/graph/builder/SwitchBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/graph/builder/SwitchBuilder.js +155 -0
- package/lib/frontend/cppFrontend/graph/builder/TrapBuilder.d.ts +29 -0
- package/lib/frontend/cppFrontend/graph/builder/TrapBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/graph/builder/TrapBuilder.js +302 -0
- package/lib/frontend/cppFrontend/inference/CxxInference.d.ts +10 -0
- package/lib/frontend/cppFrontend/inference/CxxInference.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/inference/CxxInference.js +41 -0
- package/lib/frontend/cppFrontend/inference/CxxModelInference.d.ts +28 -0
- package/lib/frontend/cppFrontend/inference/CxxModelInference.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/inference/CxxModelInference.js +98 -0
- package/lib/frontend/cppFrontend/inference/CxxValueInference.d.ts +20 -0
- package/lib/frontend/cppFrontend/inference/CxxValueInference.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/inference/CxxValueInference.js +128 -0
- package/lib/frontend/cppFrontend/model/builder/ArkClassBuilder.d.ts +11 -0
- package/lib/frontend/cppFrontend/model/builder/ArkClassBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/model/builder/ArkClassBuilder.js +413 -0
- package/lib/frontend/cppFrontend/model/builder/ArkFieldBuilder.d.ts +5 -0
- package/lib/frontend/cppFrontend/model/builder/ArkFieldBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/model/builder/ArkFieldBuilder.js +61 -0
- package/lib/frontend/cppFrontend/model/builder/ArkFileBuilder.d.ts +17 -0
- package/lib/frontend/cppFrontend/model/builder/ArkFileBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/model/builder/ArkFileBuilder.js +285 -0
- package/lib/frontend/cppFrontend/model/builder/ArkImportBuilder.d.ts +6 -0
- package/lib/frontend/cppFrontend/model/builder/ArkImportBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/model/builder/ArkImportBuilder.js +57 -0
- package/lib/frontend/cppFrontend/model/builder/ArkMethodBuilder.d.ts +14 -0
- package/lib/frontend/cppFrontend/model/builder/ArkMethodBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/model/builder/ArkMethodBuilder.js +422 -0
- package/lib/frontend/cppFrontend/model/builder/ArkNamespaceBuilder.d.ts +8 -0
- package/lib/frontend/cppFrontend/model/builder/ArkNamespaceBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/model/builder/ArkNamespaceBuilder.js +194 -0
- package/lib/frontend/cppFrontend/model/builder/BodyBuilder.d.ts +59 -0
- package/lib/frontend/cppFrontend/model/builder/BodyBuilder.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/model/builder/BodyBuilder.js +605 -0
- package/lib/frontend/cppFrontend/model/builder/builderUtils.d.ts +46 -0
- package/lib/frontend/cppFrontend/model/builder/builderUtils.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/model/builder/builderUtils.js +499 -0
- package/lib/frontend/cppFrontend/utils/cmakeUtils.d.ts +44 -0
- package/lib/frontend/cppFrontend/utils/cmakeUtils.d.ts.map +1 -0
- package/lib/frontend/cppFrontend/utils/cmakeUtils.js +240 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -1
- package/lib/node_modules/ohos-typescript/.ohos-typescript-version +1 -0
- package/{node_modules → lib/node_modules}/ohos-typescript/package.json +2 -1
- package/lib/save/CGJsonPrinter.d.ts +8 -0
- package/lib/save/CGJsonPrinter.d.ts.map +1 -0
- package/lib/save/CGJsonPrinter.js +41 -0
- package/lib/save/GraphPrinter.js +2 -2
- package/lib/save/json/JsonDto.d.ts +86 -2
- package/lib/save/json/JsonDto.d.ts.map +1 -1
- package/lib/save/json/JsonSerialization.d.ts +1 -1
- package/lib/save/json/JsonSerialization.d.ts.map +1 -1
- package/lib/save/json/JsonSerialization.js +235 -145
- package/lib/save/source/SourceTransformer.d.ts.map +1 -1
- package/lib/save/source/SourceTransformer.js +0 -3
- package/lib/utils/CxxSceneUtils.d.ts +11 -0
- package/lib/utils/CxxSceneUtils.d.ts.map +1 -0
- package/lib/utils/CxxSceneUtils.js +178 -0
- package/lib/utils/FileUtils.d.ts +7 -8
- package/lib/utils/FileUtils.d.ts.map +1 -1
- package/lib/utils/FileUtils.js +27 -45
- package/lib/utils/LRUCacheDecorator.d.ts +20 -0
- package/lib/utils/LRUCacheDecorator.d.ts.map +1 -0
- package/lib/utils/LRUCacheDecorator.js +89 -0
- package/lib/utils/ModuleUtils.d.ts +39 -0
- package/lib/utils/ModuleUtils.d.ts.map +1 -0
- package/lib/utils/ModuleUtils.js +261 -0
- package/package.json +10 -7
- /package/{node_modules → lib/node_modules}/ohos-typescript/LICENSE +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/README.OpenSource +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/README.md +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/SECURITY.md +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/ThirdPartyNoticeText.txt +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/bin/tsc +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/bin/tsserver +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/README.md +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/cancellationToken.js +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/cs/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/de/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/es/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/fr/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/it/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/ja/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/ko/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.dom.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.dom.iterable.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2015.collection.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2015.core.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2015.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2015.generator.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2015.iterable.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2015.promise.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2015.proxy.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2015.reflect.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2015.symbol.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2015.symbol.wellknown.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2016.array.include.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2016.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2016.full.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2017.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2017.full.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2017.intl.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2017.object.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2017.sharedmemory.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2017.string.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2017.typedarrays.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2018.asyncgenerator.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2018.asynciterable.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2018.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2018.full.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2018.intl.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2018.promise.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2018.regexp.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2019.array.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2019.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2019.full.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2019.intl.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2019.object.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2019.string.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2019.symbol.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2020.bigint.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2020.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2020.date.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2020.full.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2020.intl.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2020.number.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2020.promise.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2020.sharedmemory.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2020.string.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2020.symbol.wellknown.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2021.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2021.full.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2021.intl.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2021.promise.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2021.string.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2021.weakref.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2022.array.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2022.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2022.error.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2022.full.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2022.intl.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2022.object.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2022.sharedmemory.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es2022.string.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es5.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.es6.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.esnext.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.esnext.full.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.esnext.intl.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.scripthost.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.webworker.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.webworker.importscripts.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/lib.webworker.iterable.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/pl/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/pt-br/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/ru/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/tr/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/tsc.js +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/tsserver.js +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/tsserverlibrary.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/tsserverlibrary.js +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/typesMap.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/typescript.d.ts +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/typescript.js +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/typingsInstaller.js +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/watchGuard.js +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/zh-cn/diagnosticMessages.generated.json +0 -0
- /package/{node_modules → lib/node_modules}/ohos-typescript/lib/zh-tw/diagnosticMessages.generated.json +0 -0
|
@@ -0,0 +1,2746 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2024-2025 Huawei Device Co., Ltd.
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.ArkCxxValueTransformer = void 0;
|
|
41
|
+
const Local_1 = require("../../../core/base/Local");
|
|
42
|
+
const Position_1 = require("../../../core/base/Position");
|
|
43
|
+
const Stmt_1 = require("../../../core/base/Stmt");
|
|
44
|
+
const Expr_1 = require("../../../core/base/Expr");
|
|
45
|
+
const Expr_2 = require("../base/Expr");
|
|
46
|
+
const Type_1 = require("../../../core/base/Type");
|
|
47
|
+
const Type_2 = require("../base/Type");
|
|
48
|
+
const ArkSignatureBuilder_1 = require("../../../core/model/builder/ArkSignatureBuilder");
|
|
49
|
+
const ArkSignature_1 = require("../../../core/model/ArkSignature");
|
|
50
|
+
const EtsConst_1 = require("../../../core/common/EtsConst");
|
|
51
|
+
const ValueUtil_1 = require("./ValueUtil");
|
|
52
|
+
const IRUtils_1 = require("./IRUtils");
|
|
53
|
+
const Ref_1 = require("../../../core/base/Ref");
|
|
54
|
+
const Ref_2 = require("../base/Ref");
|
|
55
|
+
const ArkMethod_1 = require("../../../core/model/ArkMethod");
|
|
56
|
+
const ArkMethodBuilder_1 = require("../model/builder/ArkMethodBuilder");
|
|
57
|
+
const Builtin_1 = require("../../../core/common/Builtin");
|
|
58
|
+
const Constant_1 = require("../../../core/base/Constant");
|
|
59
|
+
const ArkIRTransformer_1 = require("./ArkIRTransformer");
|
|
60
|
+
const builderUtils_1 = require("../model/builder/builderUtils");
|
|
61
|
+
const logger_1 = __importStar(require("../../../utils/logger"));
|
|
62
|
+
const ArkValueTransformer_1 = require("../../../core/common/ArkValueTransformer");
|
|
63
|
+
const ModelUtils_1 = require("../../../core/common/ModelUtils");
|
|
64
|
+
const TSConst_1 = require("../../../core/common/TSConst");
|
|
65
|
+
const TypeInference_1 = require("./TypeInference");
|
|
66
|
+
const ModelUtils_2 = require("./ModelUtils");
|
|
67
|
+
const ArkCxxAstNode_1 = require("../ast/ArkCxxAstNode");
|
|
68
|
+
const ArkIRTransformer_2 = require("../../../core/common/ArkIRTransformer");
|
|
69
|
+
const Builtin_2 = require("./Builtin");
|
|
70
|
+
const ArkClass_1 = require("../../../core/model/ArkClass");
|
|
71
|
+
const ValueUtil_2 = require("../../../core/common/ValueUtil");
|
|
72
|
+
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'ArkValueTransformer');
|
|
73
|
+
var CompoundBinaryOperator;
|
|
74
|
+
(function (CompoundBinaryOperator) {
|
|
75
|
+
CompoundBinaryOperator["AdditionEquals"] = "+=";
|
|
76
|
+
CompoundBinaryOperator["SubtractionEquals"] = "-=";
|
|
77
|
+
CompoundBinaryOperator["MultiplicationEquals"] = "*=";
|
|
78
|
+
CompoundBinaryOperator["DivisionEquals"] = "/=";
|
|
79
|
+
CompoundBinaryOperator["RemainderEquals"] = "%=";
|
|
80
|
+
CompoundBinaryOperator["LeftShiftEquals"] = "<<=";
|
|
81
|
+
CompoundBinaryOperator["RightShiftEquals"] = ">>=";
|
|
82
|
+
CompoundBinaryOperator["BitwiseAndEquals"] = "&=";
|
|
83
|
+
CompoundBinaryOperator["BitwiseOrEquals"] = "|=";
|
|
84
|
+
CompoundBinaryOperator["BitwiseXorEquals"] = "^=";
|
|
85
|
+
})(CompoundBinaryOperator || (CompoundBinaryOperator = {}));
|
|
86
|
+
/**
|
|
87
|
+
* Get the inner node of an AST node
|
|
88
|
+
*
|
|
89
|
+
* @param node - C++ AST node object
|
|
90
|
+
* @returns Returns the processed C++ AST node, or an unsupported type node if unable to process
|
|
91
|
+
*/
|
|
92
|
+
function nodeInnerNode(node) {
|
|
93
|
+
var _a, _b;
|
|
94
|
+
if (Array.isArray(node === null || node === void 0 ? void 0 : node.inner) && node.inner.length > 0) {
|
|
95
|
+
const last = node.inner[node.inner.length - 1];
|
|
96
|
+
// Return InitListExpr first
|
|
97
|
+
if ((last === null || last === void 0 ? void 0 : last.kind) === ArkCxxAstNode_1.astKind.InitListExpr) {
|
|
98
|
+
return last;
|
|
99
|
+
}
|
|
100
|
+
// Arrays containing only one TypeRef node do not return
|
|
101
|
+
if (!(node.inner.length === 1 && ((_a = node.inner[0]) === null || _a === void 0 ? void 0 : _a.kind) === ArkCxxAstNode_1.astKind.TypeRef) && !(0, builderUtils_1.isCxxFunctionPointer)(node.type.qualType)) {
|
|
102
|
+
return last;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
logger.info(`unsupported node! kind: ${(_b = node === null || node === void 0 ? void 0 : node.kind) !== null && _b !== void 0 ? _b : ''}, node:`, node);
|
|
106
|
+
return { kind: 'unsupported kind' };
|
|
107
|
+
}
|
|
108
|
+
const COMPOUND_BIN_OPS = new Set(Object.values(CompoundBinaryOperator));
|
|
109
|
+
class ArkCxxValueTransformer extends ArkValueTransformer_1.ArkValueTransformer {
|
|
110
|
+
constructor(arkIRTransformer, sourceFile, declaringMethod) {
|
|
111
|
+
super(arkIRTransformer, sourceFile, declaringMethod);
|
|
112
|
+
// An object that records the corresponding processing functions of CXX ast nodes.
|
|
113
|
+
this.nodeTransformerFuncMap = {
|
|
114
|
+
[ArkCxxAstNode_1.astKind.ArraySubscriptExpr]: this.cxxElementAccessExpressionToValueAndStmts,
|
|
115
|
+
[ArkCxxAstNode_1.astKind.ArrayTypeTraitExpr]: this.arrayTypeTraitExprToValueAndStmts,
|
|
116
|
+
[ArkCxxAstNode_1.astKind.AtomicCallExpr]: this.cxxCallExpressionToValueAndStmts,
|
|
117
|
+
[ArkCxxAstNode_1.astKind.BinaryConditionalOperator]: this.cxxConditionalExpressionToValueAndStmts,
|
|
118
|
+
[ArkCxxAstNode_1.astKind.CXXRewrittenBinaryOperator]: this.cxxBinaryExpressionToValueAndStmts,
|
|
119
|
+
[ArkCxxAstNode_1.astKind.BinaryOperator]: this.cxxBinaryExpressionToValueAndStmts,
|
|
120
|
+
[ArkCxxAstNode_1.astKind.BindingDecl]: this.bindingNodeToValueAndStmts,
|
|
121
|
+
[ArkCxxAstNode_1.astKind.CallExpr]: this.cxxCallExpressionToValueAndStmts,
|
|
122
|
+
[ArkCxxAstNode_1.astKind.CharacterLiteral]: this.cxxLiteralNodeToValueAndStmts,
|
|
123
|
+
[ArkCxxAstNode_1.astKind.CompoundAssignOperator]: this.cxxCompoundAssignmentToValueAndStmts,
|
|
124
|
+
[ArkCxxAstNode_1.astKind.CompoundLiteralExpr]: this.cxxAggregateToValueAndStmts,
|
|
125
|
+
[ArkCxxAstNode_1.astKind.ConditionalOperator]: this.cxxConditionalExpressionToValueAndStmts,
|
|
126
|
+
[ArkCxxAstNode_1.astKind.ConstantExpr]: this.processInnerNodeToValueAndStmts,
|
|
127
|
+
[ArkCxxAstNode_1.astKind.CXXBindTemporaryExpr]: this.processInnerNodeToValueAndStmts,
|
|
128
|
+
[ArkCxxAstNode_1.astKind.CXXBoolLiteralExpr]: this.cxxLiteralNodeToValueAndStmts,
|
|
129
|
+
[ArkCxxAstNode_1.astKind.CXXConstCastExpr]: this.castExpressionToValueAndStmts,
|
|
130
|
+
[ArkCxxAstNode_1.astKind.CXXConstructExpr]: this.cxxConstructExprToValueAndStmts,
|
|
131
|
+
[ArkCxxAstNode_1.astKind.CXXCtorInitializer]: this.cxxCtorInitializerToValueAndStmts,
|
|
132
|
+
[ArkCxxAstNode_1.astKind.CXXDeleteExpr]: this.cxxDeleteExpressionToValueAndStmts,
|
|
133
|
+
[ArkCxxAstNode_1.astKind.CXXDynamicCastExpr]: this.castExpressionToValueAndStmts,
|
|
134
|
+
[ArkCxxAstNode_1.astKind.CXXFoldExpr]: this.cxxFoldExprToValueAndStmts,
|
|
135
|
+
[ArkCxxAstNode_1.astKind.CXXFunctionalCastExpr]: this.castExpressionToValueAndStmts,
|
|
136
|
+
[ArkCxxAstNode_1.astKind.CXXMemberCallExpr]: this.cxxMemberCallExpressionToValueAndStmts,
|
|
137
|
+
[ArkCxxAstNode_1.astKind.CXXNewExpr]: this.cxxNewExpressionToValueAndStmts,
|
|
138
|
+
[ArkCxxAstNode_1.astKind.CXXNoexceptExpr]: this.cxxNoexceptExprToValueAndStmts,
|
|
139
|
+
[ArkCxxAstNode_1.astKind.CXXNullPtrLiteralExpr]: this.cxxLiteralNodeToValueAndStmts,
|
|
140
|
+
[ArkCxxAstNode_1.astKind.CXXOperatorCallExpr]: this.cxxOperatorExpressionToValueAndStmts,
|
|
141
|
+
[ArkCxxAstNode_1.astKind.CXXReinterpretCastExpr]: this.castExpressionToValueAndStmts,
|
|
142
|
+
[ArkCxxAstNode_1.astKind.CXXScalarValueInitExpr]: this.cxxScalarValueInitToValueAndStmts,
|
|
143
|
+
[ArkCxxAstNode_1.astKind.CXXStdInitializerListExpr]: this.processInnerNodeToValueAndStmts,
|
|
144
|
+
[ArkCxxAstNode_1.astKind.CXXStaticCastExpr]: this.castExpressionToValueAndStmts,
|
|
145
|
+
[ArkCxxAstNode_1.astKind.CXXThisExpr]: this.cxxThisExpressionToValueAndStmts,
|
|
146
|
+
[ArkCxxAstNode_1.astKind.CXXTypeidExpr]: this.cxxTypeidExprToValueAndStmts,
|
|
147
|
+
[ArkCxxAstNode_1.astKind.CStyleCastExpr]: this.castExpressionToValueAndStmts,
|
|
148
|
+
[ArkCxxAstNode_1.astKind.CXXTemporaryObjectExpr]: this.cxxTemporaryObjectExprToValueAndStmts,
|
|
149
|
+
[ArkCxxAstNode_1.astKind.DeclRefExpr]: this.declAndTypeRefToValueAndStmts,
|
|
150
|
+
[ArkCxxAstNode_1.astKind.DeclStmt]: this.declStmtToValueAndStmts,
|
|
151
|
+
[ArkCxxAstNode_1.astKind.DecompositionDecl]: this.bindingNodeToValueAndStmts,
|
|
152
|
+
[ArkCxxAstNode_1.astKind.ExprWithCleanups]: this.processInnerNodeToValueAndStmts,
|
|
153
|
+
[ArkCxxAstNode_1.astKind.FloatingLiteral]: this.cxxLiteralNodeToValueAndStmts,
|
|
154
|
+
[ArkCxxAstNode_1.astKind.ImplicitCastExpr]: this.implicitCastExprToValueAndStmts,
|
|
155
|
+
[ArkCxxAstNode_1.astKind.InitListExpr]: this.initListExprToValueAndStmts,
|
|
156
|
+
[ArkCxxAstNode_1.astKind.IntegerLiteral]: this.cxxLiteralNodeToValueAndStmts,
|
|
157
|
+
[ArkCxxAstNode_1.astKind.LambdaExpr]: this.cxxCallableNodeToValueAndStmts,
|
|
158
|
+
[ArkCxxAstNode_1.astKind.MaterializeTemporaryExpr]: this.materializeTemporaryExprToValueAndStmts,
|
|
159
|
+
[ArkCxxAstNode_1.astKind.MemberExpr]: this.memberExpressionToValueAndStmts,
|
|
160
|
+
[ArkCxxAstNode_1.astKind.MemberRef]: this.memberExpressionToValueAndStmts,
|
|
161
|
+
[ArkCxxAstNode_1.astKind.NamespaceRef]: this.cxxNamespaceRefToValueAndStmts,
|
|
162
|
+
[ArkCxxAstNode_1.astKind.ParenExpr]: this.processInnerNodeToValueAndStmts,
|
|
163
|
+
[ArkCxxAstNode_1.astKind.ParenListExpr]: this.processInnerNodeToValueAndStmts,
|
|
164
|
+
[ArkCxxAstNode_1.astKind.RecoveryExpr]: this.RecoverExpressionToValueAndStmts,
|
|
165
|
+
[ArkCxxAstNode_1.astKind.StringLiteral]: this.cxxLiteralNodeToValueAndStmts,
|
|
166
|
+
[ArkCxxAstNode_1.astKind.TypeRef]: this.declAndTypeRefToValueAndStmts,
|
|
167
|
+
[ArkCxxAstNode_1.astKind.UnaryExprOrTypeTraitExpr]: this.unaryExprToValueAndStmts,
|
|
168
|
+
[ArkCxxAstNode_1.astKind.UnaryOperator]: this.unaryOperatorToValueAndStmts,
|
|
169
|
+
[ArkCxxAstNode_1.astKind.UnexposedExpr]: this.processInnerNodeToValueAndStmts,
|
|
170
|
+
[ArkCxxAstNode_1.astKind.UnresolvedLookupExpr]: this.declAndTypeRefToValueAndStmts,
|
|
171
|
+
[ArkCxxAstNode_1.astKind.UserDefinedLiteral]: this.userDefinedLiteralToValueAndStmts,
|
|
172
|
+
[ArkCxxAstNode_1.astKind.VarDecl]: this.cxxVariableDeclarationToValueAndStmts,
|
|
173
|
+
};
|
|
174
|
+
this.ArkCxxIRTransformer = arkIRTransformer;
|
|
175
|
+
this.cxxSourceFile = sourceFile;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
*Convert C++AST nodes into a combination of values and statements
|
|
179
|
+
*@ param node - C++AST node to be converted
|
|
180
|
+
*@ returns Objects containing converted values and related statements
|
|
181
|
+
*/
|
|
182
|
+
cxxNodeToValueAndStmts(node) {
|
|
183
|
+
if (node === undefined) {
|
|
184
|
+
return this.undefinedToValueAndStmts();
|
|
185
|
+
}
|
|
186
|
+
const nodeKind = node.kind;
|
|
187
|
+
if (nodeKind in this.nodeTransformerFuncMap) {
|
|
188
|
+
const valueAndStmts = this.nodeTransformerFuncMap[nodeKind].bind(this)(node);
|
|
189
|
+
if (valueAndStmts) {
|
|
190
|
+
return valueAndStmts;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return this.unprocessedNodeToValueAndStmts(node);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Convert an unprocessed C++AST node into a combination of values and statements
|
|
197
|
+
* @param aggregate - C++AST node to be converted
|
|
198
|
+
* @returns Objects containing converted values and related statements
|
|
199
|
+
* @throws Error if the node cannot be processed
|
|
200
|
+
* For example:
|
|
201
|
+
* struct Point q = (struct Point){.x = 5, .y = 8, .name = 'c'};
|
|
202
|
+
* int* arr = (int[5]){1, 2, 3, 4, 5};
|
|
203
|
+
* the right value is {},its kind is CompoundLiteralExpr or InitListExpr
|
|
204
|
+
*/
|
|
205
|
+
cxxAggregateToValueAndStmts(aggregate) {
|
|
206
|
+
var _a, _b;
|
|
207
|
+
const stmts = [];
|
|
208
|
+
const type = (0, builderUtils_1.cxxNode2Type)(aggregate, this.declaringMethod);
|
|
209
|
+
const typeName = (_b = (_a = aggregate.type) === null || _a === void 0 ? void 0 : _a.qualType) !== null && _b !== void 0 ? _b : 'unknown';
|
|
210
|
+
let classSignature;
|
|
211
|
+
if (!(type instanceof Type_1.ClassType)) {
|
|
212
|
+
classSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildClassSignatureFromClassName(typeName);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
classSignature = type.getClassSignature();
|
|
216
|
+
}
|
|
217
|
+
const list = aggregate.kind === ArkCxxAstNode_1.astKind.InitListExpr ? aggregate : aggregate.inner[aggregate.inner.length - 1];
|
|
218
|
+
let elements = [];
|
|
219
|
+
if (list.kind !== ArkCxxAstNode_1.astKind.InitListExpr) {
|
|
220
|
+
return this.unprocessedNodeToValueAndStmts(aggregate);
|
|
221
|
+
}
|
|
222
|
+
const aggregateExpr = new Expr_2.ArkAggregateExpr(elements, type);
|
|
223
|
+
const fullPosition = [Position_1.FullPosition.cxxBuildFromNode(aggregate, this.cxxSourceFile)];
|
|
224
|
+
let { value: temp, valueOriginalPositions: tempPositions, stmts: exprStmts, } = this.ArkCxxIRTransformer.generateAssignStmtForValue(aggregateExpr, fullPosition);
|
|
225
|
+
for (let i = 0; i < list.inner.length; i++) {
|
|
226
|
+
if (list.inner[i].kind === ArkCxxAstNode_1.astKind.DesignatedInitExpr) {
|
|
227
|
+
// Because the syntax tree does not have fields representing field information,
|
|
228
|
+
// regular matching is used to preserve the information.
|
|
229
|
+
// If there are any changes to the syntax tree, optimization can be made here
|
|
230
|
+
const dotIndex = list.inner[i].code.indexOf('.');
|
|
231
|
+
const equalsIndex = list.inner[i].code.indexOf('=');
|
|
232
|
+
const field = list.inner[i].code.substring(dotIndex + 1, equalsIndex).trim();
|
|
233
|
+
const type = (0, builderUtils_1.cxxNode2Type)(list.inner[i].inner[0], this.declaringMethod);
|
|
234
|
+
const fieldSignature = new ArkSignature_1.FieldSignature(field, classSignature, type, false);
|
|
235
|
+
const init = new Ref_2.ArkCxxInstanceFieldRef(temp, false, fieldSignature);
|
|
236
|
+
const valueAndStmts = this.cxxNodeToValueAndStmts(list.inner[i].inner[0]);
|
|
237
|
+
const designator = valueAndStmts.value;
|
|
238
|
+
stmts.push(...valueAndStmts.stmts);
|
|
239
|
+
const designatedInitExpr = new Expr_2.ArkDesignatedInitExpr(init, designator);
|
|
240
|
+
elements.push(designatedInitExpr);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
const valueAndStmts = this.cxxNodeToValueAndStmts(list.inner[i]);
|
|
244
|
+
elements.push(valueAndStmts.value);
|
|
245
|
+
stmts.push(...valueAndStmts.stmts);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
stmts.push(...exprStmts);
|
|
249
|
+
if (typeName === 'napi_property_descriptor') {
|
|
250
|
+
(0, ModelUtils_2.setTs2CxxFuncMapOfClass)(elements, false, this.declaringMethod);
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
value: temp,
|
|
254
|
+
valueOriginalPositions: tempPositions,
|
|
255
|
+
stmts: stmts,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
cxxThisExpressionToValueAndStmts(thisExpression) {
|
|
259
|
+
return {
|
|
260
|
+
value: this.getThisLocal(),
|
|
261
|
+
valueOriginalPositions: [Position_1.FullPosition.cxxBuildFromNode(thisExpression, this.cxxSourceFile)],
|
|
262
|
+
stmts: [],
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// Judge whether the current node is related to the lambda function of CPP
|
|
266
|
+
isNodeRelatedToCXXLambdaFunc(node) {
|
|
267
|
+
var _a, _b, _c, _d;
|
|
268
|
+
return ((_b = (_a = node.type) === null || _a === void 0 ? void 0 : _a.qualType) === null || _b === void 0 ? void 0 : _b.startsWith('(lambda at')) || ((_d = (_c = node.inner) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.kind) === ArkCxxAstNode_1.astKind.LambdaExpr;
|
|
269
|
+
}
|
|
270
|
+
isNodeRelatedToImplicitNode(node) {
|
|
271
|
+
var _a, _b;
|
|
272
|
+
if (node.inner) {
|
|
273
|
+
return (((_b = (_a = node.inner) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.kind) === ArkCxxAstNode_1.astKind.ImplicitCastExpr && (node.name === '__tree_const_iterator'));
|
|
274
|
+
}
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
// Judge whether the child nodes of the current node are materializing temporary variables
|
|
278
|
+
isNodeRelatedToMaterializeTemporaryExpr(node) {
|
|
279
|
+
var _a, _b;
|
|
280
|
+
return ((_b = (_a = node.inner) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.kind) === ArkCxxAstNode_1.astKind.MaterializeTemporaryExpr;
|
|
281
|
+
}
|
|
282
|
+
// Check if the child nodes of the current node are member function calls
|
|
283
|
+
isNodeRelatedToCXXMember(node) {
|
|
284
|
+
var _a, _b;
|
|
285
|
+
return ((((_b = (_a = node.inner) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.kind) === ArkCxxAstNode_1.astKind.CXXMemberCallExpr) ||
|
|
286
|
+
(node.inner[0].kind === ArkCxxAstNode_1.astKind.ImplicitCastExpr && node.inner[0].inner[0] && node.inner[0].inner[0].kind === ArkCxxAstNode_1.astKind.CXXMemberCallExpr));
|
|
287
|
+
}
|
|
288
|
+
// Construction of std::pair type
|
|
289
|
+
isPairConstructExpr(node) {
|
|
290
|
+
return node.type.qualType.includes('std::pair');
|
|
291
|
+
}
|
|
292
|
+
// Multi-layer std::pair construction
|
|
293
|
+
isNodeRelatedToTemporary(node) {
|
|
294
|
+
var _a, _b;
|
|
295
|
+
return ((_b = (_a = node.inner) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.kind) === ArkCxxAstNode_1.astKind.CXXBindTemporaryExpr && node.code === node.inner[0].code;
|
|
296
|
+
}
|
|
297
|
+
// Expressions that are not new statements (excluding constructors as parameters)
|
|
298
|
+
isNotNewExpression(newExpression) {
|
|
299
|
+
const firstChildKind = newExpression.inner.length > 0 ? newExpression.inner[0].kind : undefined;
|
|
300
|
+
if (!firstChildKind) {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
const targetKinds = [
|
|
304
|
+
ArkCxxAstNode_1.astKind.IntegerLiteral,
|
|
305
|
+
ArkCxxAstNode_1.astKind.InitListExpr,
|
|
306
|
+
ArkCxxAstNode_1.astKind.CompoundLiteralExpr,
|
|
307
|
+
ArkCxxAstNode_1.astKind.CXXOperatorCallExpr,
|
|
308
|
+
ArkCxxAstNode_1.astKind.BinaryOperator
|
|
309
|
+
];
|
|
310
|
+
return (targetKinds.includes(firstChildKind) ||
|
|
311
|
+
(firstChildKind === ArkCxxAstNode_1.astKind.ImplicitCastExpr && !newExpression.inner[0].code.includes('(')));
|
|
312
|
+
}
|
|
313
|
+
isNodeRelatedToCXXFuncCast(node) {
|
|
314
|
+
var _a;
|
|
315
|
+
return ((_a = node.inner[0]) === null || _a === void 0 ? void 0 : _a.kind) === 'CXXFunctionalCastExpr';
|
|
316
|
+
}
|
|
317
|
+
undefinedToValueAndStmts() {
|
|
318
|
+
var _a, _b;
|
|
319
|
+
logger.warn('ArkValueTransformer-Cpp NodeToValueAndStmts: node is undefined. Method signature is : ', (_b = (_a = this.declaringMethod) === null || _a === void 0 ? void 0 : _a.getSignature()) === null || _b === void 0 ? void 0 : _b.toString());
|
|
320
|
+
return {
|
|
321
|
+
value: new Local_1.Local('undefined'),
|
|
322
|
+
valueOriginalPositions: [new Position_1.FullPosition(0, 0, 0, 0)],
|
|
323
|
+
stmts: [],
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
unprocessedNodeToValueAndStmts(node) {
|
|
327
|
+
logger.warn(`ArkValueTransformer-cxxNodeToValueAndStmts: node '${node.kind}' is not specially processed.`);
|
|
328
|
+
return {
|
|
329
|
+
value: new Local_1.Local(node.code),
|
|
330
|
+
valueOriginalPositions: [Position_1.FullPosition.cxxBuildFromNode(node, this.cxxSourceFile)],
|
|
331
|
+
stmts: [],
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
cxxNamespaceRefToValueAndStmts(node) {
|
|
335
|
+
return {
|
|
336
|
+
value: new Local_1.Local(node.code),
|
|
337
|
+
valueOriginalPositions: [Position_1.FullPosition.cxxBuildFromNode(node, this.cxxSourceFile)],
|
|
338
|
+
stmts: [],
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
cxxTemporaryObjectExprToValueAndStmts(node) {
|
|
342
|
+
var _a, _b;
|
|
343
|
+
// if case: return Vector(x + other.x, y + other.y); ==> In the C++17 standard, a temporary object is no longer created in the return statement,
|
|
344
|
+
// instead, the object is directly constructed at the return value location. Therefore, it is processed here as a ConstructExpr.
|
|
345
|
+
const parentNode = (_a = node.getParent) === null || _a === void 0 ? void 0 : _a.call(node, false);
|
|
346
|
+
// case: Vector{1,2,3} Implicit call to destructor
|
|
347
|
+
if (((_b = parentNode === null || parentNode === void 0 ? void 0 : parentNode.dtor) === null || _b === void 0 ? void 0 : _b.kind) === ArkCxxAstNode_1.astKind.CXXDestructorDecl && node.inner.length > 0) {
|
|
348
|
+
return this.cxxConstructExprToValueAndStmts(node.inner[0]);
|
|
349
|
+
}
|
|
350
|
+
if (!parentNode || parentNode.kind !== ArkCxxAstNode_1.astKind.ExprWithCleanups && parentNode.kind !== ArkCxxAstNode_1.astKind.ReturnStmt) {
|
|
351
|
+
return this.unprocessedNodeToValueAndStmts(node);
|
|
352
|
+
}
|
|
353
|
+
return this.cxxConstructExprToValueAndStmts(node);
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
*Convert the C++construction expression node into a combination of values and statements.
|
|
357
|
+
* The main scenarios are structure and class construction, STL data structure object construction, and thread object construction
|
|
358
|
+
*@ param node - C++AST node, representing the construction expression
|
|
359
|
+
*@ returns ValueAndStmts object, including converted values and related statements
|
|
360
|
+
*/
|
|
361
|
+
cxxConstructExprToValueAndStmts(node) {
|
|
362
|
+
var _a, _b;
|
|
363
|
+
if (!this.isPairConstructExpr(node) &&
|
|
364
|
+
(this.isNodeRelatedToCXXLambdaFunc(node) ||
|
|
365
|
+
(this.isNodeRelatedToMaterializeTemporaryExpr(node) &&
|
|
366
|
+
((0, builderUtils_1.isCxxBasicString)((_a = node.type.desugaredQualType) !== null && _a !== void 0 ? _a : ''))) ||
|
|
367
|
+
this.isNodeRelatedToImplicitNode(node)) && ((_b = node.inner) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
368
|
+
return this.cxxNodeToValueAndStmts(node.inner[0]);
|
|
369
|
+
}
|
|
370
|
+
return this.cxxNewExpressionToValueAndStmts(node);
|
|
371
|
+
}
|
|
372
|
+
bindingNodeToValueAndStmts(node, yieldValue) {
|
|
373
|
+
var _a;
|
|
374
|
+
const length = (_a = node.inner) === null || _a === void 0 ? void 0 : _a.length;
|
|
375
|
+
if (length <= 0) {
|
|
376
|
+
return this.unprocessedNodeToValueAndStmts(node);
|
|
377
|
+
}
|
|
378
|
+
const stmts = [];
|
|
379
|
+
let objectValue;
|
|
380
|
+
let valueOriginalPositions;
|
|
381
|
+
let innerStmts;
|
|
382
|
+
if (yieldValue !== undefined) {
|
|
383
|
+
// If yieldValue exists, use it as the objectValue
|
|
384
|
+
objectValue = yieldValue;
|
|
385
|
+
valueOriginalPositions = [Position_1.FullPosition.cxxBuildFromNode(node, this.cxxSourceFile)];
|
|
386
|
+
innerStmts = [];
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
// If yieldValue does not exist, obtain it by recursively calling cxxNodeToValueAndSTms
|
|
390
|
+
const result = this.cxxNodeToValueAndStmts(node.inner[0]);
|
|
391
|
+
valueOriginalPositions = result.valueOriginalPositions;
|
|
392
|
+
innerStmts = result.stmts;
|
|
393
|
+
const tempVas = this.ArkCxxIRTransformer.generateAssignStmtForValue(result.value, valueOriginalPositions);
|
|
394
|
+
innerStmts.push(...tempVas.stmts);
|
|
395
|
+
objectValue = tempVas.value;
|
|
396
|
+
}
|
|
397
|
+
stmts.push(...innerStmts);
|
|
398
|
+
let index = 0;
|
|
399
|
+
for (let i = 0; i < length; i++) {
|
|
400
|
+
if (node.inner[i].kind !== ArkCxxAstNode_1.astKind.BindingDecl) {
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
const leftValueAndStmts = this.cxxIdentifierToValueAndStmts(node.inner[i]);
|
|
404
|
+
const indexValue = ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(index++);
|
|
405
|
+
const arrayRef = new Ref_1.ArkArrayRef(objectValue, indexValue);
|
|
406
|
+
const assignStmt = new Stmt_1.ArkAssignStmt(leftValueAndStmts.value, arrayRef);
|
|
407
|
+
stmts.push(assignStmt);
|
|
408
|
+
valueOriginalPositions = [Position_1.FullPosition.cxxBuildFromNode(node.inner[i], this.cxxSourceFile)];
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
value: objectValue,
|
|
412
|
+
valueOriginalPositions: valueOriginalPositions,
|
|
413
|
+
stmts: stmts,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
processInnerNodeToValueAndStmts(node) {
|
|
417
|
+
var _a, _b;
|
|
418
|
+
if (((_a = node.inner) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
419
|
+
// When a node is an implicit node, the actual node is the last internal node
|
|
420
|
+
return this.cxxNodeToValueAndStmts(node.inner[((_b = node.inner) === null || _b === void 0 ? void 0 : _b.length) - 1]);
|
|
421
|
+
}
|
|
422
|
+
return this.unprocessedNodeToValueAndStmts(node);
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
*Converts an implicit conversion expression node to a combination of values and statements
|
|
426
|
+
*@ param node - C++AST node, representing implicit type conversion expression
|
|
427
|
+
*@ returns ValueAndStmts object, including converted values and related statements
|
|
428
|
+
*/
|
|
429
|
+
implicitCastExprToValueAndStmts(node) {
|
|
430
|
+
var _a;
|
|
431
|
+
if (((_a = node.inner) === null || _a === void 0 ? void 0 : _a.length) === 1) {
|
|
432
|
+
return this.cxxNodeToValueAndStmts(node.inner[0]);
|
|
433
|
+
}
|
|
434
|
+
node.kind = 'DeclRefExpr';
|
|
435
|
+
node.name = node.code;
|
|
436
|
+
return this.cxxNodeToValueAndStmts(node);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
*Convert declaration and type reference nodes to collections of values and statements
|
|
440
|
+
*@ param node - C++AST node
|
|
441
|
+
*@ returns ValueAndStmts object, including converted values and related statements
|
|
442
|
+
*/
|
|
443
|
+
declAndTypeRefToValueAndStmts(node) {
|
|
444
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
445
|
+
if (((_a = node.inner) === null || _a === void 0 ? void 0 : _a.length) > 0 && !node.type) {
|
|
446
|
+
return this.cxxNodeToValueAndStmts(node.inner[0]);
|
|
447
|
+
}
|
|
448
|
+
// Handle the scenario: using Color::RED; Color c = RED;
|
|
449
|
+
if (((_b = node.referencedDecl) === null || _b === void 0 ? void 0 : _b.kind) === ArkCxxAstNode_1.astKind.EnumConstantDecl && node.inner.length === 0) {
|
|
450
|
+
const typeRefNode = {
|
|
451
|
+
kind: 'TypeRef',
|
|
452
|
+
name: node.referencedDecl.name,
|
|
453
|
+
code: node.referencedDecl.name,
|
|
454
|
+
inner: [],
|
|
455
|
+
type: node.referencedDecl.type,
|
|
456
|
+
};
|
|
457
|
+
node.inner.push(typeRefNode);
|
|
458
|
+
return this.staticMemberExprToValueAndStmts(node);
|
|
459
|
+
}
|
|
460
|
+
// when node.referencedDecl?.kind === astKind.NonTypeTemplateParmDecl ,this value is a const expr
|
|
461
|
+
if (((_c = node.referencedDecl) === null || _c === void 0 ? void 0 : _c.kind) === ArkCxxAstNode_1.astKind.NonTypeTemplateParmDecl) {
|
|
462
|
+
return {
|
|
463
|
+
value: ValueUtil_1.CxxValueUtil.createCompileConst(node.name, (0, builderUtils_1.cxxNode2Type)(node, this.declaringMethod)),
|
|
464
|
+
valueOriginalPositions: [],
|
|
465
|
+
stmts: [],
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
// Handle the invocation of static members of a class, such as A::a
|
|
469
|
+
if (((_d = node.code) === null || _d === void 0 ? void 0 : _d.includes('::')) && node.inner.length > 0 &&
|
|
470
|
+
(((_e = node.inner[0]) === null || _e === void 0 ? void 0 : _e.kind) === ArkCxxAstNode_1.astKind.TypeRef || ((_f = node.inner[0]) === null || _f === void 0 ? void 0 : _f.kind) === ArkCxxAstNode_1.astKind.NamespaceRef && ((_g = node.inner[0]) === null || _g === void 0 ? void 0 : _g.name) !== Builtin_2.BuiltinCxx.CXXSTD)) {
|
|
471
|
+
return this.staticMemberExprToValueAndStmts(node);
|
|
472
|
+
}
|
|
473
|
+
return this.cxxIdentifierToValueAndStmts(node);
|
|
474
|
+
}
|
|
475
|
+
staticMemberExprToValueAndStmts(declRefExpr) {
|
|
476
|
+
declRefExpr.kind = ArkCxxAstNode_1.astKind.MemberExpr; // Replace the type with "member invocation"
|
|
477
|
+
return this.memberExpressionToValueAndStmts(declRefExpr);
|
|
478
|
+
}
|
|
479
|
+
materializeTemporaryExprToValueAndStmts(node) {
|
|
480
|
+
if (this.isNotNewExpression(node) ||
|
|
481
|
+
this.isNodeRelatedToCXXLambdaFunc(node) ||
|
|
482
|
+
this.isNodeRelatedToCXXMember(node) ||
|
|
483
|
+
this.isNodeRelatedToTemporary(node) ||
|
|
484
|
+
this.isNodeRelatedToCXXFuncCast(node)) {
|
|
485
|
+
return this.cxxNodeToValueAndStmts(node.inner[0]);
|
|
486
|
+
}
|
|
487
|
+
return this.cxxNewExpressionToValueAndStmts(node);
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
*Initialize a list expression into a collection of values and statements
|
|
491
|
+
*@ param node - C++abstract syntax tree node
|
|
492
|
+
*@ returns ValueAndStmts object, including converted values and related statements
|
|
493
|
+
*/
|
|
494
|
+
initListExprToValueAndStmts(node) {
|
|
495
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
496
|
+
if ((((_b = (_a = node.type) === null || _a === void 0 ? void 0 : _a.qualType) === null || _b === void 0 ? void 0 : _b.includes('[')) && node.type.qualType.includes(']')) || node.type.qualType === 'void') {
|
|
497
|
+
return this.cxxArrayLiteralExpressionToValueAndStmts(node);
|
|
498
|
+
}
|
|
499
|
+
let pNode = (_e = ((_c = node.parent) !== null && _c !== void 0 ? _c : (_d = node.getParent) === null || _d === void 0 ? void 0 : _d.call(node, true))) !== null && _e !== void 0 ? _e : null;
|
|
500
|
+
if (pNode && ((_f = pNode === null || pNode === void 0 ? void 0 : pNode.inner) === null || _f === void 0 ? void 0 : _f.length) > 0 &&
|
|
501
|
+
(((_g = pNode.inner[0]) === null || _g === void 0 ? void 0 : _g.kind) === ArkCxxAstNode_1.astKind.TypeRef || !node.type.qualType.includes('[') || (0, builderUtils_1.cxxNode2Type)(node, this.declaringMethod) instanceof Type_1.ClassType)) {
|
|
502
|
+
try {
|
|
503
|
+
return this.cxxAggregateToValueAndStmts(node);
|
|
504
|
+
}
|
|
505
|
+
catch (error) {
|
|
506
|
+
logger.error(`Error in cxxAggregateToValueAndStmts.`);
|
|
507
|
+
return this.unprocessedNodeToValueAndStmts(node);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return this.cxxArrayLiteralExpressionToValueAndStmts(node);
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
*Convert the unary operator node into a combination of values and statements
|
|
514
|
+
*@ param node - C++AST node, representing unary operator expression
|
|
515
|
+
*@ returns ValueAndStmts object, including converted values and related statements
|
|
516
|
+
*/
|
|
517
|
+
unaryOperatorToValueAndStmts(node) {
|
|
518
|
+
if (node.isPostfix) {
|
|
519
|
+
return this.cxxPostfixUnaryExpressionToValueAndStmts(node);
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
return this.cxxPrefixUnaryExpressionToValueAndStmts(node);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
// expression with either a type or (unevaluated) expression operand.
|
|
526
|
+
// Used for sizeof/alignof (C99 6.5.3.4) and vec_step (OpenCL 1.1 6.11.12).
|
|
527
|
+
unaryExprToValueAndStmts(unaryExprNode) {
|
|
528
|
+
var _a;
|
|
529
|
+
const stmts = [];
|
|
530
|
+
let unaryValue;
|
|
531
|
+
const operatorString = (_a = unaryExprNode.name) !== null && _a !== void 0 ? _a : '';
|
|
532
|
+
let operator;
|
|
533
|
+
switch (operatorString) {
|
|
534
|
+
case Expr_2.Operator.sizeof:
|
|
535
|
+
operator = Expr_2.Operator.sizeof;
|
|
536
|
+
break;
|
|
537
|
+
case Expr_2.Operator.alignof:
|
|
538
|
+
operator = Expr_2.Operator.alignof;
|
|
539
|
+
break;
|
|
540
|
+
default:
|
|
541
|
+
operator = Expr_2.Operator.Unknown;
|
|
542
|
+
logger.warn(`Unsupported unary operator: ${operatorString}`);
|
|
543
|
+
}
|
|
544
|
+
let operpositions = [Position_1.FullPosition.cxxBuildFromNode(unaryExprNode, this.cxxSourceFile)];
|
|
545
|
+
if (unaryExprNode.inner.length > 0) {
|
|
546
|
+
let { value: innerValue, valueOriginalPositions: innerPositions, stmts: innerStmts } = this.cxxNodeToValueAndStmts(unaryExprNode.inner[0]);
|
|
547
|
+
unaryValue = innerValue;
|
|
548
|
+
stmts.push(...innerStmts);
|
|
549
|
+
operpositions.push(...innerPositions);
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
const typeNameMatch = unaryExprNode.code.match(/\(([^)]*)\)/);
|
|
553
|
+
const typeName = typeNameMatch ? typeNameMatch[1] : '';
|
|
554
|
+
unaryValue = (0, builderUtils_1.buildTypeFromPreStr)(typeName, unaryExprNode, this.declaringMethod);
|
|
555
|
+
}
|
|
556
|
+
const unaryExpr = new Expr_2.ArkCxxUnaryExpr(operator, unaryValue);
|
|
557
|
+
return {
|
|
558
|
+
value: unaryExpr,
|
|
559
|
+
valueOriginalPositions: operpositions,
|
|
560
|
+
stmts: stmts,
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
*Convert user-defined literals into sets of values and statements
|
|
565
|
+
*The syntax format of user-defined literals is: original value+suffix (for example: 123_km, "hello" _s, 'a' _s)
|
|
566
|
+
*
|
|
567
|
+
*@ param userDefinedLiteral - AST node of user-defined literal
|
|
568
|
+
*@ returns The ValueAndStmts object containing the converted value and related statements
|
|
569
|
+
*/
|
|
570
|
+
userDefinedLiteralToValueAndStmts(userDefinedLiteral) {
|
|
571
|
+
var _a;
|
|
572
|
+
// The syntax for user-defined literals is: raw value + suffix (e.g., 123_km, "hello"_s, 'a'_s)
|
|
573
|
+
if (((_a = userDefinedLiteral.inner) === null || _a === void 0 ? void 0 : _a.length) < 2) {
|
|
574
|
+
return this.unprocessedNodeToValueAndStmts(userDefinedLiteral);
|
|
575
|
+
}
|
|
576
|
+
const stmts = [];
|
|
577
|
+
const literalStr = this.getOverloadOpName(userDefinedLiteral).replace('operator""', '');
|
|
578
|
+
const argNode = userDefinedLiteral.inner[1];
|
|
579
|
+
argNode.code = argNode.code.replace(literalStr, ''); // Get the primitive value (e.g., 123, 'a')
|
|
580
|
+
return this.buildValueAndStmtsForMemberCall(stmts, userDefinedLiteral.inner[0], [argNode], userDefinedLiteral, undefined);
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
*Convert the C++constructor initialization list node to a collection of values and statements
|
|
584
|
+
* 1. C++uses the initialization list to initialize class member variables: Base (char pname): name (pname) {...}.
|
|
585
|
+
* The final effect is similar to this ->name=pname, which is also processed as an assignment here
|
|
586
|
+
* 2. using parent::parent, The constructor of the subclass calls the constructor inherited from the parent class
|
|
587
|
+
*@ param cxxCtorInitializer C++constructor initializes list nodes
|
|
588
|
+
*@ returns An object containing a collection of values and statements
|
|
589
|
+
*/
|
|
590
|
+
cxxCtorInitializerToValueAndStmts(cxxCtorInitializer) {
|
|
591
|
+
var _a, _b, _c, _d;
|
|
592
|
+
if (!cxxCtorInitializer.inner || cxxCtorInitializer.inner.length === 0) {
|
|
593
|
+
return this.unprocessedNodeToValueAndStmts(cxxCtorInitializer);
|
|
594
|
+
}
|
|
595
|
+
const firstInnerNode = cxxCtorInitializer.inner[0];
|
|
596
|
+
if (firstInnerNode.kind === ArkCxxAstNode_1.astKind.CXXInheritedCtorInitExpr) {
|
|
597
|
+
// Processing of using parent:: parent
|
|
598
|
+
return this.cxxInheritedCtorInitExprToValueAndStmts(firstInnerNode);
|
|
599
|
+
}
|
|
600
|
+
else if (firstInnerNode.kind === ArkCxxAstNode_1.astKind.CXXConstructExpr && cxxCtorInitializer.baseInit) {
|
|
601
|
+
// Processing of case: Left(const char& name) : Base(name) // call base class constructor
|
|
602
|
+
return this.cxxSuperExpressionToValueAndStmts(firstInnerNode);
|
|
603
|
+
}
|
|
604
|
+
// If the kind of firstNode is CXXConstructExpr and firstNode does not correspond to a parent class initialization call,
|
|
605
|
+
// it is equivalent to directly assigning a value to the class member.
|
|
606
|
+
// For example, the constructor of class Circle in file 'tests/cppResources/exports/crossFileCase/include/myHeader.h'.
|
|
607
|
+
const assignRight = (firstInnerNode.kind === ArkCxxAstNode_1.astKind.CXXConstructExpr && firstInnerNode.inner.length > 0) ? firstInnerNode.inner[0] : firstInnerNode;
|
|
608
|
+
const CtorInit2ThisMemberExpr = {
|
|
609
|
+
kind: 'MemberExpr',
|
|
610
|
+
name: (_b = (_a = cxxCtorInitializer.anyInit) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : '',
|
|
611
|
+
inner: [
|
|
612
|
+
{
|
|
613
|
+
kind: 'CXXThisExpr',
|
|
614
|
+
},
|
|
615
|
+
],
|
|
616
|
+
type: (_d = (_c = cxxCtorInitializer.anyInit) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : '',
|
|
617
|
+
};
|
|
618
|
+
const initType = (0, builderUtils_1.cxxNode2Type)(CtorInit2ThisMemberExpr, undefined);
|
|
619
|
+
return this.cxxAssignmentToValueAndStmts(CtorInit2ThisMemberExpr, assignRight, false, false, initType, true);
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
*Convert the C++inheritance constructor initialization expression to a collection of values and statements
|
|
623
|
+
* Using parent:: parent==>The constructor of the sub——class calls the constructor inherited from the parent
|
|
624
|
+
* class==>The same as calling the constructor of the parent class directly
|
|
625
|
+
*@ param cxxInheritedCtorInitExpr - C++inheritance constructor initialization expression node
|
|
626
|
+
*@ returns The object containing the converted value and statement array
|
|
627
|
+
*/
|
|
628
|
+
cxxInheritedCtorInitExprToValueAndStmts(cxxInheritedCtorInitExpr) {
|
|
629
|
+
var _a;
|
|
630
|
+
cxxInheritedCtorInitExpr.code = `using ${cxxInheritedCtorInitExpr.code}::${cxxInheritedCtorInitExpr.code}`;
|
|
631
|
+
const cls = this.declaringMethod.getDeclaringArkClass();
|
|
632
|
+
const clsInitMtd = cls.getInstanceInitMethod();
|
|
633
|
+
if (!clsInitMtd) {
|
|
634
|
+
return this.unprocessedNodeToValueAndStmts(cxxInheritedCtorInitExpr);
|
|
635
|
+
}
|
|
636
|
+
const superClass = cls.getHeritageClass(cxxInheritedCtorInitExpr.type.qualType);
|
|
637
|
+
if (!superClass) {
|
|
638
|
+
return this.unprocessedNodeToValueAndStmts(cxxInheritedCtorInitExpr);
|
|
639
|
+
}
|
|
640
|
+
(0, ArkMethodBuilder_1.buildDefaultConstructor)(superClass);
|
|
641
|
+
const superConstructor = superClass.getMethodWithName(TSConst_1.CONSTRUCTOR_NAME);
|
|
642
|
+
if (!superConstructor) {
|
|
643
|
+
return this.unprocessedNodeToValueAndStmts(cxxInheritedCtorInitExpr);
|
|
644
|
+
}
|
|
645
|
+
let base = (_a = clsInitMtd.getBody()) === null || _a === void 0 ? void 0 : _a.getLocals().get(TSConst_1.THIS_NAME);
|
|
646
|
+
if (base === undefined) {
|
|
647
|
+
return this.unprocessedNodeToValueAndStmts(cxxInheritedCtorInitExpr);
|
|
648
|
+
}
|
|
649
|
+
const params = this.declaringMethod.getParameters();
|
|
650
|
+
const argValues = [];
|
|
651
|
+
params.forEach(param => {
|
|
652
|
+
argValues.push(this.getOrCreateLocal(param.getName()));
|
|
653
|
+
});
|
|
654
|
+
const newSuperInvokeExpr = new Expr_1.ArkInstanceInvokeExpr(base, superConstructor.getSignature(), argValues);
|
|
655
|
+
return {
|
|
656
|
+
value: newSuperInvokeExpr,
|
|
657
|
+
valueOriginalPositions: [Position_1.FullPosition.cxxBuildFromNode(cxxInheritedCtorInitExpr, this.cxxSourceFile)],
|
|
658
|
+
stmts: [],
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
*Convert super expression in C++to IR
|
|
663
|
+
* C++subclasses call the parent class constructor for initialization,
|
|
664
|
+
* similar to ts super (xx). For example, Left (const char&name, int power): Base (name) {...}
|
|
665
|
+
*@ param cxxConstructExpr C++construction expression node
|
|
666
|
+
*@ returns The ValueAndStmts object containing the converted value and related statements
|
|
667
|
+
*/
|
|
668
|
+
cxxSuperExpressionToValueAndStmts(cxxConstructExpr) {
|
|
669
|
+
var _a, _b;
|
|
670
|
+
const cls = this.declaringMethod.getDeclaringArkClass();
|
|
671
|
+
if (!cls) {
|
|
672
|
+
return this.cxxNewExpressionToValueAndStmts(cxxConstructExpr);
|
|
673
|
+
}
|
|
674
|
+
const clsInitMtd = cls.getInstanceInitMethod();
|
|
675
|
+
if (!clsInitMtd) {
|
|
676
|
+
return this.cxxNewExpressionToValueAndStmts(cxxConstructExpr);
|
|
677
|
+
}
|
|
678
|
+
const stmts = [];
|
|
679
|
+
const { args: argValues } = this.cxxParseArguments(stmts, cxxConstructExpr.inner);
|
|
680
|
+
const superClass = cls.getHeritageClass((_a = cxxConstructExpr.type.qualType) !== null && _a !== void 0 ? _a : '');
|
|
681
|
+
if (!superClass) {
|
|
682
|
+
return this.cxxNewExpressionToValueAndStmts(cxxConstructExpr);
|
|
683
|
+
}
|
|
684
|
+
(0, ArkMethodBuilder_1.buildDefaultConstructor)(superClass);
|
|
685
|
+
const superConstructor = superClass.getMethodWithName(TSConst_1.CONSTRUCTOR_NAME);
|
|
686
|
+
if (superConstructor !== null) {
|
|
687
|
+
let base = (_b = clsInitMtd.getBody()) === null || _b === void 0 ? void 0 : _b.getLocals().get(TSConst_1.THIS_NAME);
|
|
688
|
+
if (base === undefined) {
|
|
689
|
+
return this.cxxNewExpressionToValueAndStmts(cxxConstructExpr);
|
|
690
|
+
}
|
|
691
|
+
const newSuperInvokeExpr = new Expr_1.ArkInstanceInvokeExpr(base, superConstructor.getSignature(), argValues);
|
|
692
|
+
return {
|
|
693
|
+
value: newSuperInvokeExpr,
|
|
694
|
+
valueOriginalPositions: [Position_1.FullPosition.cxxBuildFromNode(cxxConstructExpr, this.cxxSourceFile)],
|
|
695
|
+
stmts: [],
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
return this.cxxNewExpressionToValueAndStmts(cxxConstructExpr);
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
*Convert array type characteristic expression to IR
|
|
702
|
+
* ArrayTypeTraitExpr is processed by function call
|
|
703
|
+
*@ param ArrayTypeTraitExpr - C++AST node, representing array type characteristic expression
|
|
704
|
+
*@ returns ValueAndStmts object, including converted values and related statements
|
|
705
|
+
*/
|
|
706
|
+
arrayTypeTraitExprToValueAndStmts(ArrayTypeTraitExpr) {
|
|
707
|
+
const stmts = [];
|
|
708
|
+
let dimensionSizes = [];
|
|
709
|
+
let op = null;
|
|
710
|
+
for (let i = 0; i < ArrayTypeTraitExpr.inner.length; i++) {
|
|
711
|
+
if (ArrayTypeTraitExpr.inner[i].kind === ArkCxxAstNode_1.astKind.IntegerLiteral) {
|
|
712
|
+
dimensionSizes.push(Number(ArrayTypeTraitExpr.inner[i].value));
|
|
713
|
+
}
|
|
714
|
+
else if (ArrayTypeTraitExpr.inner[i].kind === ArkCxxAstNode_1.astKind.DeclRefExpr) {
|
|
715
|
+
const innerValueAndStmts = this.cxxNodeToValueAndStmts(ArrayTypeTraitExpr.inner[i]);
|
|
716
|
+
op = innerValueAndStmts.value;
|
|
717
|
+
stmts.push(...innerValueAndStmts.stmts);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
const arrayRankExpr = new Expr_2.ArkArrayTypeTraitExpr(dimensionSizes, op);
|
|
721
|
+
return {
|
|
722
|
+
value: arrayRankExpr,
|
|
723
|
+
valueOriginalPositions: [Position_1.FullPosition.cxxBuildFromNode(ArrayTypeTraitExpr, this.cxxSourceFile)],
|
|
724
|
+
stmts: stmts,
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Convert C++typeid expression to IR, And CXXTypeidExpr is processed by function call.
|
|
729
|
+
*@ param CXXTypeidExpr - typeid expression node in C++AST
|
|
730
|
+
*@ returns Objects containing converted values and related statements
|
|
731
|
+
*/
|
|
732
|
+
cxxTypeidExprToValueAndStmts(CXXTypeidExpr) {
|
|
733
|
+
const stmts = [];
|
|
734
|
+
let typeValue;
|
|
735
|
+
// [1.typeid's inner.length is 0 or 2, then the type name is passed in; 2. std:: Type refers to the type in the namespace]==>
|
|
736
|
+
// Parameter function call to construct the string corresponding to the type into the parameter
|
|
737
|
+
if (CXXTypeidExpr.inner.length === 0) {
|
|
738
|
+
const innerType = (0, builderUtils_1.cxxNode2Type)(CXXTypeidExpr, undefined, undefined);
|
|
739
|
+
typeValue = new Local_1.Local(innerType.toString(), innerType);
|
|
740
|
+
}
|
|
741
|
+
else {
|
|
742
|
+
let innerValueAndStmts = this.cxxNodeToValueAndStmts(CXXTypeidExpr.inner[0]);
|
|
743
|
+
stmts.push(...innerValueAndStmts.stmts);
|
|
744
|
+
typeValue = innerValueAndStmts.value;
|
|
745
|
+
}
|
|
746
|
+
const typeIdExpr = new Expr_2.ArkTypeIdExpr(typeValue);
|
|
747
|
+
return {
|
|
748
|
+
value: typeIdExpr,
|
|
749
|
+
valueOriginalPositions: [Position_1.FullPosition.cxxBuildFromNode(CXXTypeidExpr, this.cxxSourceFile)],
|
|
750
|
+
stmts: stmts,
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
*Convert the noexcept expression of C++syntax tree to IR
|
|
755
|
+
*@ param CXXNoexceptExpr - AST node representing C++noexcept expression
|
|
756
|
+
*@ returns Objects containing converted values and related statements
|
|
757
|
+
*/
|
|
758
|
+
cxxNoexceptExprToValueAndStmts(CXXNoexceptExpr) {
|
|
759
|
+
const stmts = [];
|
|
760
|
+
let innerValueAndStmts = this.cxxNodeToValueAndStmts(CXXNoexceptExpr.inner[0]);
|
|
761
|
+
stmts.push(...innerValueAndStmts.stmts);
|
|
762
|
+
const noExpectExpr = new Expr_2.ArkNoExpectExpr(innerValueAndStmts.value);
|
|
763
|
+
return {
|
|
764
|
+
value: noExpectExpr,
|
|
765
|
+
valueOriginalPositions: [Position_1.FullPosition.cxxBuildFromNode(CXXNoexceptExpr, this.cxxSourceFile)],
|
|
766
|
+
stmts: stmts,
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
*Process the C++scalar value initialization expression and convert it to IR
|
|
771
|
+
*@ param CXXScalarValueInitExpr - C++abstract syntax tree node, representing scalar value initialization expression
|
|
772
|
+
*@ returns an object containing initialization values and related statements. If it cannot be processed, it returns null
|
|
773
|
+
*/
|
|
774
|
+
cxxScalarValueInitToValueAndStmts(CXXScalarValueInitExpr) {
|
|
775
|
+
const initType = CXXScalarValueInitExpr.type.qualType;
|
|
776
|
+
let constant = null;
|
|
777
|
+
switch (initType) {
|
|
778
|
+
case 'int':
|
|
779
|
+
constant = ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(parseFloat('0'));
|
|
780
|
+
break;
|
|
781
|
+
case 'float':
|
|
782
|
+
case 'double':
|
|
783
|
+
constant = ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(parseFloat('0.0'));
|
|
784
|
+
break;
|
|
785
|
+
case 'char':
|
|
786
|
+
constant = ValueUtil_1.CxxValueUtil.createStringConst('');
|
|
787
|
+
break;
|
|
788
|
+
default:
|
|
789
|
+
logger.warn(`The initType of ast node "CXXScalarValueInitExpr" is ${initType}, maybe it is not literalNode or is not processed`);
|
|
790
|
+
}
|
|
791
|
+
if (constant === null) {
|
|
792
|
+
return null;
|
|
793
|
+
}
|
|
794
|
+
return {
|
|
795
|
+
value: constant,
|
|
796
|
+
valueOriginalPositions: [Position_1.FullPosition.cxxBuildFromNode(CXXScalarValueInitExpr, this.cxxSourceFile)],
|
|
797
|
+
stmts: [],
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
*Convert C++delete expression to IR
|
|
802
|
+
*@ param deleteExpression - C++AST node, representing delete expression
|
|
803
|
+
*@ returns The object containing the converted value and statement array
|
|
804
|
+
*/
|
|
805
|
+
cxxDeleteExpressionToValueAndStmts(deleteExpression) {
|
|
806
|
+
const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts, } = this.cxxNodeToValueAndStmts(deleteExpression.inner[0]);
|
|
807
|
+
const isArray = deleteExpression.isArray;
|
|
808
|
+
const deleteExpr = isArray ? new Expr_2.ArkCxxDeleteArrayExpr(exprValue) : new Expr_1.ArkDeleteExpr(exprValue);
|
|
809
|
+
const deleteExprPosition = [Position_1.FullPosition.cxxBuildFromNode(deleteExpression, this.cxxSourceFile), ...exprPositions];
|
|
810
|
+
return { value: deleteExpr, valueOriginalPositions: deleteExprPosition, stmts: stmts };
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
*Convert C++type conversion expression to IR
|
|
814
|
+
*@ param castExpression C++AST node, representing type conversion expression
|
|
815
|
+
*@ returns ValueAndStmts object, including converted values, original location information and related statements
|
|
816
|
+
*/
|
|
817
|
+
castExpressionToValueAndStmts(castExpression) {
|
|
818
|
+
const stmts = [];
|
|
819
|
+
let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts, } = this.cxxNodeToValueAndStmts(castExpression.inner[castExpression.inner.length - 1]);
|
|
820
|
+
stmts.push(...exprStmts);
|
|
821
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(exprValue)) {
|
|
822
|
+
({
|
|
823
|
+
value: exprValue,
|
|
824
|
+
valueOriginalPositions: exprPositions,
|
|
825
|
+
stmts: exprStmts,
|
|
826
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(exprValue, exprPositions));
|
|
827
|
+
stmts.push(...exprStmts);
|
|
828
|
+
}
|
|
829
|
+
const castType = castExpression.kind;
|
|
830
|
+
const castExpr = new Expr_2.ArkCxxCastExpr(exprValue, (0, builderUtils_1.cxxNode2Type)(castExpression, this.declaringMethod), castType);
|
|
831
|
+
const castExprPosition = [Position_1.FullPosition.cxxBuildFromNode(castExpression, this.cxxSourceFile), ...exprPositions];
|
|
832
|
+
return { value: castExpr, valueOriginalPositions: castExprPosition, stmts: stmts };
|
|
833
|
+
}
|
|
834
|
+
cxxFoldExprToValueAndStmts(CXXFoldExpr) {
|
|
835
|
+
var _a;
|
|
836
|
+
const stmts = [];
|
|
837
|
+
let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts, } = this.cxxNodeToValueAndStmts(CXXFoldExpr.inner[CXXFoldExpr.inner.length - 1]);
|
|
838
|
+
stmts.push(...exprStmts);
|
|
839
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(exprValue)) {
|
|
840
|
+
({
|
|
841
|
+
value: exprValue,
|
|
842
|
+
valueOriginalPositions: exprPositions,
|
|
843
|
+
stmts: exprStmts,
|
|
844
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(exprValue, exprPositions));
|
|
845
|
+
stmts.push(...exprStmts);
|
|
846
|
+
}
|
|
847
|
+
const foldOp = (_a = CXXFoldExpr.op) !== null && _a !== void 0 ? _a : ' ';
|
|
848
|
+
const folderExpr = new Expr_2.ArkCxxFolderExpr(exprValue, foldOp);
|
|
849
|
+
const folderExprPosition = [Position_1.FullPosition.cxxBuildFromNode(CXXFoldExpr, this.cxxSourceFile), ...exprPositions];
|
|
850
|
+
return { value: folderExpr, valueOriginalPositions: folderExprPosition, stmts: stmts };
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
*Convert C++conditional expression to IR
|
|
854
|
+
*@ param conditionalExpression - C++AST node, representing conditional expression
|
|
855
|
+
*@ returns ValueAndStmts object, including converted values, original location information and related statements
|
|
856
|
+
*/
|
|
857
|
+
cxxConditionalExpressionToValueAndStmts(conditionalExpression) {
|
|
858
|
+
// Starting from 0 to access internal nodes
|
|
859
|
+
let InnerIdx = 0;
|
|
860
|
+
const stmts = [];
|
|
861
|
+
const currConditionalOperatorIndex = this.conditionalOperatorNo++;
|
|
862
|
+
// Peel off 'ImplicitCastExpr'
|
|
863
|
+
const conditionNode = conditionalExpression.inner[InnerIdx].kind === ArkCxxAstNode_1.astKind.ImplicitCastExpr ?
|
|
864
|
+
conditionalExpression.inner[InnerIdx].inner[0] : conditionalExpression.inner[InnerIdx];
|
|
865
|
+
let conditionExpr;
|
|
866
|
+
const context = { conditionExpr: conditionExpr };
|
|
867
|
+
const ifStmts = this.ArkCxxIRTransformer.cxxIfStatementToStmts(conditionNode, 0, context);
|
|
868
|
+
stmts.push(...ifStmts);
|
|
869
|
+
let isBooleanExpr = conditionNode.type.qualType === 'bool';
|
|
870
|
+
stmts.push(new ArkIRTransformer_2.DummyStmt(ArkIRTransformer_1.ArkCxxIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT + currConditionalOperatorIndex));
|
|
871
|
+
// inner[1] is a value whose expression is true
|
|
872
|
+
InnerIdx++;
|
|
873
|
+
let whenTrueValueAndStmts;
|
|
874
|
+
if (conditionalExpression.kind === ArkCxxAstNode_1.astKind.ConditionalOperator) {
|
|
875
|
+
whenTrueValueAndStmts = this.cxxNodeToValueAndStmts(conditionalExpression.inner[InnerIdx]);
|
|
876
|
+
// else kind is BinaryConditionalOperator,No need to parse the node again, the result of the judgment is its value
|
|
877
|
+
}
|
|
878
|
+
else {
|
|
879
|
+
whenTrueValueAndStmts = {
|
|
880
|
+
value: isBooleanExpr ? ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(1) : context.conditionExpr.getOp1(),
|
|
881
|
+
stmts: [],
|
|
882
|
+
valueOriginalPositions: [],
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
stmts.push(...whenTrueValueAndStmts.stmts);
|
|
886
|
+
const resultLocal = this.generateTempLocal();
|
|
887
|
+
const assignStmtWhenTrue = new Stmt_1.ArkAssignStmt(resultLocal, whenTrueValueAndStmts.value);
|
|
888
|
+
const resultLocalPosition = [whenTrueValueAndStmts.valueOriginalPositions[0]];
|
|
889
|
+
assignStmtWhenTrue.setOperandOriginalPositions([...resultLocalPosition, ...whenTrueValueAndStmts.valueOriginalPositions]);
|
|
890
|
+
stmts.push(assignStmtWhenTrue);
|
|
891
|
+
stmts.push(new ArkIRTransformer_2.DummyStmt(ArkIRTransformer_1.ArkCxxIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_FALSE_STMT + currConditionalOperatorIndex));
|
|
892
|
+
// The last internal node is the value when the expression is false
|
|
893
|
+
InnerIdx = conditionalExpression.inner.length - 1;
|
|
894
|
+
const { value: whenFalseValue, valueOriginalPositions: whenFalsePositions, stmts: whenFalseStmts } = this.cxxNodeToValueAndStmts(conditionalExpression.inner[InnerIdx]);
|
|
895
|
+
stmts.push(...whenFalseStmts);
|
|
896
|
+
const assignStmt = new Stmt_1.ArkAssignStmt(resultLocal, whenFalseValue);
|
|
897
|
+
assignStmt.setOperandOriginalPositions([...resultLocalPosition, ...whenFalsePositions]);
|
|
898
|
+
stmts.push(assignStmt);
|
|
899
|
+
stmts.push(new ArkIRTransformer_2.DummyStmt(ArkIRTransformer_1.ArkCxxIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT + currConditionalOperatorIndex));
|
|
900
|
+
return {
|
|
901
|
+
value: resultLocal,
|
|
902
|
+
valueOriginalPositions: resultLocalPosition,
|
|
903
|
+
stmts: stmts,
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
*Extract the calling node and parameter node from the internal AST node array for overwriting
|
|
908
|
+
*@ param innerAsNodes An AST node array containing call information and parameters. The first element is the call node, and the rest are parameter nodes
|
|
909
|
+
*@ returns an array containing two elements: the first element is the call node, and the second element is the parameter node array
|
|
910
|
+
*/
|
|
911
|
+
getArgumentNodeForRecover(innerAsNodes) {
|
|
912
|
+
const [callNode, ...argumentNodes] = innerAsNodes;
|
|
913
|
+
return [callNode, argumentNodes];
|
|
914
|
+
}
|
|
915
|
+
getArgumentNode(innerAstNodes) {
|
|
916
|
+
var _a, _b, _c;
|
|
917
|
+
// At this time, innerAstNode is a separate point
|
|
918
|
+
if (!Array.isArray(innerAstNodes)) {
|
|
919
|
+
const firstInner = (_a = innerAstNodes.inner) === null || _a === void 0 ? void 0 : _a[0];
|
|
920
|
+
if (!firstInner) {
|
|
921
|
+
return [undefined, []];
|
|
922
|
+
}
|
|
923
|
+
const call = this.getDeclRef(firstInner);
|
|
924
|
+
const args = ((_c = (_b = innerAstNodes.inner) === null || _b === void 0 ? void 0 : _b.slice(1)) !== null && _c !== void 0 ? _c : [])
|
|
925
|
+
.map(n => this.getDeclRef(n));
|
|
926
|
+
return [call, args];
|
|
927
|
+
}
|
|
928
|
+
// Several callable kinds
|
|
929
|
+
const CALLABLE_KINDS = new Set([
|
|
930
|
+
ArkCxxAstNode_1.astKind.DeclRefExpr,
|
|
931
|
+
ArkCxxAstNode_1.astKind.MemberExpr,
|
|
932
|
+
ArkCxxAstNode_1.astKind.OverloadedDeclRef,
|
|
933
|
+
ArkCxxAstNode_1.astKind.ArraySubscriptExpr,
|
|
934
|
+
ArkCxxAstNode_1.astKind.CXXOperatorCallExpr,
|
|
935
|
+
ArkCxxAstNode_1.astKind.UnresolvedLookupExpr,
|
|
936
|
+
]);
|
|
937
|
+
function unwrapImplicit(n) {
|
|
938
|
+
var _a;
|
|
939
|
+
while (n && n.kind === ArkCxxAstNode_1.astKind.ImplicitCastExpr) {
|
|
940
|
+
n = (_a = n.inner) === null || _a === void 0 ? void 0 : _a[0];
|
|
941
|
+
}
|
|
942
|
+
return n;
|
|
943
|
+
}
|
|
944
|
+
let callNode;
|
|
945
|
+
const argumentNodes = [];
|
|
946
|
+
for (let i = 0; i < innerAstNodes.length; i++) {
|
|
947
|
+
const node = innerAstNodes[i];
|
|
948
|
+
if (i === 0) {
|
|
949
|
+
const first = unwrapImplicit(node);
|
|
950
|
+
if (!first) {
|
|
951
|
+
continue;
|
|
952
|
+
}
|
|
953
|
+
if (CALLABLE_KINDS.has(first.kind)) {
|
|
954
|
+
callNode = first;
|
|
955
|
+
}
|
|
956
|
+
else {
|
|
957
|
+
argumentNodes.push(first);
|
|
958
|
+
}
|
|
959
|
+
continue;
|
|
960
|
+
}
|
|
961
|
+
argumentNodes.push(node);
|
|
962
|
+
}
|
|
963
|
+
return [callNode, argumentNodes];
|
|
964
|
+
}
|
|
965
|
+
getDeclRef(astNode) {
|
|
966
|
+
let n = astNode;
|
|
967
|
+
while (n) {
|
|
968
|
+
if (n.kind === ArkCxxAstNode_1.astKind.DeclRefExpr) {
|
|
969
|
+
return n;
|
|
970
|
+
}
|
|
971
|
+
// No child node or empty child node, end
|
|
972
|
+
if (!n.inner || n.inner.length === 0) {
|
|
973
|
+
break;
|
|
974
|
+
}
|
|
975
|
+
// Go down the first child node
|
|
976
|
+
n = n.inner[0];
|
|
977
|
+
}
|
|
978
|
+
return undefined;
|
|
979
|
+
}
|
|
980
|
+
cxxGenerateSystemComponentStmt(componentName, args, argPositionsAllFlat, componentExpression, currStmts) {
|
|
981
|
+
const stmts = [...currStmts];
|
|
982
|
+
const componentExpressionPosition = Position_1.FullPosition.cxxBuildFromNode(componentExpression, this.cxxSourceFile);
|
|
983
|
+
const { value: componentValue, valueOriginalPositions: componentPositions, stmts: componentStmts, } = this.cxxGenerateComponentCreationStmts(componentName, args, componentExpressionPosition, argPositionsAllFlat);
|
|
984
|
+
stmts.push(...componentStmts);
|
|
985
|
+
stmts.push(this.generateComponentPopStmts(componentName, componentExpressionPosition));
|
|
986
|
+
return {
|
|
987
|
+
value: componentValue,
|
|
988
|
+
valueOriginalPositions: componentPositions,
|
|
989
|
+
stmts: stmts,
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
cxxGenerateCustomViewStmt(componentName, args, argPositionsAllFlat, componentExpression, currStmts) {
|
|
993
|
+
const stmts = [...currStmts];
|
|
994
|
+
const componentExpressionPosition = Position_1.FullPosition.cxxBuildFromNode(componentExpression, this.cxxSourceFile);
|
|
995
|
+
const classSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildClassSignatureFromClassName(componentName);
|
|
996
|
+
const classType = new Type_1.ClassType(classSignature);
|
|
997
|
+
const newExpr = new Expr_1.ArkNewExpr(classType);
|
|
998
|
+
const { value: newExprLocal, valueOriginalPositions: newExprPositions, stmts: newExprStmts, } = this.ArkCxxIRTransformer.generateAssignStmtForValue(newExpr, [componentExpressionPosition]);
|
|
999
|
+
stmts.push(...newExprStmts);
|
|
1000
|
+
const constructorMethodSubSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(TSConst_1.CONSTRUCTOR_NAME);
|
|
1001
|
+
const constructorMethodSignature = new ArkSignature_1.MethodSignature(classSignature, constructorMethodSubSignature);
|
|
1002
|
+
const instanceInvokeExpr = new Expr_1.ArkInstanceInvokeExpr(newExprLocal, constructorMethodSignature, args);
|
|
1003
|
+
const instanceInvokeExprPositions = [componentExpressionPosition, ...newExprPositions, ...argPositionsAllFlat];
|
|
1004
|
+
const instanceInvokeStmt = new Stmt_1.ArkInvokeStmt(instanceInvokeExpr);
|
|
1005
|
+
instanceInvokeStmt.setOperandOriginalPositions(instanceInvokeExprPositions);
|
|
1006
|
+
stmts.push(instanceInvokeStmt);
|
|
1007
|
+
const createViewArgs = [newExprLocal];
|
|
1008
|
+
const createViewArgPositionsAll = [newExprPositions];
|
|
1009
|
+
const { value: componentValue, valueOriginalPositions: componentPositions, stmts: componentStmts, } = this.cxxGenerateComponentCreationStmts(EtsConst_1.COMPONENT_CUSTOMVIEW, createViewArgs, componentExpressionPosition, createViewArgPositionsAll.flat());
|
|
1010
|
+
stmts.push(...componentStmts);
|
|
1011
|
+
stmts.push(this.generateComponentPopStmts(EtsConst_1.COMPONENT_CUSTOMVIEW, componentExpressionPosition));
|
|
1012
|
+
return {
|
|
1013
|
+
value: componentValue,
|
|
1014
|
+
valueOriginalPositions: componentPositions,
|
|
1015
|
+
stmts: stmts,
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
cxxGenerateComponentCreationStmts(componentName, createArgs, componentExpressionPosition, createArgsPositionsAllFlat) {
|
|
1019
|
+
const createMethodSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(componentName, EtsConst_1.COMPONENT_CREATE_FUNCTION);
|
|
1020
|
+
const createInvokeExpr = new Expr_1.ArkStaticInvokeExpr(createMethodSignature, createArgs);
|
|
1021
|
+
const createInvokeExprPositions = [componentExpressionPosition, ...createArgsPositionsAllFlat];
|
|
1022
|
+
const { value: componentValue, valueOriginalPositions: componentPositions, stmts: componentStmts, } = this.ArkCxxIRTransformer.generateAssignStmtForValue(createInvokeExpr, createInvokeExprPositions);
|
|
1023
|
+
return {
|
|
1024
|
+
value: componentValue,
|
|
1025
|
+
valueOriginalPositions: componentPositions,
|
|
1026
|
+
stmts: componentStmts,
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
/**
|
|
1030
|
+
*Convert C++identifiers to collections of values and statements
|
|
1031
|
+
*@ param identifier C++AST node identifier
|
|
1032
|
+
*@ param variableDefFlag Optional variable definition flag, used to distinguish variable declaration from variable use
|
|
1033
|
+
*@ returns Objects containing values, location information and statement arrays
|
|
1034
|
+
*/
|
|
1035
|
+
cxxIdentifierToValueAndStmts(identifier, variableDefFlag) {
|
|
1036
|
+
var _a;
|
|
1037
|
+
let identifierValue;
|
|
1038
|
+
let identifierPositions = [Position_1.FullPosition.cxxBuildFromNode(identifier, this.cxxSourceFile)];
|
|
1039
|
+
let varNode;
|
|
1040
|
+
if (identifier.referencedDecl) {
|
|
1041
|
+
varNode = identifier.referencedDecl;
|
|
1042
|
+
}
|
|
1043
|
+
else {
|
|
1044
|
+
varNode = identifier;
|
|
1045
|
+
}
|
|
1046
|
+
let varName = varNode.kind === ArkCxxAstNode_1.astKind.TypeRef ? varNode.code : varNode.name;
|
|
1047
|
+
const varType = (0, builderUtils_1.cxxNode2Type)(identifier, this.declaringMethod);
|
|
1048
|
+
if (varName === Type_1.UndefinedType.getInstance().getName()) {
|
|
1049
|
+
identifierValue = ValueUtil_1.CxxValueUtil.getUndefinedConst();
|
|
1050
|
+
}
|
|
1051
|
+
else {
|
|
1052
|
+
if (variableDefFlag) {
|
|
1053
|
+
identifierValue = this.addNewLocal(varName, varType);
|
|
1054
|
+
}
|
|
1055
|
+
else {
|
|
1056
|
+
if ((_a = identifier.name) === null || _a === void 0 ? void 0 : _a.includes('::' + varName + '<')) { // Determine whether it is a variable template
|
|
1057
|
+
varName = identifier.name;
|
|
1058
|
+
}
|
|
1059
|
+
identifierValue = this.getOrCreateLocal(varName, varType);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
return {
|
|
1063
|
+
value: identifierValue,
|
|
1064
|
+
valueOriginalPositions: identifierPositions,
|
|
1065
|
+
stmts: [],
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
*Convert the member expression of C++(such as testMap. insert) to ValueAndStmts of Ark IR
|
|
1070
|
+
*@ param memberExpression - shaped like an AST MemberExpr/MemberRef node, which usually means obj. field or obj ->field
|
|
1071
|
+
*@ param localValue - (Optional) The scenario where the baseValue is specified directly (
|
|
1072
|
+
* such as determining the base in advance when resolving the parent node)
|
|
1073
|
+
*/
|
|
1074
|
+
memberExpressionToValueAndStmts(memberExpression, localValue) {
|
|
1075
|
+
var _a, _b, _c;
|
|
1076
|
+
const stmts = [];
|
|
1077
|
+
// [Scenario 1] Process this ->field or this ->method calls in C++code
|
|
1078
|
+
// If it's a class member reference (MemberExpr/MemberRef) but has no inner[0], it means implicit this, need to supplement this node
|
|
1079
|
+
if ((memberExpression.kind === ArkCxxAstNode_1.astKind.MemberExpr || memberExpression.kind === ArkCxxAstNode_1.astKind.MemberRef) && memberExpression.inner[0] === undefined) {
|
|
1080
|
+
memberExpression.inner[0] = {
|
|
1081
|
+
kind: 'CXXThisExpr',
|
|
1082
|
+
name: memberExpression.name,
|
|
1083
|
+
code: '',
|
|
1084
|
+
type: { qualType: 'void' },
|
|
1085
|
+
inner: [],
|
|
1086
|
+
}; // As base node
|
|
1087
|
+
}
|
|
1088
|
+
// [Scenario 2] Recursively process base object, such as testMap in testMap.insert
|
|
1089
|
+
// Get baseValue (e.g., testMap), position information, and possible preceding statements (e.g., auto tmp = ...;)
|
|
1090
|
+
let { value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts, } = this.cxxNodeToValueAndStmts(memberExpression.inner[0]);
|
|
1091
|
+
// [Scenario 3] Processing chained member access, such as a.b.c or (* ptr). field
|
|
1092
|
+
// If the base is a member access, generate an assignment statement to ensure the validity of SSA
|
|
1093
|
+
if (((_a = memberExpression.inner[0]) === null || _a === void 0 ? void 0 : _a.kind) === ArkCxxAstNode_1.astKind.MemberExpr || memberExpression.kind === ArkCxxAstNode_1.astKind.MemberRef) {
|
|
1094
|
+
({ value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } =
|
|
1095
|
+
this.ArkCxxIRTransformer.generateAssignStmtForValue(baseValue, basePositions));
|
|
1096
|
+
}
|
|
1097
|
+
// [Scenario 4] On special occasions, the caller directly specifies the baseValue (generally used to replace the base,
|
|
1098
|
+
// such as virtual members, generics, etc.)
|
|
1099
|
+
if (localValue) {
|
|
1100
|
+
baseValue = localValue;
|
|
1101
|
+
}
|
|
1102
|
+
// Combine preceding statements to ensure complete order
|
|
1103
|
+
stmts.push(...baseStmts);
|
|
1104
|
+
// [Scenario 5] Get the member's field signature
|
|
1105
|
+
// The purpose is to associate the insert in testMap.insert with the base type (such as the type of testMap) to form a complete field signature
|
|
1106
|
+
const fieldSignature = this.buildFieldSignatureFromMemberExpr(baseValue, memberExpression);
|
|
1107
|
+
// [Scenario 6] Generate the field reference object of IR layer (such as testMap. insert)
|
|
1108
|
+
let fieldRef;
|
|
1109
|
+
if (((_b = memberExpression.referencedDecl) === null || _b === void 0 ? void 0 : _b.kind) === ArkCxxAstNode_1.astKind.EnumConstantDecl) {
|
|
1110
|
+
fieldRef = new Ref_1.ArkStaticFieldRef(fieldSignature);
|
|
1111
|
+
}
|
|
1112
|
+
else {
|
|
1113
|
+
fieldRef = new Ref_2.ArkCxxInstanceFieldRef(baseValue, // baseValue(eg: testMap)
|
|
1114
|
+
(_c = memberExpression.isArrow) !== null && _c !== void 0 ? _c : false, // Whether it is arrow access (->)
|
|
1115
|
+
fieldSignature);
|
|
1116
|
+
}
|
|
1117
|
+
// Record node location information for subsequent traceability and debugging
|
|
1118
|
+
const fieldRefPositions = [Position_1.FullPosition.cxxBuildFromNode(memberExpression, this.cxxSourceFile), ...basePositions];
|
|
1119
|
+
// Return resolution results, including IR field references, location information, and related SSA statements
|
|
1120
|
+
return { value: fieldRef, valueOriginalPositions: fieldRefPositions, stmts: stmts };
|
|
1121
|
+
}
|
|
1122
|
+
buildFieldSignatureFromMemberExpr(baseValue, memberExpression) {
|
|
1123
|
+
var _a, _b;
|
|
1124
|
+
let fieldSignature;
|
|
1125
|
+
const memberName = ((_a = memberExpression.referencedDecl) === null || _a === void 0 ? void 0 : _a.name) || memberExpression.name || memberExpression.code;
|
|
1126
|
+
// ==Scenarios for Special Handling of Enum Members==
|
|
1127
|
+
if (((_b = memberExpression.referencedDecl) === null || _b === void 0 ? void 0 : _b.kind) === ArkCxxAstNode_1.astKind.EnumConstantDecl) {
|
|
1128
|
+
const enumClassName = memberExpression.type.qualType.replace('enum', '').trim();
|
|
1129
|
+
const enumArkClass = ModelUtils_2.CxxModelUtils.findSymbolInFileWithName(enumClassName, this.declaringMethod.getDeclaringArkClass());
|
|
1130
|
+
const enumSignature = (enumArkClass instanceof ArkClass_1.ArkClass) ?
|
|
1131
|
+
enumArkClass.getSignature() :
|
|
1132
|
+
ArkSignatureBuilder_1.ArkSignatureBuilder.buildClassSignatureFromClassName(enumClassName);
|
|
1133
|
+
return new ArkSignature_1.FieldSignature(memberName, enumSignature, enumSignature.getType(), true);
|
|
1134
|
+
}
|
|
1135
|
+
// ==Handling common scenarios==
|
|
1136
|
+
let baseType = baseValue.getType();
|
|
1137
|
+
if (baseValue instanceof Ref_1.ArkArrayRef) {
|
|
1138
|
+
let arrayBaseType = TypeInference_1.TypeInference.replaceTypeWithReal(baseValue.getBase().getType());
|
|
1139
|
+
if (arrayBaseType instanceof Type_2.CxxArrayType) {
|
|
1140
|
+
baseType = arrayBaseType.getBaseType();
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
let baseClassType = null;
|
|
1144
|
+
// Judge whether the base is a class type or its pointer/reference
|
|
1145
|
+
if (baseType instanceof Type_1.ClassType) {
|
|
1146
|
+
baseClassType = baseType;
|
|
1147
|
+
}
|
|
1148
|
+
else if (baseType instanceof Type_2.PointerType && baseType.getBaseType() instanceof Type_1.ClassType) {
|
|
1149
|
+
baseClassType = baseType.getBaseType();
|
|
1150
|
+
}
|
|
1151
|
+
else if (baseType instanceof Type_2.ReferenceType && baseType.getBaseType() instanceof Type_1.ClassType) {
|
|
1152
|
+
baseClassType = baseType.getBaseType();
|
|
1153
|
+
}
|
|
1154
|
+
// Construction field signature
|
|
1155
|
+
// If base is a class local variable, use the complete class signature
|
|
1156
|
+
if ((baseValue instanceof Local_1.Local || baseValue instanceof Ref_1.ArkArrayRef) && baseClassType !== null) {
|
|
1157
|
+
fieldSignature = new ArkSignature_1.FieldSignature(memberName, // Field name (such as insert)
|
|
1158
|
+
baseClassType.getClassSignature(), // Base class type signature
|
|
1159
|
+
baseType);
|
|
1160
|
+
}
|
|
1161
|
+
else {
|
|
1162
|
+
// Otherwise, it is generated only according to the field name
|
|
1163
|
+
fieldSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildFieldSignatureFromFieldName(memberName);
|
|
1164
|
+
}
|
|
1165
|
+
// Set field types to support C++complex type resolution (such as template, pointer, const, etc.)
|
|
1166
|
+
fieldSignature.setType((0, builderUtils_1.cxxNode2Type)(memberExpression, this.declaringMethod));
|
|
1167
|
+
return fieldSignature;
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
*Convert element access expressions (such as array [index] or object. field) in C++AST to values and statements in intermediate representation (IR).
|
|
1171
|
+
*
|
|
1172
|
+
*@ param elementAccessExpression represents the AST node of C++element access expression
|
|
1173
|
+
*@ returns contains the generated IR value, original location information and the ValueAndStmts object of related statements
|
|
1174
|
+
*/
|
|
1175
|
+
cxxElementAccessExpressionToValueAndStmts(elementAccessExpression) {
|
|
1176
|
+
const stmts = [];
|
|
1177
|
+
let { value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts, } = this.cxxNodeToValueAndStmts(elementAccessExpression.inner[0]);
|
|
1178
|
+
stmts.push(...baseStmts);
|
|
1179
|
+
if (!(baseValue instanceof Local_1.Local)) {
|
|
1180
|
+
({
|
|
1181
|
+
value: baseValue,
|
|
1182
|
+
valueOriginalPositions: basePositions,
|
|
1183
|
+
stmts: baseStmts,
|
|
1184
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(baseValue, basePositions));
|
|
1185
|
+
stmts.push(...baseStmts);
|
|
1186
|
+
}
|
|
1187
|
+
let { value: argumentValue, valueOriginalPositions: arguPositions, stmts: argumentStmts, } = this.cxxNodeToValueAndStmts(elementAccessExpression.inner[1]);
|
|
1188
|
+
stmts.push(...argumentStmts);
|
|
1189
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(argumentValue)) {
|
|
1190
|
+
({
|
|
1191
|
+
value: argumentValue,
|
|
1192
|
+
valueOriginalPositions: arguPositions,
|
|
1193
|
+
stmts: argumentStmts,
|
|
1194
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(argumentValue, arguPositions));
|
|
1195
|
+
stmts.push(...argumentStmts);
|
|
1196
|
+
}
|
|
1197
|
+
let elementAccessExpr;
|
|
1198
|
+
if (baseValue.getType() instanceof Type_2.CxxArrayType || baseValue.getType() instanceof Type_2.PointerType) {
|
|
1199
|
+
elementAccessExpr = new Ref_1.ArkArrayRef(baseValue, argumentValue);
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
const fieldSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildFieldSignatureFromFieldName(argumentValue.toString());
|
|
1203
|
+
elementAccessExpr = new Ref_1.ArkInstanceFieldRef(baseValue, fieldSignature);
|
|
1204
|
+
}
|
|
1205
|
+
// reserve positions for field name
|
|
1206
|
+
const exprPositions = [Position_1.FullPosition.cxxBuildFromNode(elementAccessExpression, this.cxxSourceFile), ...basePositions, ...arguPositions];
|
|
1207
|
+
return {
|
|
1208
|
+
value: elementAccessExpr,
|
|
1209
|
+
valueOriginalPositions: exprPositions,
|
|
1210
|
+
stmts: stmts,
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
cxxCallExpressionToValueAndStmts(callExpression) {
|
|
1214
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1215
|
+
if (callExpression.kind === ArkCxxAstNode_1.astKind.CallExpr && ((_a = callExpression.inner) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
1216
|
+
if (((_e = (_d = ((_b = callExpression.parent) !== null && _b !== void 0 ? _b : (_c = callExpression.getParent) === null || _c === void 0 ? void 0 : _c.call(callExpression, true))) === null || _d === void 0 ? void 0 : _d.type) === null || _e === void 0 ? void 0 : _e.qualType) === 'std::thread') {
|
|
1217
|
+
return this.cxxNewExpressionToValueAndStmts(callExpression);
|
|
1218
|
+
}
|
|
1219
|
+
else if (callExpression.inner[0].kind === ArkCxxAstNode_1.astKind.CXXPseudoDestructorExpression) {
|
|
1220
|
+
return this.cxxCallExpressionToValueAndStmts(callExpression.inner[0]);
|
|
1221
|
+
}
|
|
1222
|
+
else if (callExpression.name === 'basic_string' || callExpression.inner[0].kind === ArkCxxAstNode_1.astKind.MaterializeTemporaryExpr) {
|
|
1223
|
+
return this.cxxNodeToValueAndStmts(callExpression.inner[0]);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
const stmts = [];
|
|
1227
|
+
const [callNode, argumentNodes] = this.getArgumentNode(callExpression.inner);
|
|
1228
|
+
if (callNode && (0, builderUtils_1.isFuncInClassOrNamespace)(callNode) && ((_f = callNode.referencedDecl) === null || _f === void 0 ? void 0 : _f.name)) {
|
|
1229
|
+
// Process static function calls
|
|
1230
|
+
callNode.kind = 'MemberExpr';
|
|
1231
|
+
const replaceFuncName = callNode.referencedDecl.name;
|
|
1232
|
+
callNode.name = replaceFuncName;
|
|
1233
|
+
const outerName = callNode.code.replace('::' + replaceFuncName, '');
|
|
1234
|
+
callNode.inner[0] = {
|
|
1235
|
+
kind: 'DeclRefExpr',
|
|
1236
|
+
name: outerName,
|
|
1237
|
+
code: outerName,
|
|
1238
|
+
type: { qualType: outerName },
|
|
1239
|
+
inner: [],
|
|
1240
|
+
};
|
|
1241
|
+
return this.buildValueAndStmtsForMemberCall(stmts, callNode, argumentNodes, callExpression, undefined);
|
|
1242
|
+
}
|
|
1243
|
+
const argus = this.cxxParseArgumentsOfCallExpression(stmts, argumentNodes, callNode);
|
|
1244
|
+
if (callExpression.name === 'napi_define_class') {
|
|
1245
|
+
(0, ModelUtils_2.setTs2CxxFuncMapOfClass)(argus.args, true, this.declaringMethod);
|
|
1246
|
+
}
|
|
1247
|
+
const returnType = (0, builderUtils_1.cxxNode2Type)(callExpression, this.declaringMethod);
|
|
1248
|
+
return this.cxxGenerateInvokeValueAndStmts(callNode, argus, stmts, callExpression, returnType);
|
|
1249
|
+
}
|
|
1250
|
+
/**
|
|
1251
|
+
*Process the 'cout<<...' or lambda expression in C++, extract its operands and construct corresponding statements and values.
|
|
1252
|
+
*
|
|
1253
|
+
*@ param callExpression - The currently processed C++AST node, which represents an operator calling expression (such as<<).
|
|
1254
|
+
*@ param callArgus - An array used to collect the parameter nodes involved in the expression.
|
|
1255
|
+
*@ returns the ValueAndStmts object containing values and statements. If it cannot be processed, it returns null.
|
|
1256
|
+
*/
|
|
1257
|
+
streamOrLambdaExprToValueAndStmts(callExpression, callArgus) {
|
|
1258
|
+
const stmts = [];
|
|
1259
|
+
// Because inner extracts the last parameters in turn, it traverses the last parameters in reverse order
|
|
1260
|
+
for (let i = callExpression.inner.length - 1; i >= 0; i--) {
|
|
1261
|
+
let innerNode = callExpression.inner[i];
|
|
1262
|
+
if (!innerNode.code.includes('cout') &&
|
|
1263
|
+
!innerNode.code.includes('<<') &&
|
|
1264
|
+
!innerNode.code.includes('endl') &&
|
|
1265
|
+
!callExpression.code.startsWith(innerNode.code)) {
|
|
1266
|
+
callArgus.push(innerNode);
|
|
1267
|
+
}
|
|
1268
|
+
if (innerNode.kind === ArkCxxAstNode_1.astKind.CXXOperatorCallExpr) {
|
|
1269
|
+
// Recursive call processing CXXOperatorCallExpr
|
|
1270
|
+
if (innerNode.type.qualType !== 'std::ostream') {
|
|
1271
|
+
return this.streamOrLambdaExprToValueAndStmts(innerNode, callArgus);
|
|
1272
|
+
}
|
|
1273
|
+
// When the type is std:: ostream, it indicates an overloaded stream operator and records the overloaded node of the stream operator
|
|
1274
|
+
callArgus.push(innerNode);
|
|
1275
|
+
// Recursive call to process CXXOperatorCallExpr nested in the inner of CXXOperatorCallExpr
|
|
1276
|
+
if (innerNode.inner[1].kind === ArkCxxAstNode_1.astKind.CXXOperatorCallExpr) {
|
|
1277
|
+
return this.streamOrLambdaExprToValueAndStmts(innerNode.inner[1], callArgus);
|
|
1278
|
+
}
|
|
1279
|
+
// If there is no nested CXXOperatorCallExpr, the ValueAndStmts of overloaded stream operators will be built directly
|
|
1280
|
+
return this.buildValueAndStmtsForStreamOrLambdaCall(innerNode.inner[1], callArgus.reverse(), stmts, callExpression);
|
|
1281
|
+
}
|
|
1282
|
+
while (innerNode.kind === ArkCxxAstNode_1.astKind.ImplicitCastExpr && innerNode.valueCategory === 'lvalue' && innerNode.inner.length > 0) {
|
|
1283
|
+
innerNode = innerNode.inner[0];
|
|
1284
|
+
}
|
|
1285
|
+
if (innerNode.kind === ArkCxxAstNode_1.astKind.DeclRefExpr &&
|
|
1286
|
+
(innerNode.type.qualType.includes('iostream') ||
|
|
1287
|
+
innerNode.type.qualType.includes('ostream') ||
|
|
1288
|
+
innerNode.type.qualType.includes('istream') ||
|
|
1289
|
+
innerNode.type.qualType.includes('lambda at'))) {
|
|
1290
|
+
// Get DeclRefExpr and its subsequent nodes
|
|
1291
|
+
return this.buildValueAndStmtsForStreamOrLambdaCall(innerNode, callArgus.reverse(), stmts, callExpression);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
return null;
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
*Build a collection of values and statements for stream operations or lambda function call
|
|
1298
|
+
*
|
|
1299
|
+
*@ param streamNode The AST node of the stream node
|
|
1300
|
+
*@ param args parameter array of stream operation
|
|
1301
|
+
*@ param stmts statement array
|
|
1302
|
+
*@ param streamExpr AST node of stream expression
|
|
1303
|
+
*@ returns The ValueAndStmts object containing values and statements
|
|
1304
|
+
*/
|
|
1305
|
+
buildValueAndStmtsForStreamOrLambdaCall(streamNode, args, stmts, streamExpr) {
|
|
1306
|
+
let nonOverloadedArgs = [];
|
|
1307
|
+
const currValueAndStmts = {
|
|
1308
|
+
value: new Local_1.Local(streamExpr.code),
|
|
1309
|
+
valueOriginalPositions: [],
|
|
1310
|
+
stmts: [...stmts],
|
|
1311
|
+
};
|
|
1312
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
1313
|
+
let arg = args[i];
|
|
1314
|
+
if (arg.kind === ArkCxxAstNode_1.astKind.CXXOperatorCallExpr) {
|
|
1315
|
+
// Standard stream operator+overloaded stream operator
|
|
1316
|
+
// 1. Object of standard stream operator, call std:: stream function
|
|
1317
|
+
this.buildValueAndStmtsForStdStreamOrLambdaCall(streamNode, nonOverloadedArgs, streamExpr, currValueAndStmts);
|
|
1318
|
+
// 2. Overload the object of the output operator and call the overloaded function
|
|
1319
|
+
this.buildValueAndStmtsForOverloadedStream(streamNode, arg, currValueAndStmts);
|
|
1320
|
+
nonOverloadedArgs = [];
|
|
1321
|
+
}
|
|
1322
|
+
else {
|
|
1323
|
+
nonOverloadedArgs.push(arg);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
// process the remaining standard stream operators
|
|
1327
|
+
this.buildValueAndStmtsForStdStreamOrLambdaCall(streamNode, nonOverloadedArgs, streamExpr, currValueAndStmts);
|
|
1328
|
+
return currValueAndStmts;
|
|
1329
|
+
}
|
|
1330
|
+
/**
|
|
1331
|
+
*Build values and statements of overloaded flow operators
|
|
1332
|
+
*@ param streamNode
|
|
1333
|
+
*@ param overloadedArg overload parameter node
|
|
1334
|
+
*@ param currValueAndStmts Current value and statement collection
|
|
1335
|
+
*/
|
|
1336
|
+
buildValueAndStmtsForOverloadedStream(streamNode, overloadedArg, currValueAndStmts) {
|
|
1337
|
+
// Replace the second child node with an overloaded operator node to avoid repeated processing of nested CXXOperatorCallExpr
|
|
1338
|
+
overloadedArg.inner[1] = streamNode;
|
|
1339
|
+
let overloadedStreamValueAndStmts = this.handleOverloadedOp(overloadedArg);
|
|
1340
|
+
if (!overloadedStreamValueAndStmts) {
|
|
1341
|
+
return;
|
|
1342
|
+
}
|
|
1343
|
+
currValueAndStmts.stmts.push(...overloadedStreamValueAndStmts.stmts);
|
|
1344
|
+
currValueAndStmts.valueOriginalPositions.push(...overloadedStreamValueAndStmts.valueOriginalPositions);
|
|
1345
|
+
if (overloadedStreamValueAndStmts.value instanceof Expr_1.AbstractInvokeExpr) {
|
|
1346
|
+
const invokeStmt = new Stmt_1.ArkInvokeStmt(overloadedStreamValueAndStmts.value);
|
|
1347
|
+
invokeStmt.setOperandOriginalPositions(overloadedStreamValueAndStmts.valueOriginalPositions);
|
|
1348
|
+
currValueAndStmts.stmts.push(invokeStmt);
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
/**
|
|
1352
|
+
*Build a collection of values and statements for standard flow or lambda call nodes
|
|
1353
|
+
*@ param streamNode - AST node of the stream node
|
|
1354
|
+
*@ param nonOverlooadedArgs - non overloaded parameter array
|
|
1355
|
+
*@ param streamExpr - AST node of stream expression
|
|
1356
|
+
*@ param currValueAndStmts - current value and statement collection object, used to store processing results
|
|
1357
|
+
*/
|
|
1358
|
+
buildValueAndStmtsForStdStreamOrLambdaCall(streamNode, nonOverloadedArgs, streamExpr, currValueAndStmts) {
|
|
1359
|
+
const stmts = [];
|
|
1360
|
+
const argus = this.cxxParseArgumentsOfCallExpression(stmts, nonOverloadedArgs);
|
|
1361
|
+
const normalCoutValueAndStmts = this.cxxGenerateInvokeValueAndStmts(streamNode, argus, stmts, streamExpr);
|
|
1362
|
+
currValueAndStmts.stmts.push(...normalCoutValueAndStmts.stmts);
|
|
1363
|
+
currValueAndStmts.valueOriginalPositions = normalCoutValueAndStmts.valueOriginalPositions;
|
|
1364
|
+
if (streamNode.type.qualType.includes('lambda at')) {
|
|
1365
|
+
currValueAndStmts.value = normalCoutValueAndStmts.value;
|
|
1366
|
+
}
|
|
1367
|
+
else if (normalCoutValueAndStmts.value instanceof Expr_1.AbstractInvokeExpr) {
|
|
1368
|
+
const invokeStmt = new Stmt_1.ArkInvokeStmt(normalCoutValueAndStmts.value);
|
|
1369
|
+
invokeStmt.setOperandOriginalPositions(normalCoutValueAndStmts.valueOriginalPositions);
|
|
1370
|
+
currValueAndStmts.stmts.push(invokeStmt);
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
/**
|
|
1374
|
+
*Convert C++operator expression to binary operator expression
|
|
1375
|
+
*@ param expression - C++AST node, representing operator expression
|
|
1376
|
+
*@ returns the converted values and statements
|
|
1377
|
+
*/
|
|
1378
|
+
CXXOperatorExpressionToBinaryOperator(expression) {
|
|
1379
|
+
let operatorExpression = Object.assign({}, expression);
|
|
1380
|
+
operatorExpression.opcode = expression.inner[0].code;
|
|
1381
|
+
operatorExpression.inner = [expression.inner[1], expression.inner[2]];
|
|
1382
|
+
return this.cxxBinaryExpressionToValueAndStmts(operatorExpression);
|
|
1383
|
+
}
|
|
1384
|
+
/**
|
|
1385
|
+
*Convert C++operator expression to unary operator expression
|
|
1386
|
+
*@ param expression - C++AST node, representing operator expression
|
|
1387
|
+
*@ returns ValueAndStmts object, including converted values and statements
|
|
1388
|
+
*/
|
|
1389
|
+
CXXOperatorExpressionToUnaryOperator(expression) {
|
|
1390
|
+
let operatorExpression = Object.assign({}, expression);
|
|
1391
|
+
operatorExpression.opcode = expression.inner[0].code;
|
|
1392
|
+
operatorExpression.inner = [expression.inner[1]];
|
|
1393
|
+
if (expression.code.indexOf(expression.inner[0].code) === 0) {
|
|
1394
|
+
return this.cxxPrefixUnaryExpressionToValueAndStmts(operatorExpression);
|
|
1395
|
+
}
|
|
1396
|
+
return this.cxxPostfixUnaryExpressionToValueAndStmts(operatorExpression);
|
|
1397
|
+
}
|
|
1398
|
+
cxxOperatorExpressionToValueAndStmts(callExpression, layer = true) {
|
|
1399
|
+
var _a;
|
|
1400
|
+
// First handle overloaded operators or other special cases
|
|
1401
|
+
const specialResult = this.handleSpecialOperators(callExpression);
|
|
1402
|
+
if (specialResult) {
|
|
1403
|
+
return specialResult;
|
|
1404
|
+
}
|
|
1405
|
+
const innerStmts = [];
|
|
1406
|
+
const stmts = [];
|
|
1407
|
+
// Collect statements from all inner nodes
|
|
1408
|
+
this.collectInnerOperatorStmts(callExpression, innerStmts);
|
|
1409
|
+
if (!layer) {
|
|
1410
|
+
// Only process final output in the first recursive layer
|
|
1411
|
+
return innerStmts;
|
|
1412
|
+
}
|
|
1413
|
+
// Merge results and build element access expression
|
|
1414
|
+
const exprPositions = [Position_1.FullPosition.cxxBuildFromNode(callExpression, this.cxxSourceFile)];
|
|
1415
|
+
for (const stmt of innerStmts) {
|
|
1416
|
+
exprPositions.push(...stmt.valueOriginalPositions);
|
|
1417
|
+
}
|
|
1418
|
+
// *ptr,When ptr is a smart pointer and the node type is CXXOperatorCallExpr, we will perform pointer dereference parsing here
|
|
1419
|
+
let elementAccessExpr;
|
|
1420
|
+
if (innerStmts.length >= 2) {
|
|
1421
|
+
elementAccessExpr = new Ref_1.ArkArrayRef(innerStmts[0].value, innerStmts[1].value);
|
|
1422
|
+
}
|
|
1423
|
+
else {
|
|
1424
|
+
const operatorToken = ((_a = callExpression.name) !== null && _a !== void 0 ? _a : '').replace('operator', '');
|
|
1425
|
+
const operator = ArkIRTransformer_1.ArkCxxIRTransformer.cxxTokenToUnaryOperator(operatorToken);
|
|
1426
|
+
if (operator && innerStmts.length > 0) {
|
|
1427
|
+
elementAccessExpr = new Expr_1.ArkUnopExpr(innerStmts[0].value, operator);
|
|
1428
|
+
}
|
|
1429
|
+
else {
|
|
1430
|
+
elementAccessExpr = ValueUtil_1.CxxValueUtil.getUndefinedConst();
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
innerStmts.forEach(innerStmt => {
|
|
1434
|
+
stmts.push(...innerStmt.stmts);
|
|
1435
|
+
});
|
|
1436
|
+
return { value: elementAccessExpr, valueOriginalPositions: exprPositions, stmts: stmts };
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Handle special operator scenarios and return early if matched
|
|
1440
|
+
*/
|
|
1441
|
+
handleSpecialOperators(callExpression) {
|
|
1442
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
1443
|
+
// Overloaded operator
|
|
1444
|
+
const overloadedOpToValueAndStmts = this.handleOverloadedOp(callExpression);
|
|
1445
|
+
if (overloadedOpToValueAndStmts) {
|
|
1446
|
+
return overloadedOpToValueAndStmts;
|
|
1447
|
+
}
|
|
1448
|
+
// operator<< / operator>> and lambda cout scenario
|
|
1449
|
+
if ((((_a = callExpression.inner[0]) === null || _a === void 0 ? void 0 : _a.kind) === ArkCxxAstNode_1.astKind.ImplicitCastExpr && ((_b = callExpression.inner[0]) === null || _b === void 0 ? void 0 : _b.name) === 'operator>>') ||
|
|
1450
|
+
callExpression.name === 'operator<<' ||
|
|
1451
|
+
((_c = callExpression.inner[0]) === null || _c === void 0 ? void 0 : _c.name) === 'operator<<' ||
|
|
1452
|
+
((_d = callExpression.inner[1]) === null || _d === void 0 ? void 0 : _d.type.qualType.toString().includes('(lambda at'))) {
|
|
1453
|
+
return this.streamOrLambdaExprToValueAndStmts(callExpression, []);
|
|
1454
|
+
}
|
|
1455
|
+
// Relational binary operator or assignment operator
|
|
1456
|
+
if (((_e = callExpression.inner[0]) === null || _e === void 0 ? void 0 : _e.kind) === ArkCxxAstNode_1.astKind.ImplicitCastExpr &&
|
|
1457
|
+
(ArkCxxValueTransformer.isRelationalBinaryOperator((_f = callExpression.inner[0]) === null || _f === void 0 ? void 0 : _f.code) ||
|
|
1458
|
+
this.getOverloadOpName(callExpression) === 'operator=')) {
|
|
1459
|
+
return this.CXXOperatorExpressionToBinaryOperator(callExpression);
|
|
1460
|
+
}
|
|
1461
|
+
// Unary operators (++ / --)
|
|
1462
|
+
if (((_g = callExpression.inner[0]) === null || _g === void 0 ? void 0 : _g.kind) === ArkCxxAstNode_1.astKind.ImplicitCastExpr &&
|
|
1463
|
+
['++', '--', '*'].includes((_h = callExpression.inner[0]) === null || _h === void 0 ? void 0 : _h.code)) {
|
|
1464
|
+
return this.CXXOperatorExpressionToUnaryOperator(callExpression);
|
|
1465
|
+
}
|
|
1466
|
+
// Arrow operator (->) in iteration
|
|
1467
|
+
if (((_j = callExpression.inner[0]) === null || _j === void 0 ? void 0 : _j.kind) === ArkCxxAstNode_1.astKind.ImplicitCastExpr &&
|
|
1468
|
+
((_k = callExpression.inner[0]) === null || _k === void 0 ? void 0 : _k.code) === '->') {
|
|
1469
|
+
return this.cxxNodeToValueAndStmts(callExpression.inner[1]);
|
|
1470
|
+
}
|
|
1471
|
+
return null;
|
|
1472
|
+
}
|
|
1473
|
+
/**
|
|
1474
|
+
* Collect ValueAndStmts from each inner node
|
|
1475
|
+
*/
|
|
1476
|
+
collectInnerOperatorStmts(callExpression, innerStmts) {
|
|
1477
|
+
for (let innerNode of callExpression.inner) {
|
|
1478
|
+
// 将第一组递归表达式类型定义为 string 数组
|
|
1479
|
+
const recursiveKinds = [
|
|
1480
|
+
ArkCxxAstNode_1.astKind.CXXOperatorCallExpr,
|
|
1481
|
+
ArkCxxAstNode_1.astKind.MaterializeTemporaryExpr,
|
|
1482
|
+
ArkCxxAstNode_1.astKind.CXXBindTemporaryExpr,
|
|
1483
|
+
ArkCxxAstNode_1.astKind.CXXConstructExpr
|
|
1484
|
+
];
|
|
1485
|
+
if (recursiveKinds.includes(innerNode.kind) ||
|
|
1486
|
+
(innerNode.kind === ArkCxxAstNode_1.astKind.ImplicitCastExpr && innerNode.castKind !== 'FunctionToPointerDecay')) {
|
|
1487
|
+
innerStmts.push(...this.cxxOperatorExpressionToValueAndStmts(innerNode, false));
|
|
1488
|
+
}
|
|
1489
|
+
else if (innerNode.kind === ArkCxxAstNode_1.astKind.DeclRefExpr) {
|
|
1490
|
+
innerStmts.push(this.cxxIdentifierToValueAndStmts(innerNode));
|
|
1491
|
+
}
|
|
1492
|
+
else if (innerNode.kind === ArkCxxAstNode_1.astKind.IntegerLiteral || innerNode.kind === ArkCxxAstNode_1.astKind.StringLiteral) {
|
|
1493
|
+
let literalNode = this.cxxLiteralNodeToValueAndStmts(innerNode);
|
|
1494
|
+
if (literalNode) {
|
|
1495
|
+
innerStmts.push(literalNode);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
getOverloadOpName(cxxOperatorCallExpr) {
|
|
1501
|
+
var _a, _b, _c, _d;
|
|
1502
|
+
return (_d = (_c = (_b = (_a = cxxOperatorCallExpr.inner[0]) === null || _a === void 0 ? void 0 : _a.inner[0]) === null || _b === void 0 ? void 0 : _b.referencedDecl) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : '';
|
|
1503
|
+
}
|
|
1504
|
+
/**
|
|
1505
|
+
*Handling C++overloaded operator call expressions
|
|
1506
|
+
*@ param cxxOperatorCallExpr C++AST node, representing operator calling expression
|
|
1507
|
+
*@ returns the processed value and statement object. If it cannot be processed, it returns null
|
|
1508
|
+
*/
|
|
1509
|
+
handleOverloadedOp(cxxOperatorCallExpr) {
|
|
1510
|
+
var _a, _b, _c, _d;
|
|
1511
|
+
if (((_a = cxxOperatorCallExpr.type) === null || _a === void 0 ? void 0 : _a.qualType) === '' ||
|
|
1512
|
+
((_c = (_b = cxxOperatorCallExpr.inner) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.castKind) !== 'FunctionToPointerDecay') {
|
|
1513
|
+
return null;
|
|
1514
|
+
}
|
|
1515
|
+
// Handling Recursive function, e.g. Case10 in lambdaFuncSample.cpp
|
|
1516
|
+
if ((_d = cxxOperatorCallExpr.inner) === null || _d === void 0 ? void 0 : _d[1]) {
|
|
1517
|
+
let callNode = cxxOperatorCallExpr.inner[1];
|
|
1518
|
+
while (callNode.kind === ArkCxxAstNode_1.astKind.ImplicitCastExpr && callNode.valueCategory === 'lvalue' && callNode.inner.length > 0) {
|
|
1519
|
+
callNode = callNode.inner[0];
|
|
1520
|
+
}
|
|
1521
|
+
if (callNode.type.qualType.includes('std::function') || this.isNodeRelatedToCXXLambdaFunc(callNode)) {
|
|
1522
|
+
return this.buildValueAndStmtsForMemberCall([], cxxOperatorCallExpr.inner[1], [...cxxOperatorCallExpr.inner.slice(2)], cxxOperatorCallExpr, undefined);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
let callType = (0, builderUtils_1.cxxNode2Type)(cxxOperatorCallExpr, this.declaringMethod);
|
|
1526
|
+
if (callType instanceof Type_2.ReferenceType) {
|
|
1527
|
+
callType = callType.getBaseType();
|
|
1528
|
+
}
|
|
1529
|
+
// Handling overloaded stream operators
|
|
1530
|
+
const callTypeStr = callType.toString();
|
|
1531
|
+
if (callTypeStr.includes('istream') || callTypeStr.includes('ostream')) {
|
|
1532
|
+
return this.buildInvokeValueForOverloadedStreamOp(cxxOperatorCallExpr);
|
|
1533
|
+
}
|
|
1534
|
+
if (!(callType instanceof Type_1.ClassType)) {
|
|
1535
|
+
return null;
|
|
1536
|
+
}
|
|
1537
|
+
// Handling overloaded operators in user-defined class
|
|
1538
|
+
const classSignature = callType.getClassSignature();
|
|
1539
|
+
const arkClass = this.declaringMethod.getDeclaringArkFile().getScene().getClass(classSignature);
|
|
1540
|
+
if (!arkClass) {
|
|
1541
|
+
return null;
|
|
1542
|
+
}
|
|
1543
|
+
const overloadOpName = this.getOverloadOpName(cxxOperatorCallExpr);
|
|
1544
|
+
const overloadOpMethod = overloadOpName ? arkClass.getMethodWithName(overloadOpName) : null;
|
|
1545
|
+
if (!overloadOpMethod) {
|
|
1546
|
+
return null;
|
|
1547
|
+
}
|
|
1548
|
+
return this.buildInvokeValueForNormalOverloadedOp(cxxOperatorCallExpr);
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
*Build values and statements called by overloaded flow operators, such as<<or>>.
|
|
1552
|
+
* Call IR for the function corresponding to the overload construction of the input/output stream operators operator<<, operator>>
|
|
1553
|
+
*This function is used to handle operator overloading call expressions in C++, especially for input/output stream operators.
|
|
1554
|
+
*It will parse parameters, find matching Ark methods, and generate corresponding call expressions.
|
|
1555
|
+
*
|
|
1556
|
+
*@ param cxxOperatorCallExpr represents the AST node of the C++operator call expression
|
|
1557
|
+
*@ returns an object containing values and statements. If it cannot be constructed, it returns null
|
|
1558
|
+
*/
|
|
1559
|
+
buildInvokeValueForOverloadedStreamOp(cxxOperatorCallExpr) {
|
|
1560
|
+
if (!cxxOperatorCallExpr.inner || cxxOperatorCallExpr.inner.length < 2) {
|
|
1561
|
+
return null;
|
|
1562
|
+
}
|
|
1563
|
+
const stmts = [];
|
|
1564
|
+
const { args, argPositions: argPositionsAll, } = this.cxxParseArguments(stmts, cxxOperatorCallExpr.inner.slice(1));
|
|
1565
|
+
// The input/output operator must be overloaded as a global function, and the overloaded function only has 2 parameters,
|
|
1566
|
+
// because the input/output operator is actually a binary operation: stream (left operand)+object (right operand)
|
|
1567
|
+
const defaultClass = this.declaringMethod.getDeclaringArkFile().getDefaultClass();
|
|
1568
|
+
const arkMtds = defaultClass.getAllMethodsWithName(cxxOperatorCallExpr.name);
|
|
1569
|
+
let matchMtd;
|
|
1570
|
+
for (const mtd of arkMtds) {
|
|
1571
|
+
const params = mtd.getParameters();
|
|
1572
|
+
let objType = params[1].getType();
|
|
1573
|
+
if (objType instanceof Type_2.ReferenceType) {
|
|
1574
|
+
objType = objType.getBaseType();
|
|
1575
|
+
}
|
|
1576
|
+
if (objType.toString() === args[1].getType().toString()) {
|
|
1577
|
+
matchMtd = mtd;
|
|
1578
|
+
break;
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
const argus = {
|
|
1582
|
+
realGenericTypes: undefined,
|
|
1583
|
+
args: args,
|
|
1584
|
+
argPositions: argPositionsAll,
|
|
1585
|
+
};
|
|
1586
|
+
if (!matchMtd) {
|
|
1587
|
+
return this.cxxGenerateInvokeValueAndStmts(cxxOperatorCallExpr.inner[0], argus, stmts, cxxOperatorCallExpr);
|
|
1588
|
+
}
|
|
1589
|
+
// Construct callNode
|
|
1590
|
+
const callNode = {
|
|
1591
|
+
code: cxxOperatorCallExpr.name,
|
|
1592
|
+
name: cxxOperatorCallExpr.name,
|
|
1593
|
+
kind: 'DeclRefExpr',
|
|
1594
|
+
inner: [],
|
|
1595
|
+
range: cxxOperatorCallExpr.range,
|
|
1596
|
+
type: cxxOperatorCallExpr.type,
|
|
1597
|
+
};
|
|
1598
|
+
const valueAndStmts = this.cxxGenerateInvokeValueAndStmts(callNode, argus, stmts, cxxOperatorCallExpr);
|
|
1599
|
+
if (valueAndStmts.value instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
1600
|
+
valueAndStmts.value.setMethodSignature(matchMtd.getSignature());
|
|
1601
|
+
}
|
|
1602
|
+
return valueAndStmts;
|
|
1603
|
+
}
|
|
1604
|
+
/* Build corresponding function call IR for overloading ordinary operators */
|
|
1605
|
+
buildInvokeValueForNormalOverloadedOp(cxxOperatorCallExpr) {
|
|
1606
|
+
var _a;
|
|
1607
|
+
// The child nodes of the overloaded operator node cannot be less than 2 (inner [0] is FunctionToPointerDecay,
|
|
1608
|
+
// and inner [1] is the instance object DeclRefExpr)
|
|
1609
|
+
const innerLen = (_a = cxxOperatorCallExpr.inner) === null || _a === void 0 ? void 0 : _a.length;
|
|
1610
|
+
if (!innerLen || innerLen < 2) {
|
|
1611
|
+
return null;
|
|
1612
|
+
}
|
|
1613
|
+
const stmts = [];
|
|
1614
|
+
const argNodes = innerLen === 2 ? [] : cxxOperatorCallExpr.inner.slice(2);
|
|
1615
|
+
// For example, when overloading operator+, a+b is equivalent to a.operator+(b), and the memberExpr of a.operator+is constructed as the caller
|
|
1616
|
+
const overloadOpName = this.getOverloadOpName(cxxOperatorCallExpr);
|
|
1617
|
+
const callNode = {
|
|
1618
|
+
code: cxxOperatorCallExpr.inner[1].code + '.' + overloadOpName,
|
|
1619
|
+
name: overloadOpName,
|
|
1620
|
+
range: cxxOperatorCallExpr.range,
|
|
1621
|
+
kind: 'MemberExpr',
|
|
1622
|
+
type: { qualType: '<bound member function type>' },
|
|
1623
|
+
inner: [cxxOperatorCallExpr.inner[1]],
|
|
1624
|
+
};
|
|
1625
|
+
return this.buildValueAndStmtsForMemberCall(stmts, callNode, argNodes, cxxOperatorCallExpr, undefined);
|
|
1626
|
+
}
|
|
1627
|
+
RecoverExpressionToValueAndStmts(callExpression) {
|
|
1628
|
+
const stmts = [];
|
|
1629
|
+
const [callNode, argumentNodes] = this.getArgumentNodeForRecover(callExpression.inner);
|
|
1630
|
+
const argus = this.cxxParseArgumentsOfCallExpression(stmts, argumentNodes);
|
|
1631
|
+
return this.cxxGenerateInvokeValueAndStmts(callNode, argus, stmts, callExpression);
|
|
1632
|
+
}
|
|
1633
|
+
/**
|
|
1634
|
+
*Generate the value and statement block of the C++call expression (ValueAndStmts).
|
|
1635
|
+
*
|
|
1636
|
+
*@ param functionNameNode - the node corresponding to the function name, which is used to resolve the caller information.
|
|
1637
|
+
*@ param argus - The object containing the actual generic type, parameter value list, and parameter location information.
|
|
1638
|
+
*- realGenericTypes: list of actual generic types.
|
|
1639
|
+
*- args: parameter value list.
|
|
1640
|
+
*- argPositions: The location information of the parameter in the source code.
|
|
1641
|
+
*@ param currStmts - List of existing statements. The newly generated statements will be appended on this basis.
|
|
1642
|
+
*@ param callExpression - represents the AST node of the call expression, which is used to obtain the call location information.
|
|
1643
|
+
*@ returns a ValueAndStmts object that contains the call value, value location information, and related statements.
|
|
1644
|
+
*/
|
|
1645
|
+
cxxGenerateInvokeValueAndStmts(functionNameNode, argus, currStmts, callExpression, returnType) {
|
|
1646
|
+
var _a;
|
|
1647
|
+
functionNameNode = functionNameNode !== null && functionNameNode !== void 0 ? functionNameNode : callExpression;
|
|
1648
|
+
const stmts = [...currStmts];
|
|
1649
|
+
let { value: callerValue, valueOriginalPositions: callerPositions, stmts: callerStmts, } = this.cxxNodeToValueAndStmts(functionNameNode);
|
|
1650
|
+
stmts.push(...callerStmts);
|
|
1651
|
+
let invokeValue;
|
|
1652
|
+
let invokeValuePositions = [Position_1.FullPosition.cxxBuildFromNode(callExpression, this.cxxSourceFile)];
|
|
1653
|
+
const { args, argPositions, realGenericTypes } = argus;
|
|
1654
|
+
if (callerValue instanceof Ref_1.AbstractFieldRef) {
|
|
1655
|
+
invokeValue = this.buildInvokeValueForFieldRef(callerValue, args, realGenericTypes, invokeValuePositions, callerPositions, returnType);
|
|
1656
|
+
}
|
|
1657
|
+
else if (callerValue instanceof Local_1.Local) {
|
|
1658
|
+
const callerName = callerValue.getName();
|
|
1659
|
+
let classSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildClassSignatureFromClassName(callerName);
|
|
1660
|
+
let cls = ModelUtils_1.ModelUtils.getClass(this.declaringMethod, classSignature);
|
|
1661
|
+
const callExprs = [ArkCxxAstNode_1.astKind.CallExpr, ArkCxxAstNode_1.astKind.CXXOperatorCallExpr];
|
|
1662
|
+
if ((cls === null || cls === void 0 ? void 0 : cls.hasComponentDecorator()) && callExprs.includes(callExpression.kind)) {
|
|
1663
|
+
return this.cxxGenerateCustomViewStmt(callerName, args, argPositions, callExpression, stmts);
|
|
1664
|
+
}
|
|
1665
|
+
else if (callerName === EtsConst_1.COMPONENT_FOR_EACH || callerName === EtsConst_1.COMPONENT_LAZY_FOR_EACH) {
|
|
1666
|
+
// foreach/lazyforeach will be parsed as ts.callExpression
|
|
1667
|
+
return this.cxxGenerateSystemComponentStmt(callerName, args, argPositions, callExpression, stmts);
|
|
1668
|
+
}
|
|
1669
|
+
const methodSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildMethodSignatureFromMethodName(callerName);
|
|
1670
|
+
const callerType = callerValue.getType();
|
|
1671
|
+
if (callerType instanceof Type_1.FunctionType || (callerType instanceof Type_2.PointerType && callerType.getBaseType() instanceof Type_1.FunctionType) ||
|
|
1672
|
+
!((_a = this.getGlobals()) === null || _a === void 0 ? void 0 : _a.has(callerName))) {
|
|
1673
|
+
invokeValue = new Expr_1.ArkPtrInvokeExpr(methodSignature, callerValue, args, realGenericTypes);
|
|
1674
|
+
}
|
|
1675
|
+
else {
|
|
1676
|
+
invokeValue = new Expr_1.ArkStaticInvokeExpr(methodSignature, args, realGenericTypes);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
else {
|
|
1680
|
+
({
|
|
1681
|
+
value: callerValue,
|
|
1682
|
+
stmts: callerStmts,
|
|
1683
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(callerValue, callerPositions));
|
|
1684
|
+
stmts.push(...callerStmts);
|
|
1685
|
+
const methodSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildMethodSignatureFromMethodName(callerValue.getName());
|
|
1686
|
+
invokeValue = new Expr_1.ArkStaticInvokeExpr(methodSignature, args, realGenericTypes);
|
|
1687
|
+
}
|
|
1688
|
+
invokeValuePositions.push(...argPositions);
|
|
1689
|
+
return {
|
|
1690
|
+
value: invokeValue,
|
|
1691
|
+
valueOriginalPositions: invokeValuePositions,
|
|
1692
|
+
stmts: stmts,
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
/**
|
|
1696
|
+
*IR Processing of C++Function Calls
|
|
1697
|
+
*@ param callExpression - C++AST node, representing member call expression
|
|
1698
|
+
*@ returns ValueAndStmts object, including converted values and related statements
|
|
1699
|
+
*/
|
|
1700
|
+
cxxMemberCallExpressionToValueAndStmts(callExpression) {
|
|
1701
|
+
var _a, _b, _c, _d;
|
|
1702
|
+
if (((_d = (_c = ((_a = callExpression.parent) !== null && _a !== void 0 ? _a : (_b = callExpression.getParent) === null || _b === void 0 ? void 0 : _b.call(callExpression, true))) === null || _c === void 0 ? void 0 : _c.type) === null || _d === void 0 ? void 0 : _d.qualType) === 'std::thread') {
|
|
1703
|
+
return this.cxxNewExpressionToValueAndStmts(callExpression);
|
|
1704
|
+
}
|
|
1705
|
+
const cxxMemberCallExprType = (0, builderUtils_1.cxxNode2Type)(callExpression, this.declaringMethod, this.cxxSourceFile, callExpression);
|
|
1706
|
+
let realGenericTypes;
|
|
1707
|
+
const stmts = [];
|
|
1708
|
+
const [_, rightNodes] = this.getArgumentNode(callExpression.inner);
|
|
1709
|
+
return this.buildValueAndStmtsForMemberCall(stmts, callExpression.inner[0], rightNodes, callExpression, realGenericTypes, cxxMemberCallExprType);
|
|
1710
|
+
}
|
|
1711
|
+
/**
|
|
1712
|
+
*Build values and statements called by members
|
|
1713
|
+
*@ param stmts statement array, used to collect generated statements
|
|
1714
|
+
*@ param callerNode Caller Node
|
|
1715
|
+
*@ param argNodes parameter node array
|
|
1716
|
+
*@ param callExpression calls the expression node
|
|
1717
|
+
*@ param realGenericTypes Actual generic type array
|
|
1718
|
+
*@ returns The ValueAndStmts object containing values, location information, and statements
|
|
1719
|
+
*/
|
|
1720
|
+
buildValueAndStmtsForMemberCall(stmts, callerNode, argNodes, callExpression, realGenericTypes, cxxMemberCallExprType) {
|
|
1721
|
+
const { args, argPositions: argPositionsAll } = this.cxxParseArguments(stmts, argNodes);
|
|
1722
|
+
const argPositionsAllFlat = argPositionsAll.flat();
|
|
1723
|
+
let { value: callerValue, valueOriginalPositions: callerPositions, stmts: callerStmts, } = this.cxxNodeToValueAndStmts(callerNode);
|
|
1724
|
+
stmts.push(...callerStmts);
|
|
1725
|
+
let invokeValue;
|
|
1726
|
+
let invokeValuePositions = [Position_1.FullPosition.cxxBuildFromNode(callExpression, this.cxxSourceFile)];
|
|
1727
|
+
if (callerValue instanceof Ref_1.ArkInstanceFieldRef) {
|
|
1728
|
+
invokeValue = this.buildInvokeValueForFieldRef(callerValue, args, realGenericTypes, invokeValuePositions, callerPositions, cxxMemberCallExprType);
|
|
1729
|
+
}
|
|
1730
|
+
else if (callerValue instanceof Local_1.Local) {
|
|
1731
|
+
invokeValue = this.buildInvokeValueForLocal(callerValue, args, realGenericTypes, cxxMemberCallExprType);
|
|
1732
|
+
}
|
|
1733
|
+
else {
|
|
1734
|
+
({
|
|
1735
|
+
value: callerValue,
|
|
1736
|
+
valueOriginalPositions: callerPositions,
|
|
1737
|
+
stmts: callerStmts,
|
|
1738
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(callerValue, callerPositions));
|
|
1739
|
+
stmts.push(...callerStmts);
|
|
1740
|
+
const methodSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildMethodSignatureFromMethodName(callerValue.getName());
|
|
1741
|
+
invokeValue = new Expr_1.ArkStaticInvokeExpr(methodSignature, args, realGenericTypes);
|
|
1742
|
+
invokeValuePositions.push(...argPositionsAllFlat);
|
|
1743
|
+
}
|
|
1744
|
+
invokeValuePositions.push(...argPositionsAllFlat);
|
|
1745
|
+
return {
|
|
1746
|
+
value: invokeValue,
|
|
1747
|
+
valueOriginalPositions: invokeValuePositions,
|
|
1748
|
+
stmts: stmts,
|
|
1749
|
+
};
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1752
|
+
*Build the call value referenced by the field
|
|
1753
|
+
*
|
|
1754
|
+
*@ param callerValue The caller value indicates the field reference
|
|
1755
|
+
*@ param args calls the parameter array
|
|
1756
|
+
*@ param realGenericTypes The actual generic type array may be undefined
|
|
1757
|
+
*@ param invokeValuePositions calls the value position information array
|
|
1758
|
+
*@ param callerPositions Caller position information array
|
|
1759
|
+
*@ returns the ArkInstanceFieldRef or ArkStaticInvokeExpr instance
|
|
1760
|
+
*/
|
|
1761
|
+
buildInvokeValueForFieldRef(callerValue, args, realGenericTypes, invokeValuePositions, callerPositions, returnType) {
|
|
1762
|
+
let methodSignature;
|
|
1763
|
+
const declareSignature = callerValue.getFieldSignature().getDeclaringSignature();
|
|
1764
|
+
if (declareSignature instanceof ArkSignature_1.ClassSignature) {
|
|
1765
|
+
methodSignature = new ArkSignature_1.MethodSignature(declareSignature, ArkSignatureBuilder_1.ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(callerValue.getFieldName()));
|
|
1766
|
+
}
|
|
1767
|
+
else {
|
|
1768
|
+
methodSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildMethodSignatureFromMethodName(callerValue.getFieldName());
|
|
1769
|
+
}
|
|
1770
|
+
methodSignature.getMethodSubSignature().setReturnType(returnType !== null && returnType !== void 0 ? returnType : Type_1.UnknownType.getInstance());
|
|
1771
|
+
if (callerValue instanceof Ref_1.ArkInstanceFieldRef) {
|
|
1772
|
+
invokeValuePositions.push(...callerPositions.slice());
|
|
1773
|
+
return new Expr_1.ArkInstanceInvokeExpr(callerValue.getBase(), methodSignature, args, realGenericTypes);
|
|
1774
|
+
}
|
|
1775
|
+
else {
|
|
1776
|
+
return new Expr_1.ArkStaticInvokeExpr(methodSignature, args, realGenericTypes);
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
buildInvokeValueForLocal(callerValue, args, realGenericTypes, cxxMemberCallExprType) {
|
|
1780
|
+
const callerName = callerValue.getName();
|
|
1781
|
+
const methodSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildMethodSignatureFromMethodName(callerName);
|
|
1782
|
+
methodSignature.getMethodSubSignature().setReturnType(cxxMemberCallExprType !== null && cxxMemberCallExprType !== void 0 ? cxxMemberCallExprType : Type_1.UnknownType.getInstance());
|
|
1783
|
+
if (callerValue.getType() instanceof Type_1.FunctionType) {
|
|
1784
|
+
return new Expr_1.ArkPtrInvokeExpr(methodSignature, callerValue, args, realGenericTypes);
|
|
1785
|
+
}
|
|
1786
|
+
else {
|
|
1787
|
+
return new Expr_1.ArkStaticInvokeExpr(methodSignature, args, realGenericTypes);
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
cxxParseArgumentsOfCallExpression(currStmts, callExpression, callNode) {
|
|
1791
|
+
let realGenericTypes = this.getRealGenericTypes(callNode);
|
|
1792
|
+
let builderMethodIndexes;
|
|
1793
|
+
const { args: args, argPositions: argPositions, } = this.cxxParseArguments(currStmts, callExpression, builderMethodIndexes);
|
|
1794
|
+
return {
|
|
1795
|
+
realGenericTypes: realGenericTypes,
|
|
1796
|
+
args: args,
|
|
1797
|
+
argPositions: argPositions,
|
|
1798
|
+
};
|
|
1799
|
+
}
|
|
1800
|
+
getRealGenericTypes(node, qualType) {
|
|
1801
|
+
if (!node) {
|
|
1802
|
+
return undefined;
|
|
1803
|
+
}
|
|
1804
|
+
// 1. Determine the target type string
|
|
1805
|
+
const nodeType = this.getTargetQualType(node, qualType);
|
|
1806
|
+
if (!nodeType) {
|
|
1807
|
+
return undefined;
|
|
1808
|
+
}
|
|
1809
|
+
// 2. Extract and split template content
|
|
1810
|
+
const match = nodeType.match(/<(.*)>/);
|
|
1811
|
+
if (!match || !match[1]) {
|
|
1812
|
+
return undefined;
|
|
1813
|
+
}
|
|
1814
|
+
const members = this.splitTemplateArguments(match[1]);
|
|
1815
|
+
// 3. Map to Type objects
|
|
1816
|
+
return members.map(arg => (0, builderUtils_1.buildTypeFromPreStr)(arg, node, this.declaringMethod));
|
|
1817
|
+
}
|
|
1818
|
+
/**
|
|
1819
|
+
* Resolves the type string based on priority (provided qualType > desugared > default).
|
|
1820
|
+
*/
|
|
1821
|
+
getTargetQualType(node, qualType) {
|
|
1822
|
+
if (qualType) {
|
|
1823
|
+
return qualType;
|
|
1824
|
+
}
|
|
1825
|
+
return (node.type.desugaredQualType && node.type.typeAliasDeclId)
|
|
1826
|
+
? node.type.desugaredQualType
|
|
1827
|
+
: node.type.qualType;
|
|
1828
|
+
}
|
|
1829
|
+
/**
|
|
1830
|
+
* Splits template arguments by comma, but remains aware of nested brackets
|
|
1831
|
+
* to prevent incorrect splitting of nested templates.
|
|
1832
|
+
*/
|
|
1833
|
+
splitTemplateArguments(content) {
|
|
1834
|
+
const parts = [];
|
|
1835
|
+
let current = '';
|
|
1836
|
+
let depth = 0;
|
|
1837
|
+
for (const char of content) {
|
|
1838
|
+
if (char === '<') {
|
|
1839
|
+
depth++;
|
|
1840
|
+
}
|
|
1841
|
+
if (char === '>') {
|
|
1842
|
+
depth--;
|
|
1843
|
+
}
|
|
1844
|
+
if (char === ',' && depth === 0) {
|
|
1845
|
+
parts.push(current.trim());
|
|
1846
|
+
current = '';
|
|
1847
|
+
}
|
|
1848
|
+
else {
|
|
1849
|
+
current += char;
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
if (current.trim()) {
|
|
1853
|
+
parts.push(current.trim());
|
|
1854
|
+
}
|
|
1855
|
+
return parts;
|
|
1856
|
+
}
|
|
1857
|
+
cxxParseArguments(currStmts, argumentNodes, builderMethodIndexes) {
|
|
1858
|
+
const args = [];
|
|
1859
|
+
const argPositions = [];
|
|
1860
|
+
if (argumentNodes) {
|
|
1861
|
+
for (let i = 0; i < argumentNodes.length; i++) {
|
|
1862
|
+
if (argumentNodes[i].kind === ArkCxxAstNode_1.astKind.CXXDefaultArgExpr) {
|
|
1863
|
+
continue;
|
|
1864
|
+
}
|
|
1865
|
+
const argument = argumentNodes[i];
|
|
1866
|
+
const prevBuilderMethodContextFlag = this.builderMethodContextFlag;
|
|
1867
|
+
if (builderMethodIndexes === null || builderMethodIndexes === void 0 ? void 0 : builderMethodIndexes.has(i)) {
|
|
1868
|
+
this.builderMethodContextFlag = true;
|
|
1869
|
+
this.ArkCxxIRTransformer.setBuilderMethodContextFlag(true);
|
|
1870
|
+
}
|
|
1871
|
+
let { value: argValue, valueOriginalPositions: argPositionsSingle, stmts: argStmts, } = this.cxxNodeToValueAndStmts(argument);
|
|
1872
|
+
this.builderMethodContextFlag = prevBuilderMethodContextFlag;
|
|
1873
|
+
this.ArkCxxIRTransformer.setBuilderMethodContextFlag(prevBuilderMethodContextFlag);
|
|
1874
|
+
currStmts.push(...argStmts);
|
|
1875
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(argValue)) {
|
|
1876
|
+
({
|
|
1877
|
+
value: argValue,
|
|
1878
|
+
valueOriginalPositions: argPositionsSingle,
|
|
1879
|
+
stmts: argStmts,
|
|
1880
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(argValue, argPositionsSingle));
|
|
1881
|
+
currStmts.push(...argStmts);
|
|
1882
|
+
}
|
|
1883
|
+
args.push(argValue);
|
|
1884
|
+
argPositions.push(argPositionsSingle[0]);
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
return { args: args, argPositions: argPositions };
|
|
1888
|
+
}
|
|
1889
|
+
cxxCallableNodeToValueAndStmts(callableNode) {
|
|
1890
|
+
const declaringClass = this.declaringMethod.getDeclaringArkClass();
|
|
1891
|
+
const lambdaArkMethod = new ArkMethod_1.ArkMethod();
|
|
1892
|
+
(0, ArkMethodBuilder_1.buildArkMethodFromArkClass)(callableNode, declaringClass, lambdaArkMethod, this.cxxSourceFile, this.declaringMethod);
|
|
1893
|
+
const callableType = new Type_1.FunctionType(lambdaArkMethod.getSignature());
|
|
1894
|
+
const callableValue = this.addNewLocal(lambdaArkMethod.getName(), callableType);
|
|
1895
|
+
return {
|
|
1896
|
+
value: callableValue,
|
|
1897
|
+
valueOriginalPositions: [Position_1.FullPosition.cxxBuildFromNode(callableNode, this.cxxSourceFile)],
|
|
1898
|
+
stmts: [],
|
|
1899
|
+
};
|
|
1900
|
+
}
|
|
1901
|
+
cxxNewExpressionToValueAndStmts(newExpression) {
|
|
1902
|
+
var _a, _b;
|
|
1903
|
+
let className = this.getNewExpressionClassName(newExpression);
|
|
1904
|
+
// Add handling for dynamic array creation: int *arr = new int[10]
|
|
1905
|
+
if (className === Builtin_1.Builtin.ARRAY || newExpression.isArray) {
|
|
1906
|
+
return this.cxxNewArrayExpressionToValueAndStmts(newExpression);
|
|
1907
|
+
}
|
|
1908
|
+
const stmts = [];
|
|
1909
|
+
let realGenericTypes = this.getRealGenericTypes(newExpression);
|
|
1910
|
+
// Handle the scenarios of namespace::Member and class::member
|
|
1911
|
+
const parentClassOrNs = (_a = newExpression.getParent) === null || _a === void 0 ? void 0 : _a.call(newExpression, true).inner.filter(inn => [ArkCxxAstNode_1.astKind.TypeRef, ArkCxxAstNode_1.astKind.NamespaceRef].includes(inn.kind));
|
|
1912
|
+
let refType = null;
|
|
1913
|
+
// If the parent node has a namespaceRef or TypeRef, it indicates a constructor call,
|
|
1914
|
+
// and should infer the type of the corresponding namespace/class.
|
|
1915
|
+
if (parentClassOrNs && parentClassOrNs.length > 0) {
|
|
1916
|
+
refType = (_b = TypeInference_1.TypeInference.inferUnclearRefName(className, this.declaringMethod.getDeclaringArkClass())) !== null && _b !== void 0 ? _b : (0, builderUtils_1.cxxNode2Type)(newExpression, this.declaringMethod.getDeclaringArkClass());
|
|
1917
|
+
}
|
|
1918
|
+
let classType;
|
|
1919
|
+
let classSignature;
|
|
1920
|
+
if (refType instanceof Type_1.ClassType) {
|
|
1921
|
+
classType = refType;
|
|
1922
|
+
}
|
|
1923
|
+
else if (refType instanceof Type_1.AliasType && refType.getOriginalType() instanceof Type_1.ClassType) {
|
|
1924
|
+
classType = refType.getOriginalType();
|
|
1925
|
+
}
|
|
1926
|
+
else {
|
|
1927
|
+
let curClass = this.declaringMethod.getDeclaringArkFile().getClassWithName(className);
|
|
1928
|
+
classSignature = curClass ? curClass.getSignature() : ArkSignatureBuilder_1.ArkSignatureBuilder.buildClassSignatureFromClassName(className);
|
|
1929
|
+
classType = new Type_1.ClassType(classSignature, realGenericTypes);
|
|
1930
|
+
}
|
|
1931
|
+
const expr = new Expr_1.ArkNewExpr(classType);
|
|
1932
|
+
const { value: newLocal, valueOriginalPositions: newLocalPositions, stmts: newExprStmts } = this.ArkCxxIRTransformer.generateAssignStmtForValue(expr, [Position_1.FullPosition.cxxBuildFromNode(newExpression, this.cxxSourceFile)]);
|
|
1933
|
+
// When using the new keyword, the type of Local should be a pointer type.
|
|
1934
|
+
if (newExpression.kind === ArkCxxAstNode_1.astKind.CXXNewExpr) {
|
|
1935
|
+
newLocal.setType(new Type_2.PointerType(classType, 1));
|
|
1936
|
+
}
|
|
1937
|
+
stmts.push(...newExprStmts);
|
|
1938
|
+
this.cxxEmitCtorInvokeAndMemberInits(stmts, newExpression, newLocal, newLocalPositions, classType, className);
|
|
1939
|
+
return { value: newLocal, valueOriginalPositions: newLocalPositions, stmts: stmts };
|
|
1940
|
+
}
|
|
1941
|
+
/**
|
|
1942
|
+
*Generate C++code representation of constructor calls and member initialization, and add related statements to stmts.
|
|
1943
|
+
* Extracted tail logic: construction call+special case processing+member initialization
|
|
1944
|
+
*@ param stmts - an array that stores the generated statement nodes
|
|
1945
|
+
*@ param newExpression - C++AST node representing new expression
|
|
1946
|
+
*@ param newLocal - local variable representing the newly created object
|
|
1947
|
+
*@ param newLocalPositions - the location information of the new local variable in the source code
|
|
1948
|
+
*@ param constructorMethodSignature - constructor's method signature
|
|
1949
|
+
*@ param className - the name of the current class, which is used for special processing of certain types (such as napi_property_descriptor)
|
|
1950
|
+
*/
|
|
1951
|
+
cxxEmitCtorInvokeAndMemberInits(stmts, newExpression, newLocal, newLocalPositions, classType, className) {
|
|
1952
|
+
// 对象构造,使用 invokeStmt 表达
|
|
1953
|
+
const constructArgs = (() => {
|
|
1954
|
+
var _a, _b;
|
|
1955
|
+
let args = newExpression.inner;
|
|
1956
|
+
if (newExpression.kind === ArkCxxAstNode_1.astKind.CXXNewExpr && ((_a = newExpression.inner[0]) === null || _a === void 0 ? void 0 : _a.kind) === ArkCxxAstNode_1.astKind.CXXConstructExpr) {
|
|
1957
|
+
return [...newExpression.inner[0].inner];
|
|
1958
|
+
}
|
|
1959
|
+
else if (newExpression.kind === ArkCxxAstNode_1.astKind.CompoundLiteralExpr) {
|
|
1960
|
+
return this.getConstructArgs(args);
|
|
1961
|
+
}
|
|
1962
|
+
else if (
|
|
1963
|
+
// if case : struct LargeStruct s;, inner.length is 0, so we need to avoid it
|
|
1964
|
+
newExpression.kind === ArkCxxAstNode_1.astKind.CXXConstructExpr &&
|
|
1965
|
+
newExpression.type.qualType.startsWith('struct') &&
|
|
1966
|
+
args.length > 0 && ((_b = args[0].inner[0]) === null || _b === void 0 ? void 0 : _b.kind) === ArkCxxAstNode_1.astKind.CompoundLiteralExpr) {
|
|
1967
|
+
return this.getConstructArgs(args[0].inner[0].inner);
|
|
1968
|
+
}
|
|
1969
|
+
else if (newExpression.kind === ArkCxxAstNode_1.astKind.InitListExpr) {
|
|
1970
|
+
return this.getConstructArgs(newExpression);
|
|
1971
|
+
}
|
|
1972
|
+
return args.filter(arg => (arg === null || arg === void 0 ? void 0 : arg.kind) !== ArkCxxAstNode_1.astKind.TemplateRef &&
|
|
1973
|
+
(arg === null || arg === void 0 ? void 0 : arg.kind) !== ArkCxxAstNode_1.astKind.NamespaceRef &&
|
|
1974
|
+
(arg === null || arg === void 0 ? void 0 : arg.kind) !== ArkCxxAstNode_1.astKind.TypeRef);
|
|
1975
|
+
})();
|
|
1976
|
+
const { args: argValues, argPositions } = this.cxxParseArguments(stmts, constructArgs);
|
|
1977
|
+
const constructorMethodSignature = this.getConstructorSignatureByClassTypeAndArgs(classType, argValues);
|
|
1978
|
+
const instanceInvokeExpr = new Expr_1.ArkInstanceInvokeExpr(newLocal, constructorMethodSignature, argValues);
|
|
1979
|
+
const invokeStmt = new Stmt_1.ArkInvokeStmt(instanceInvokeExpr);
|
|
1980
|
+
const instanceInvokeExprPositions = [newLocalPositions[0], ...newLocalPositions, ...argPositions];
|
|
1981
|
+
invokeStmt.setOperandOriginalPositions(instanceInvokeExprPositions);
|
|
1982
|
+
stmts.push(invokeStmt);
|
|
1983
|
+
// Processing the interface between cpp and ts
|
|
1984
|
+
if (className === 'napi_property_descriptor') {
|
|
1985
|
+
(0, ModelUtils_2.setTs2CxxFuncMapOfClass)(argValues, false, this.declaringMethod);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
getConstructorSignatureByClassTypeAndArgs(classType, args) {
|
|
1989
|
+
const file = this.declaringMethod.getDeclaringArkFile();
|
|
1990
|
+
const arkClass = file.getClass(classType.getClassSignature());
|
|
1991
|
+
const constructorMethodSubSignature = ArkSignatureBuilder_1.ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(TSConst_1.CONSTRUCTOR_NAME);
|
|
1992
|
+
if (!arkClass) {
|
|
1993
|
+
return new ArkSignature_1.MethodSignature(ArkSignatureBuilder_1.ArkSignatureBuilder.buildClassSignatureFromClassName(classType.getClassSignature().getClassName()), constructorMethodSubSignature);
|
|
1994
|
+
}
|
|
1995
|
+
const constructors = arkClass.getMethodsWithName(TSConst_1.CONSTRUCTOR_NAME);
|
|
1996
|
+
if (constructors.length === 0) {
|
|
1997
|
+
return new ArkSignature_1.MethodSignature(classType.getClassSignature(), constructorMethodSubSignature);
|
|
1998
|
+
}
|
|
1999
|
+
else if (constructors.length === 1) {
|
|
2000
|
+
return constructors[0].getSignature();
|
|
2001
|
+
}
|
|
2002
|
+
const argsStr = args.map(arg => arg.getType().toString());
|
|
2003
|
+
for (const constructor of constructors) {
|
|
2004
|
+
const paramTypes = constructor.getSignature().getMethodSubSignature().getParameterTypes();
|
|
2005
|
+
if (paramTypes.length !== args.length) {
|
|
2006
|
+
continue;
|
|
2007
|
+
}
|
|
2008
|
+
for (const [idx, paramType] of paramTypes.entries()) {
|
|
2009
|
+
const paramTypeStr = paramType.toString();
|
|
2010
|
+
if (!paramTypeStr.includes(argsStr[idx]) && !argsStr[idx].includes(paramTypeStr)) {
|
|
2011
|
+
break;
|
|
2012
|
+
}
|
|
2013
|
+
if (idx === paramTypes.length - 1) {
|
|
2014
|
+
return constructor.getSignature();
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
return new ArkSignature_1.MethodSignature(classType.getClassSignature(), constructorMethodSubSignature);
|
|
2019
|
+
}
|
|
2020
|
+
getConstructArgs(constructArgs) {
|
|
2021
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2022
|
+
// 1) Regularize to "parameter array"
|
|
2023
|
+
let arr;
|
|
2024
|
+
if (Array.isArray(constructArgs)) {
|
|
2025
|
+
arr = constructArgs;
|
|
2026
|
+
}
|
|
2027
|
+
else if (constructArgs.kind === ArkCxxAstNode_1.astKind.InitListExpr) {
|
|
2028
|
+
arr = (_a = constructArgs.inner) !== null && _a !== void 0 ? _a : [];
|
|
2029
|
+
}
|
|
2030
|
+
else {
|
|
2031
|
+
// Parameters of some scenarios (such as CXXConstructExpr) may be placed in InitListExpr of inner [1]
|
|
2032
|
+
arr = (_b = constructArgs.inner) !== null && _b !== void 0 ? _b : [];
|
|
2033
|
+
}
|
|
2034
|
+
// 2) If the second element itself is InitListExpr, take its inner as the real parameter
|
|
2035
|
+
if (((_c = arr[1]) === null || _c === void 0 ? void 0 : _c.kind) === ArkCxxAstNode_1.astKind.InitListExpr) {
|
|
2036
|
+
arr = (_d = arr[1].inner) !== null && _d !== void 0 ? _d : [];
|
|
2037
|
+
}
|
|
2038
|
+
// 3) If there is "implicit conversion" (original logic: check whether the second element is ImplicitCastExpr)
|
|
2039
|
+
const useInner1 = ((_e = arr[1]) === null || _e === void 0 ? void 0 : _e.kind) === ArkCxxAstNode_1.astKind.ImplicitCastExpr;
|
|
2040
|
+
// 4) Generate a new parameter list (equivalent to the original logic)
|
|
2041
|
+
const newConstructArgs = [];
|
|
2042
|
+
for (let i = 0; i < arr.length; i++) {
|
|
2043
|
+
if (useInner1) {
|
|
2044
|
+
const inner1 = (_g = (_f = arr[i]) === null || _f === void 0 ? void 0 : _f.inner) === null || _g === void 0 ? void 0 : _g[1];
|
|
2045
|
+
newConstructArgs.push(inner1 !== null && inner1 !== void 0 ? inner1 : arr[i]); // 防御:缺少 inner[1] 时退回 arr[i]
|
|
2046
|
+
}
|
|
2047
|
+
else {
|
|
2048
|
+
newConstructArgs.push(arr[i]);
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
return newConstructArgs;
|
|
2052
|
+
}
|
|
2053
|
+
/**
|
|
2054
|
+
*Get the class name of the new expression
|
|
2055
|
+
*@ param newExpression - new expression node of CxxAstNode type
|
|
2056
|
+
*@ returns the processed class name string
|
|
2057
|
+
*/
|
|
2058
|
+
getNewExpressionClassName(newExpression) {
|
|
2059
|
+
let oriType = '';
|
|
2060
|
+
if (newExpression.type.desugaredQualType) {
|
|
2061
|
+
oriType = newExpression.type.desugaredQualType.replace(Builtin_2.BuiltinCxx.ANONYMOUS_NAMESPACE_REF, '');
|
|
2062
|
+
}
|
|
2063
|
+
else if (newExpression.type.qualType) {
|
|
2064
|
+
oriType = newExpression.type.qualType;
|
|
2065
|
+
}
|
|
2066
|
+
else if (newExpression.code) {
|
|
2067
|
+
oriType = newExpression.code;
|
|
2068
|
+
}
|
|
2069
|
+
oriType = this.removeOutermostTemplateArgs(oriType);
|
|
2070
|
+
if ((0, builderUtils_1.isCXXSTLContainer)(oriType)) {
|
|
2071
|
+
return oriType;
|
|
2072
|
+
}
|
|
2073
|
+
return oriType.replace(/[()]|\ \*|struct\ |union\ |const\ /g, '');
|
|
2074
|
+
}
|
|
2075
|
+
/**
|
|
2076
|
+
*Remove the outermost template parameter (angle brackets and their contents) from the string
|
|
2077
|
+
*@ param typeStr is a type string containing template parameters
|
|
2078
|
+
*@ returns string after removing the outermost template parameter
|
|
2079
|
+
*/
|
|
2080
|
+
removeOutermostTemplateArgs(typeStr) {
|
|
2081
|
+
// Find the position of the first '<'
|
|
2082
|
+
const start = typeStr.indexOf('<');
|
|
2083
|
+
if (start === -1) {
|
|
2084
|
+
return typeStr; // Cannot find '<', return the original string directly
|
|
2085
|
+
}
|
|
2086
|
+
let bracketCount = 1;
|
|
2087
|
+
let end = -1;
|
|
2088
|
+
// Starting from the first '<', search and calculate bracket matches
|
|
2089
|
+
for (let i = start + 1; i < typeStr.length; i++) {
|
|
2090
|
+
if (typeStr[i] === '<') {
|
|
2091
|
+
bracketCount++;
|
|
2092
|
+
}
|
|
2093
|
+
else if (typeStr[i] === '>') {
|
|
2094
|
+
bracketCount--;
|
|
2095
|
+
if (bracketCount === 0) {
|
|
2096
|
+
end = i;
|
|
2097
|
+
break;
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
// If a matching ending '>' is found, remove this paragraph
|
|
2102
|
+
if (end !== -1) {
|
|
2103
|
+
return typeStr.substring(0, start) + typeStr.substring(end + 1);
|
|
2104
|
+
}
|
|
2105
|
+
return typeStr;
|
|
2106
|
+
}
|
|
2107
|
+
/**
|
|
2108
|
+
*Convert the new array expression of C++to ValueAndStmts
|
|
2109
|
+
*@ param newArrayExpression - C++AST node, representing new array expression
|
|
2110
|
+
*@ returns ValueAndStmts object, including converted values and related statements
|
|
2111
|
+
*/
|
|
2112
|
+
cxxNewArrayExpressionToValueAndStmts(newArrayExpression) {
|
|
2113
|
+
let baseType = Type_1.UnknownType.getInstance();
|
|
2114
|
+
if (newArrayExpression.type.qualType) {
|
|
2115
|
+
const argumentType = (0, builderUtils_1.cxxNode2Type)(newArrayExpression, this.declaringMethod);
|
|
2116
|
+
if (!(argumentType instanceof Type_1.AnyType || argumentType instanceof Type_1.UnknownType)) {
|
|
2117
|
+
baseType = argumentType;
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
const stmts = [];
|
|
2121
|
+
const { args: argumentValues, argPositions: argPositions, } = this.cxxParseArguments(stmts, newArrayExpression.inner);
|
|
2122
|
+
let argumentsLength = newArrayExpression.inner ? newArrayExpression.inner.length : 0;
|
|
2123
|
+
let arrayLengthValue;
|
|
2124
|
+
let fromLiteral; // Does it contain specific elements
|
|
2125
|
+
let arrayLengthPosition = Position_1.FullPosition.DEFAULT;
|
|
2126
|
+
if (argumentsLength === 1 && (argumentValues[0].getType() instanceof Type_1.NumberType || argumentValues[0].getType() instanceof Type_1.UnknownType)) {
|
|
2127
|
+
arrayLengthValue = argumentValues[0];
|
|
2128
|
+
arrayLengthPosition = argPositions[0];
|
|
2129
|
+
fromLiteral = false;
|
|
2130
|
+
}
|
|
2131
|
+
else {
|
|
2132
|
+
arrayLengthValue = ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(argumentsLength);
|
|
2133
|
+
fromLiteral = true;
|
|
2134
|
+
}
|
|
2135
|
+
if (baseType instanceof Type_1.UnknownType) {
|
|
2136
|
+
if (argumentsLength > 1 && !(argumentValues[0].getType() instanceof Type_1.UnknownType)) {
|
|
2137
|
+
baseType = argumentValues[0].getType();
|
|
2138
|
+
}
|
|
2139
|
+
else {
|
|
2140
|
+
baseType = Type_1.AnyType.getInstance();
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
const newArrayExprPosition = Position_1.FullPosition.cxxBuildFromNode(newArrayExpression, this.cxxSourceFile);
|
|
2144
|
+
return this.cxxGenerateArrayExprAndStmts(baseType, arrayLengthValue, arrayLengthPosition, argumentValues, argPositions, stmts, newArrayExprPosition, fromLiteral);
|
|
2145
|
+
}
|
|
2146
|
+
/**
|
|
2147
|
+
*Convert C++array literal expression to ValueAndStmts
|
|
2148
|
+
*@ param arrayLiteralExpression - Array literal node in C++abstract syntax tree
|
|
2149
|
+
*@ returns The ValueAndStmts object containing the converted value and related statements
|
|
2150
|
+
*/
|
|
2151
|
+
cxxArrayLiteralExpressionToValueAndStmts(arrayLiteralExpression, dimensions, isInitZero) {
|
|
2152
|
+
var _a, _b, _c, _d;
|
|
2153
|
+
const stmts = [];
|
|
2154
|
+
const elementTypes = new Set();
|
|
2155
|
+
const elementValues = [];
|
|
2156
|
+
const elementPositions = [];
|
|
2157
|
+
const oriType = arrayLiteralExpression.type.qualType;
|
|
2158
|
+
let arrayLength = 0; // Indicate the length of the array
|
|
2159
|
+
let elementsNumber = 0; // Indicates the total number of elements included
|
|
2160
|
+
if (!dimensions) {
|
|
2161
|
+
// Obtain dimensional information
|
|
2162
|
+
dimensions = this.getArrayDimensions(oriType);
|
|
2163
|
+
}
|
|
2164
|
+
arrayLength = (_a = dimensions[0]) !== null && _a !== void 0 ? _a : arrayLiteralExpression.inner.length;
|
|
2165
|
+
elementsNumber = (_b = dimensions.reduce((acc, cur) => acc * cur, 1)) !== null && _b !== void 0 ? _b : arrayLength;
|
|
2166
|
+
dimensions.shift();
|
|
2167
|
+
isInitZero = (((_c = arrayLiteralExpression.inner) === null || _c === void 0 ? void 0 : _c.length) === 1 && arrayLiteralExpression.inner[0].code === '0' ||
|
|
2168
|
+
((_d = arrayLiteralExpression.inner) === null || _d === void 0 ? void 0 : _d.length) === 0);
|
|
2169
|
+
this.getArrayLiteralExpression(arrayLiteralExpression, stmts, elementTypes, elementValues, elementPositions, dimensions, isInitZero);
|
|
2170
|
+
if ((0, builderUtils_1.isCxxFunctionPointer)(oriType)) {
|
|
2171
|
+
// If it's an array of function pointers, the array symbols in the type should be removed here before resolving for the base type.
|
|
2172
|
+
arrayLiteralExpression.type.qualType = arrayLiteralExpression.type.qualType.replace(/\[.*?\]/g, '');
|
|
2173
|
+
}
|
|
2174
|
+
let baseType = (0, builderUtils_1.cxxNode2Type)(arrayLiteralExpression, this.declaringMethod);
|
|
2175
|
+
arrayLiteralExpression.type.qualType = oriType;
|
|
2176
|
+
if (baseType === Type_1.UnknownType.getInstance()) {
|
|
2177
|
+
// If the type is uncertain, it is regarded as an unknown reference type
|
|
2178
|
+
return this.cxxNewExpressionToValueAndStmts(arrayLiteralExpression);
|
|
2179
|
+
}
|
|
2180
|
+
const newArrayExprPosition = Position_1.FullPosition.cxxBuildFromNode(arrayLiteralExpression, this.cxxSourceFile);
|
|
2181
|
+
return this.cxxGenerateArrayExprAndStmts(baseType, ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(arrayLength), Position_1.FullPosition.DEFAULT, elementValues, elementPositions, stmts, newArrayExprPosition, true, elementsNumber, isInitZero);
|
|
2182
|
+
}
|
|
2183
|
+
// Analyze array dimension information
|
|
2184
|
+
getArrayDimensions(declaration) {
|
|
2185
|
+
// Extract all dimensional numbers using regular expressions
|
|
2186
|
+
const dimensions = declaration.match(/\[(\d+)\]/g);
|
|
2187
|
+
if (!dimensions) {
|
|
2188
|
+
return [];
|
|
2189
|
+
}
|
|
2190
|
+
// Parse numbers and return a dimension array
|
|
2191
|
+
return dimensions
|
|
2192
|
+
.map(dim => parseInt(dim.replace(/[\[\]]/g, '')));
|
|
2193
|
+
}
|
|
2194
|
+
/**
|
|
2195
|
+
*Process array literal expression and convert it to intermediate representation
|
|
2196
|
+
*@ param arrayLiteralExpression array literal expression node
|
|
2197
|
+
*@ param stmts is used to collect the generated statement list
|
|
2198
|
+
*@ param elementTypes is used to collect the collection of array element types
|
|
2199
|
+
*@ param elementValues is used to collect the list of array element values
|
|
2200
|
+
*@ param elementPositions is used to collect the list of array element position information
|
|
2201
|
+
*/
|
|
2202
|
+
getArrayLiteralExpression(arrayLiteralExpression, stmts, elementTypes, elementValues, elementPositions, dimensions, isInitZero) {
|
|
2203
|
+
for (const element of arrayLiteralExpression.inner) {
|
|
2204
|
+
// If there is still dimension information in the array, build an internal array
|
|
2205
|
+
let { value: elementValue, valueOriginalPositions: elementPosition, stmts: elementStmts } = dimensions.length > 0 ? this.cxxArrayLiteralExpressionToValueAndStmts(element, dimensions) : this.cxxNodeToValueAndStmts(element);
|
|
2206
|
+
stmts.push(...elementStmts);
|
|
2207
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(elementValue)) {
|
|
2208
|
+
({
|
|
2209
|
+
value: elementValue,
|
|
2210
|
+
valueOriginalPositions: elementPosition,
|
|
2211
|
+
stmts: elementStmts,
|
|
2212
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(elementValue, elementPosition));
|
|
2213
|
+
stmts.push(...elementStmts);
|
|
2214
|
+
}
|
|
2215
|
+
elementValues.push(elementValue);
|
|
2216
|
+
elementTypes.add(elementValue.getType());
|
|
2217
|
+
elementPositions.push(elementPosition[0]);
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
/**
|
|
2221
|
+
*Generate IR expressed by C++array
|
|
2222
|
+
*
|
|
2223
|
+
*@ param baseType - the basic type of the array element
|
|
2224
|
+
*@ param arrayLengthValue - value object of array length
|
|
2225
|
+
*@ param arrayLengthPosition - position information of array length
|
|
2226
|
+
*@ param arrayLength - the actual length of the array
|
|
2227
|
+
*@ param initializerValues - array initialization value list
|
|
2228
|
+
*@ param initializerPositions - List of location information of initialization values
|
|
2229
|
+
*@ param currStmts - List of existing statements
|
|
2230
|
+
*@ param newArrayExprPosition - position information of the new array expression
|
|
2231
|
+
*@ param fromLiteral - whether from literal
|
|
2232
|
+
*@ returns The ValueAndStmts object containing values and statements
|
|
2233
|
+
*/
|
|
2234
|
+
cxxGenerateArrayExprAndStmts(baseType, arrayLengthValue, arrayLengthPosition, initializerValues, initializerPositions, currStmts, newArrayExprPosition, fromLiteral, elementsNumber, isInitZero) {
|
|
2235
|
+
var _a;
|
|
2236
|
+
const stmts = [...currStmts];
|
|
2237
|
+
const newArrayExpr = new Expr_2.ArkCxxNewArrayExpr(baseType, arrayLengthValue, fromLiteral, elementsNumber);
|
|
2238
|
+
const newArrayExprPositions = [newArrayExprPosition, arrayLengthPosition];
|
|
2239
|
+
const { value: arrayLocal, valueOriginalPositions: arrayLocalPositions, stmts: arrayStmts, } = this.ArkCxxIRTransformer.generateAssignStmtForValue(newArrayExpr, newArrayExprPositions);
|
|
2240
|
+
stmts.push(...arrayStmts);
|
|
2241
|
+
const initializerZero = ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(0);
|
|
2242
|
+
for (let i = 0; i < initializerValues.length; i++) {
|
|
2243
|
+
// If the array is initialized with 0 or does not contain specific elements, do not create element statements
|
|
2244
|
+
if (isInitZero || !fromLiteral) {
|
|
2245
|
+
break;
|
|
2246
|
+
}
|
|
2247
|
+
const indexValue = ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(i);
|
|
2248
|
+
const arrayRef = new Ref_1.ArkArrayRef(arrayLocal, indexValue);
|
|
2249
|
+
const arrayRefPositions = [arrayLocalPositions[0], ...arrayLocalPositions, Position_1.FullPosition.DEFAULT];
|
|
2250
|
+
const assignStmt = new Stmt_1.ArkAssignStmt(arrayRef, initializerValues[i]);
|
|
2251
|
+
assignStmt.setOperandOriginalPositions([...arrayRefPositions, initializerPositions[i]]);
|
|
2252
|
+
stmts.push(assignStmt);
|
|
2253
|
+
}
|
|
2254
|
+
if (isInitZero) {
|
|
2255
|
+
// When the array is initialized to 0, initialize Values only contains one element for use by the upper layer
|
|
2256
|
+
let initExpr = new Expr_2.ArkCxxInitArrayExpr((_a = initializerValues[0]) !== null && _a !== void 0 ? _a : initializerZero);
|
|
2257
|
+
let assignStmt = new Stmt_1.ArkAssignStmt(arrayLocal, initExpr);
|
|
2258
|
+
stmts.push(assignStmt);
|
|
2259
|
+
}
|
|
2260
|
+
return {
|
|
2261
|
+
value: arrayLocal,
|
|
2262
|
+
valueOriginalPositions: arrayLocalPositions,
|
|
2263
|
+
stmts: stmts,
|
|
2264
|
+
};
|
|
2265
|
+
}
|
|
2266
|
+
/**
|
|
2267
|
+
*Converts C++prefix unary expression nodes to IR values and statement lists.
|
|
2268
|
+
*
|
|
2269
|
+
*@ param prefixUnaryExpression - prefix unary expression node in C++AST
|
|
2270
|
+
*@ returns The object containing the converted value and the generated statement list
|
|
2271
|
+
*/
|
|
2272
|
+
cxxPrefixUnaryExpressionToValueAndStmts(prefixUnaryExpression) {
|
|
2273
|
+
var _a;
|
|
2274
|
+
const stmts = [];
|
|
2275
|
+
let { value: operandValue, valueOriginalPositions: operandPositions, stmts: operandStmts } = this.cxxNodeToValueAndStmts(prefixUnaryExpression.inner[0]);
|
|
2276
|
+
stmts.push(...operandStmts);
|
|
2277
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(operandValue)) {
|
|
2278
|
+
({
|
|
2279
|
+
value: operandValue,
|
|
2280
|
+
valueOriginalPositions: operandPositions,
|
|
2281
|
+
stmts: operandStmts,
|
|
2282
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(operandValue, operandPositions));
|
|
2283
|
+
stmts.push(...operandStmts);
|
|
2284
|
+
}
|
|
2285
|
+
const operatorToken = (_a = prefixUnaryExpression.opcode) !== null && _a !== void 0 ? _a : ''; // Optional fields default to empty strings.
|
|
2286
|
+
let exprPositions = [Position_1.FullPosition.cxxBuildFromNode(prefixUnaryExpression, this.cxxSourceFile)];
|
|
2287
|
+
if (operatorToken === '++' || operatorToken === '--') {
|
|
2288
|
+
const binaryOperator = operatorToken === '++' ? Expr_1.NormalBinaryOperator.Addition : Expr_1.NormalBinaryOperator.Subtraction;
|
|
2289
|
+
const binopExpr = new Expr_2.ArkCxxNormalBinOpExpr(operandValue, ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(1), binaryOperator);
|
|
2290
|
+
exprPositions.push(...operandPositions, Position_1.FullPosition.DEFAULT);
|
|
2291
|
+
const assignStmt = new Stmt_1.ArkAssignStmt(operandValue, binopExpr);
|
|
2292
|
+
assignStmt.setOperandOriginalPositions([...operandPositions, ...exprPositions]);
|
|
2293
|
+
stmts.push(assignStmt);
|
|
2294
|
+
return {
|
|
2295
|
+
value: operandValue,
|
|
2296
|
+
valueOriginalPositions: operandPositions,
|
|
2297
|
+
stmts: stmts,
|
|
2298
|
+
};
|
|
2299
|
+
}
|
|
2300
|
+
else if (operatorToken === '+') {
|
|
2301
|
+
return {
|
|
2302
|
+
value: operandValue,
|
|
2303
|
+
valueOriginalPositions: operandPositions,
|
|
2304
|
+
stmts: stmts,
|
|
2305
|
+
};
|
|
2306
|
+
}
|
|
2307
|
+
else {
|
|
2308
|
+
let unopExpr;
|
|
2309
|
+
const operator = ArkIRTransformer_1.ArkCxxIRTransformer.cxxTokenToUnaryOperator(operatorToken);
|
|
2310
|
+
if (operator) {
|
|
2311
|
+
unopExpr = new Expr_1.ArkUnopExpr(operandValue, operator);
|
|
2312
|
+
exprPositions.push(...operandPositions);
|
|
2313
|
+
}
|
|
2314
|
+
else {
|
|
2315
|
+
unopExpr = ValueUtil_1.CxxValueUtil.getUndefinedConst();
|
|
2316
|
+
exprPositions = [Position_1.FullPosition.DEFAULT];
|
|
2317
|
+
}
|
|
2318
|
+
return {
|
|
2319
|
+
value: unopExpr,
|
|
2320
|
+
valueOriginalPositions: exprPositions,
|
|
2321
|
+
stmts: stmts,
|
|
2322
|
+
};
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2325
|
+
/**
|
|
2326
|
+
*Convert a C++suffix unary expression to a sequence of values and statements
|
|
2327
|
+
*
|
|
2328
|
+
*@ param postfixUnaryExpression - suffix unary expression node in C++AST
|
|
2329
|
+
*@ returns The object containing the converted value and related statements
|
|
2330
|
+
*/
|
|
2331
|
+
cxxPostfixUnaryExpressionToValueAndStmts(postfixUnaryExpression) {
|
|
2332
|
+
var _a, _b, _c;
|
|
2333
|
+
const stmts = [];
|
|
2334
|
+
let { value: operandValue, valueOriginalPositions: operandPositions, stmts: exprStmts, } = this.cxxNodeToValueAndStmts(postfixUnaryExpression.inner[0]);
|
|
2335
|
+
stmts.push(...exprStmts);
|
|
2336
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(operandValue)) {
|
|
2337
|
+
({
|
|
2338
|
+
value: operandValue, valueOriginalPositions: operandPositions, stmts: exprStmts,
|
|
2339
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(operandValue, operandPositions));
|
|
2340
|
+
stmts.push(...exprStmts);
|
|
2341
|
+
}
|
|
2342
|
+
let value = undefined;
|
|
2343
|
+
let exprPositions = [Position_1.FullPosition.cxxBuildFromNode(postfixUnaryExpression, this.cxxSourceFile)];
|
|
2344
|
+
const operatorToken = postfixUnaryExpression.opcode;
|
|
2345
|
+
// Use temporary variables to store the value before self increment, and avoid this expression for some non assignment operation scenarios
|
|
2346
|
+
if (operatorToken === '++' || operatorToken === '--') {
|
|
2347
|
+
const needAssign = [
|
|
2348
|
+
ArkCxxAstNode_1.astKind.VarDecl, ArkCxxAstNode_1.astKind.BinaryOperator, ArkCxxAstNode_1.astKind.BinaryConditionalOperator,
|
|
2349
|
+
ArkCxxAstNode_1.astKind.ConditionalOperator, ArkCxxAstNode_1.astKind.ArraySubscriptExpr,
|
|
2350
|
+
];
|
|
2351
|
+
let parent = (_c = ((_a = postfixUnaryExpression.parent) !== null && _a !== void 0 ? _a : (_b = postfixUnaryExpression.getParent) === null || _b === void 0 ? void 0 : _b.call(postfixUnaryExpression, true))) !== null && _c !== void 0 ? _c : null;
|
|
2352
|
+
if (parent && needAssign.includes(parent.kind)) {
|
|
2353
|
+
let { value: tempValue, stmts: tempStmts, } = this.arkIRTransformer.generateAssignStmtForValue(operandValue, exprPositions);
|
|
2354
|
+
stmts.push(...tempStmts);
|
|
2355
|
+
value = tempValue;
|
|
2356
|
+
}
|
|
2357
|
+
const binaryOperator = operatorToken === '++' ? Expr_1.NormalBinaryOperator.Addition : Expr_1.NormalBinaryOperator.Subtraction;
|
|
2358
|
+
const binopExpr = new Expr_2.ArkCxxNormalBinOpExpr(operandValue, ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(1), binaryOperator);
|
|
2359
|
+
exprPositions.push(...operandPositions, Position_1.FullPosition.DEFAULT);
|
|
2360
|
+
const assignStmt = new Stmt_1.ArkAssignStmt(operandValue, binopExpr);
|
|
2361
|
+
assignStmt.setOperandOriginalPositions([...operandPositions, ...exprPositions]);
|
|
2362
|
+
stmts.push(assignStmt);
|
|
2363
|
+
if (value === undefined) {
|
|
2364
|
+
value = operandValue;
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
else {
|
|
2368
|
+
value = ValueUtil_1.CxxValueUtil.getUndefinedConst();
|
|
2369
|
+
exprPositions = [Position_1.FullPosition.DEFAULT];
|
|
2370
|
+
}
|
|
2371
|
+
return {
|
|
2372
|
+
value: value, valueOriginalPositions: exprPositions, stmts: stmts,
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
declStmtToValueAndStmts(decl) {
|
|
2376
|
+
const stmt = [];
|
|
2377
|
+
let value = ValueUtil_2.ValueUtil.getUndefinedConst();
|
|
2378
|
+
let fullPositions = [];
|
|
2379
|
+
for (const node of decl.inner) {
|
|
2380
|
+
const valueAndStmts = this.cxxNodeToValueAndStmts(node);
|
|
2381
|
+
stmt.push(...valueAndStmts.stmts);
|
|
2382
|
+
value = valueAndStmts.value;
|
|
2383
|
+
fullPositions.push(...valueAndStmts.valueOriginalPositions);
|
|
2384
|
+
}
|
|
2385
|
+
return {
|
|
2386
|
+
value: value,
|
|
2387
|
+
valueOriginalPositions: fullPositions,
|
|
2388
|
+
stmts: stmt,
|
|
2389
|
+
};
|
|
2390
|
+
}
|
|
2391
|
+
/**
|
|
2392
|
+
*Convert C++variable declarations to combinations of values and statements
|
|
2393
|
+
*@ param variableDeclaration - C++variable declaration node
|
|
2394
|
+
*@ param isConst - whether it is a constant declaration
|
|
2395
|
+
*@ param needRightOp - Whether the right operand is required, the default is true
|
|
2396
|
+
*@ returns the ValueAndStmts object containing values and statements
|
|
2397
|
+
*/
|
|
2398
|
+
cxxVariableDeclarationToValueAndStmts(variableDeclaration, needRightOp = true) {
|
|
2399
|
+
let isConst = variableDeclaration.type.qualType.includes('const');
|
|
2400
|
+
const leftOpNode = variableDeclaration;
|
|
2401
|
+
let rightOpNode = undefined;
|
|
2402
|
+
if (variableDeclaration.inner !== null && variableDeclaration.inner.length !== 0) {
|
|
2403
|
+
rightOpNode = nodeInnerNode(variableDeclaration);
|
|
2404
|
+
}
|
|
2405
|
+
// In this case, the non assigned information on the right node needs to be discarded
|
|
2406
|
+
if (this.isCxxArray(leftOpNode.type.qualType) && (rightOpNode === null || rightOpNode === void 0 ? void 0 : rightOpNode.kind) === ArkCxxAstNode_1.astKind.IntegerLiteral) {
|
|
2407
|
+
rightOpNode = undefined;
|
|
2408
|
+
}
|
|
2409
|
+
const declarationType = variableDeclaration.type ? (0, builderUtils_1.cxxNode2Type)(variableDeclaration, this.declaringMethod) : Type_1.UnknownType.getInstance();
|
|
2410
|
+
const assignment = this.cxxAssignmentToValueAndStmts(leftOpNode, rightOpNode, true, isConst, declarationType, needRightOp);
|
|
2411
|
+
if (declarationType instanceof Type_2.ReferenceType && assignment.stmts[0] instanceof Stmt_1.ArkAssignStmt) {
|
|
2412
|
+
declarationType.setSourceValue(assignment.stmts[0].getRightOp());
|
|
2413
|
+
}
|
|
2414
|
+
return assignment;
|
|
2415
|
+
}
|
|
2416
|
+
isCxxArray(qualType) {
|
|
2417
|
+
const pattern = /\[.*\]/;
|
|
2418
|
+
return pattern.test(qualType);
|
|
2419
|
+
}
|
|
2420
|
+
/**
|
|
2421
|
+
*Process C++assignment expressions and convert them into ValueAndStmts structures.
|
|
2422
|
+
*
|
|
2423
|
+
*@ param leftOpNode The AST node of the left operand
|
|
2424
|
+
*@ param rightOpNode The AST node of the right operand, which may be undefined
|
|
2425
|
+
*@ param variableDefFlag indicates whether the variable is defined
|
|
2426
|
+
*@ param isConst indicates whether it is a constant
|
|
2427
|
+
*@ param declarationType Declared type
|
|
2428
|
+
*@ param needRightOp Whether to process the right operand, the default is true
|
|
2429
|
+
*@ returns the ValueAndStmts object containing the value, original position and statement list
|
|
2430
|
+
*/
|
|
2431
|
+
cxxAssignmentToValueAndStmts(leftOpNode, rightOpNode, variableDefFlag, isConst, declarationType, needRightOp = true) {
|
|
2432
|
+
let leftValueAndStmts;
|
|
2433
|
+
if (leftOpNode.kind.toString() === ArkCxxAstNode_1.astKind.VarDecl) {
|
|
2434
|
+
leftValueAndStmts = this.cxxIdentifierToValueAndStmts(leftOpNode, variableDefFlag);
|
|
2435
|
+
}
|
|
2436
|
+
else {
|
|
2437
|
+
leftValueAndStmts = this.cxxNodeToValueAndStmts(leftOpNode);
|
|
2438
|
+
}
|
|
2439
|
+
const { value: leftValue, valueOriginalPositions: leftPositions, stmts: leftStmts } = leftValueAndStmts;
|
|
2440
|
+
let stmts = [];
|
|
2441
|
+
if (needRightOp) {
|
|
2442
|
+
const { value: rightValue, valueOriginalPositions: rightPositions, stmts: rightStmts } = this.cxxAssignmentRightOpToValueAndStmts(rightOpNode, leftValue);
|
|
2443
|
+
if (leftValue instanceof Local_1.Local) {
|
|
2444
|
+
if (variableDefFlag) {
|
|
2445
|
+
leftValue.setConstFlag(isConst);
|
|
2446
|
+
leftValue.setType(declarationType);
|
|
2447
|
+
}
|
|
2448
|
+
if ((leftValue.getType() instanceof Type_1.UnknownType || leftValue.getType() instanceof Type_1.UnclearReferenceType) &&
|
|
2449
|
+
!(rightValue.getType() instanceof Type_1.UnknownType) && !(rightValue.getType() instanceof Type_1.UndefinedType)) {
|
|
2450
|
+
leftValue.setType(rightValue.getType());
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
const assignStmt = new Stmt_1.ArkAssignStmt(leftValue, rightValue);
|
|
2454
|
+
assignStmt.setOperandOriginalPositions([...leftPositions, ...rightPositions]);
|
|
2455
|
+
if (leftOpNode.kind === ArkCxxAstNode_1.astKind.InitListExpr) {
|
|
2456
|
+
stmts.push(...rightStmts);
|
|
2457
|
+
stmts.push(assignStmt);
|
|
2458
|
+
stmts.push(...leftStmts);
|
|
2459
|
+
}
|
|
2460
|
+
else {
|
|
2461
|
+
stmts.push(...rightStmts);
|
|
2462
|
+
stmts.push(...leftStmts);
|
|
2463
|
+
stmts.push(assignStmt);
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
else {
|
|
2467
|
+
stmts = leftStmts;
|
|
2468
|
+
}
|
|
2469
|
+
return {
|
|
2470
|
+
value: leftValue,
|
|
2471
|
+
valueOriginalPositions: leftPositions,
|
|
2472
|
+
stmts: stmts,
|
|
2473
|
+
};
|
|
2474
|
+
}
|
|
2475
|
+
/**
|
|
2476
|
+
*CPP implementation of converting the right operand node to a list of values and statements
|
|
2477
|
+
*@ param rightOpNode The AST node of the right operand, which may be undefined
|
|
2478
|
+
*@ param leftValue Left value object
|
|
2479
|
+
*@ returns Objects containing values, location information, and statement lists
|
|
2480
|
+
*/
|
|
2481
|
+
cxxAssignmentRightOpToValueAndStmts(rightOpNode, leftValue) {
|
|
2482
|
+
let rightValue;
|
|
2483
|
+
let rightPositions;
|
|
2484
|
+
let tempRightStmts = [];
|
|
2485
|
+
const rightStmts = [];
|
|
2486
|
+
if (rightOpNode) {
|
|
2487
|
+
({
|
|
2488
|
+
value: rightValue,
|
|
2489
|
+
valueOriginalPositions: rightPositions,
|
|
2490
|
+
stmts: tempRightStmts,
|
|
2491
|
+
} = this.cxxNodeToValueAndStmts(rightOpNode));
|
|
2492
|
+
rightStmts.push(...tempRightStmts);
|
|
2493
|
+
}
|
|
2494
|
+
else {
|
|
2495
|
+
rightValue = ValueUtil_1.CxxValueUtil.getUndefinedConst();
|
|
2496
|
+
rightPositions = [Position_1.FullPosition.DEFAULT];
|
|
2497
|
+
}
|
|
2498
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(leftValue) && IRUtils_1.IRUtils.moreThanOneAddress(rightValue)) {
|
|
2499
|
+
({
|
|
2500
|
+
value: rightValue,
|
|
2501
|
+
valueOriginalPositions: rightPositions,
|
|
2502
|
+
stmts: tempRightStmts,
|
|
2503
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(rightValue, rightPositions));
|
|
2504
|
+
rightStmts.push(...tempRightStmts);
|
|
2505
|
+
}
|
|
2506
|
+
return {
|
|
2507
|
+
value: rightValue,
|
|
2508
|
+
valueOriginalPositions: rightPositions,
|
|
2509
|
+
stmts: rightStmts,
|
|
2510
|
+
};
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
*Convert the C++AST node to a single address value and statement list
|
|
2514
|
+
*@ param node - C++AST node to be converted
|
|
2515
|
+
*@ returns An object containing a list of values, original positions, and statements
|
|
2516
|
+
*/
|
|
2517
|
+
cxxNodeToSingleAddressValueAndStmts(node) {
|
|
2518
|
+
const allStmts = [];
|
|
2519
|
+
let { value, valueOriginalPositions, stmts } = this.cxxNodeToValueAndStmts(node);
|
|
2520
|
+
allStmts.push(...stmts);
|
|
2521
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(value)) {
|
|
2522
|
+
({
|
|
2523
|
+
value,
|
|
2524
|
+
valueOriginalPositions,
|
|
2525
|
+
stmts,
|
|
2526
|
+
} = this.arkIRTransformer.generateAssignStmtForValue(value, valueOriginalPositions));
|
|
2527
|
+
allStmts.push(...stmts);
|
|
2528
|
+
}
|
|
2529
|
+
return { value, valueOriginalPositions, stmts: allStmts };
|
|
2530
|
+
}
|
|
2531
|
+
/**
|
|
2532
|
+
*Converts a C++binary expression node to a list of values and statements.
|
|
2533
|
+
*In assignment patterns, the left operand will be an array literal expression
|
|
2534
|
+
*In assignment patterns, the left operand will be an object literal expression
|
|
2535
|
+
*@ param binaryExpression - Binary expression node in C++AST
|
|
2536
|
+
*@ returns The ValueAndStmts object containing calculated values and related statements
|
|
2537
|
+
*/
|
|
2538
|
+
cxxBinaryExpressionToValueAndStmts(binaryExpression) {
|
|
2539
|
+
var _a;
|
|
2540
|
+
const operatorToken = (_a = binaryExpression.opcode) !== null && _a !== void 0 ? _a : '!=';
|
|
2541
|
+
const binaryExpressionLeft = binaryExpression.inner[0];
|
|
2542
|
+
const binaryExpressionRight = binaryExpression.inner[1];
|
|
2543
|
+
if (operatorToken === '=') {
|
|
2544
|
+
const leftType = (0, builderUtils_1.cxxNode2Type)(binaryExpressionLeft, undefined);
|
|
2545
|
+
return this.cxxAssignmentToValueAndStmts(binaryExpressionLeft, binaryExpressionRight, false, false, leftType, true);
|
|
2546
|
+
}
|
|
2547
|
+
const stmts = [];
|
|
2548
|
+
const binaryExpressionPosition = Position_1.FullPosition.cxxBuildFromNode(binaryExpression, this.cxxSourceFile);
|
|
2549
|
+
const { value: opValue1, valueOriginalPositions: opPositions1, stmts: opStmts1, } = this.cxxNodeToSingleAddressValueAndStmts(binaryExpressionLeft);
|
|
2550
|
+
stmts.push(...opStmts1);
|
|
2551
|
+
const { value: opValue2, valueOriginalPositions: opPositions2, stmts: opStmts2, } = this.cxxNodeToSingleAddressValueAndStmts(binaryExpressionRight);
|
|
2552
|
+
stmts.push(...opStmts2);
|
|
2553
|
+
let exprValue;
|
|
2554
|
+
let exprValuePositions = [binaryExpressionPosition];
|
|
2555
|
+
// In scenarios where the operator is', 'and' value 'is the rightmost value
|
|
2556
|
+
if (operatorToken === ',') {
|
|
2557
|
+
exprValue = opValue2;
|
|
2558
|
+
exprValuePositions.push(...opPositions1, ...opPositions2);
|
|
2559
|
+
}
|
|
2560
|
+
else if (operatorToken) {
|
|
2561
|
+
if (this.isRelationalOperator(operatorToken)) {
|
|
2562
|
+
exprValue = new Expr_1.ArkConditionExpr(opValue1, opValue2, operatorToken);
|
|
2563
|
+
}
|
|
2564
|
+
else {
|
|
2565
|
+
exprValue = new Expr_2.ArkCxxNormalBinOpExpr(opValue1, opValue2, operatorToken);
|
|
2566
|
+
const exprTye = (0, builderUtils_1.cxxNode2Type)(binaryExpression, undefined, undefined);
|
|
2567
|
+
exprValue.setCxxType(exprTye);
|
|
2568
|
+
}
|
|
2569
|
+
exprValuePositions.push(...opPositions1, ...opPositions2);
|
|
2570
|
+
}
|
|
2571
|
+
else {
|
|
2572
|
+
exprValue = ValueUtil_1.CxxValueUtil.getUndefinedConst();
|
|
2573
|
+
exprValuePositions.push(binaryExpressionPosition);
|
|
2574
|
+
}
|
|
2575
|
+
return {
|
|
2576
|
+
value: exprValue,
|
|
2577
|
+
valueOriginalPositions: exprValuePositions,
|
|
2578
|
+
stmts: stmts,
|
|
2579
|
+
};
|
|
2580
|
+
}
|
|
2581
|
+
/**
|
|
2582
|
+
*Convert compound assignment expressions (such as+=, -=, etc.) in C++to values and statement lists in intermediate representation (IR).
|
|
2583
|
+
*
|
|
2584
|
+
*@ param binaryExpression represents the C++AST node of the compound assignment operation
|
|
2585
|
+
*@ returns an object containing the calculated value, the original location information, and the generated statement list
|
|
2586
|
+
*/
|
|
2587
|
+
cxxCompoundAssignmentToValueAndStmts(binaryExpression) {
|
|
2588
|
+
var _a;
|
|
2589
|
+
const stmts = [];
|
|
2590
|
+
let { value: leftValue, valueOriginalPositions: leftPositions, stmts: leftStmts, } = this.cxxNodeToValueAndStmts(binaryExpression.inner[0]);
|
|
2591
|
+
stmts.push(...leftStmts);
|
|
2592
|
+
let { value: rightValue, valueOriginalPositions: rightPositions, stmts: rightStmts, } = this.cxxNodeToValueAndStmts(binaryExpression.inner[1]);
|
|
2593
|
+
stmts.push(...rightStmts);
|
|
2594
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(leftValue) && IRUtils_1.IRUtils.moreThanOneAddress(rightValue)) {
|
|
2595
|
+
const { value: newRightValue, valueOriginalPositions: newRightPositions, stmts: rightStmts, } = this.ArkCxxIRTransformer.generateAssignStmtForValue(rightValue, rightPositions);
|
|
2596
|
+
rightValue = newRightValue;
|
|
2597
|
+
rightPositions = newRightPositions;
|
|
2598
|
+
stmts.push(...rightStmts);
|
|
2599
|
+
}
|
|
2600
|
+
let leftOpValue;
|
|
2601
|
+
let leftOpPositions;
|
|
2602
|
+
const operator = this.cxxCcompoundAssignmentTokenToBinaryOperator((_a = binaryExpression.opcode) !== null && _a !== void 0 ? _a : '');
|
|
2603
|
+
if (operator) {
|
|
2604
|
+
const exprValue = new Expr_2.ArkCxxNormalBinOpExpr(leftValue, rightValue, operator);
|
|
2605
|
+
const exprValuePosition = Position_1.FullPosition.cxxBuildFromNode(binaryExpression, this.cxxSourceFile);
|
|
2606
|
+
const assignStmt = new Stmt_1.ArkAssignStmt(leftValue, exprValue);
|
|
2607
|
+
assignStmt.setOperandOriginalPositions([...leftPositions, exprValuePosition, ...leftPositions, ...rightPositions]);
|
|
2608
|
+
stmts.push(assignStmt);
|
|
2609
|
+
leftOpValue = leftValue;
|
|
2610
|
+
leftOpPositions = leftPositions;
|
|
2611
|
+
}
|
|
2612
|
+
else {
|
|
2613
|
+
leftOpValue = ValueUtil_1.CxxValueUtil.getUndefinedConst();
|
|
2614
|
+
leftOpPositions = [leftPositions[0]];
|
|
2615
|
+
}
|
|
2616
|
+
return {
|
|
2617
|
+
value: leftOpValue,
|
|
2618
|
+
valueOriginalPositions: leftOpPositions,
|
|
2619
|
+
stmts: stmts,
|
|
2620
|
+
};
|
|
2621
|
+
}
|
|
2622
|
+
/**
|
|
2623
|
+
*Convert the compound assignment operator to the corresponding binary operator
|
|
2624
|
+
*
|
|
2625
|
+
*@ param token - compound assignment operator string
|
|
2626
|
+
*@ returns The corresponding binary operator. If no match is found, null is returned
|
|
2627
|
+
*/
|
|
2628
|
+
cxxCcompoundAssignmentTokenToBinaryOperator(token) {
|
|
2629
|
+
switch (token) {
|
|
2630
|
+
case CompoundBinaryOperator.AdditionEquals:
|
|
2631
|
+
return Expr_1.NormalBinaryOperator.Addition;
|
|
2632
|
+
case CompoundBinaryOperator.SubtractionEquals:
|
|
2633
|
+
return Expr_1.NormalBinaryOperator.Subtraction;
|
|
2634
|
+
case CompoundBinaryOperator.MultiplicationEquals:
|
|
2635
|
+
return Expr_1.NormalBinaryOperator.Multiplication;
|
|
2636
|
+
case CompoundBinaryOperator.DivisionEquals:
|
|
2637
|
+
return Expr_1.NormalBinaryOperator.Division;
|
|
2638
|
+
case CompoundBinaryOperator.RemainderEquals:
|
|
2639
|
+
return Expr_1.NormalBinaryOperator.Remainder;
|
|
2640
|
+
case CompoundBinaryOperator.LeftShiftEquals:
|
|
2641
|
+
return Expr_1.NormalBinaryOperator.LeftShift;
|
|
2642
|
+
case CompoundBinaryOperator.RightShiftEquals:
|
|
2643
|
+
return Expr_1.NormalBinaryOperator.RightShift;
|
|
2644
|
+
case CompoundBinaryOperator.BitwiseAndEquals:
|
|
2645
|
+
return Expr_1.NormalBinaryOperator.BitwiseAnd;
|
|
2646
|
+
case CompoundBinaryOperator.BitwiseOrEquals:
|
|
2647
|
+
return Expr_1.NormalBinaryOperator.BitwiseOr;
|
|
2648
|
+
case CompoundBinaryOperator.BitwiseXorEquals:
|
|
2649
|
+
return Expr_1.NormalBinaryOperator.BitwiseXor;
|
|
2650
|
+
default:
|
|
2651
|
+
}
|
|
2652
|
+
return null;
|
|
2653
|
+
}
|
|
2654
|
+
/**
|
|
2655
|
+
*Convert C++conditional expression nodes to a combination of values and statements
|
|
2656
|
+
*@ param condition - Condition node in C++abstract syntax tree
|
|
2657
|
+
*@ returns Objects containing conditional expression values and related statements
|
|
2658
|
+
*/
|
|
2659
|
+
cxxConditionToValueAndStmts(condition) {
|
|
2660
|
+
const stmts = [];
|
|
2661
|
+
let { value: conditionValue, valueOriginalPositions: conditionPositions, stmts: conditionStmts, } = this.cxxNodeToValueAndStmts(condition);
|
|
2662
|
+
stmts.push(...conditionStmts);
|
|
2663
|
+
let conditionExpr;
|
|
2664
|
+
if (conditionValue instanceof Expr_1.AbstractBinopExpr && this.isRelationalOperator(conditionValue.getOperator())) {
|
|
2665
|
+
const operator = conditionValue.getOperator();
|
|
2666
|
+
conditionExpr = new Expr_1.ArkConditionExpr(conditionValue.getOp1(), conditionValue.getOp2(), operator);
|
|
2667
|
+
}
|
|
2668
|
+
else {
|
|
2669
|
+
if (IRUtils_1.IRUtils.moreThanOneAddress(conditionValue)) {
|
|
2670
|
+
({
|
|
2671
|
+
value: conditionValue,
|
|
2672
|
+
valueOriginalPositions: conditionPositions,
|
|
2673
|
+
stmts: conditionStmts,
|
|
2674
|
+
} = this.ArkCxxIRTransformer.generateAssignStmtForValue(conditionValue, conditionPositions));
|
|
2675
|
+
stmts.push(...conditionStmts);
|
|
2676
|
+
}
|
|
2677
|
+
conditionExpr = new Expr_1.ArkConditionExpr(conditionValue, ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(0), Expr_1.RelationalBinaryOperator.InEquality);
|
|
2678
|
+
conditionPositions = [conditionPositions[0], ...conditionPositions, Position_1.FullPosition.DEFAULT];
|
|
2679
|
+
}
|
|
2680
|
+
return {
|
|
2681
|
+
value: conditionExpr,
|
|
2682
|
+
valueOriginalPositions: conditionPositions,
|
|
2683
|
+
stmts: stmts,
|
|
2684
|
+
};
|
|
2685
|
+
}
|
|
2686
|
+
parseFloatAsCxxFloat(s) {
|
|
2687
|
+
const num = Number.parseFloat(s);
|
|
2688
|
+
// perform a float32 round-trip using Float32Array to simulate C++ 'float' precision
|
|
2689
|
+
const f32 = new Float32Array(1);
|
|
2690
|
+
f32[0] = num;
|
|
2691
|
+
return +f32[0].toFixed(5);
|
|
2692
|
+
}
|
|
2693
|
+
/**
|
|
2694
|
+
*Convert literal nodes in C++AST into corresponding value and statement lists.
|
|
2695
|
+
*Literals currently processed: integer, floating point, string, character, Boolean value, null pointer, address label
|
|
2696
|
+
*@ param literalNode - an AST node representing a C++literal
|
|
2697
|
+
*@ returns the object containing the value, original location information and statement list. If the node type cannot be processed, null is returned
|
|
2698
|
+
*/
|
|
2699
|
+
cxxLiteralNodeToValueAndStmts(literalNode) {
|
|
2700
|
+
var _a, _b;
|
|
2701
|
+
const stmts = [];
|
|
2702
|
+
const pos = [Position_1.FullPosition.cxxBuildFromNode(literalNode, this.cxxSourceFile)];
|
|
2703
|
+
const S = (v) => v !== null && v !== void 0 ? v : '';
|
|
2704
|
+
switch (literalNode.kind) {
|
|
2705
|
+
case ArkCxxAstNode_1.astKind.IntegerLiteral: {
|
|
2706
|
+
const num = (S(literalNode.value) || S(literalNode.code));
|
|
2707
|
+
const constant = ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(num ? num : 0);
|
|
2708
|
+
return { value: constant, valueOriginalPositions: pos, stmts };
|
|
2709
|
+
}
|
|
2710
|
+
case ArkCxxAstNode_1.astKind.FloatingLiteral: {
|
|
2711
|
+
const num = this.parseFloatAsCxxFloat(S(literalNode.value) || S(literalNode.code));
|
|
2712
|
+
const constant = ValueUtil_1.CxxValueUtil.getOrCreateNumberConst(Number.isFinite(num) ? num : 0);
|
|
2713
|
+
return { value: constant, valueOriginalPositions: pos, stmts };
|
|
2714
|
+
}
|
|
2715
|
+
case ArkCxxAstNode_1.astKind.StringLiteral: {
|
|
2716
|
+
const constant = ValueUtil_1.CxxValueUtil.createStringConst(S(literalNode.value) || S(literalNode.code));
|
|
2717
|
+
return { value: constant, valueOriginalPositions: pos, stmts };
|
|
2718
|
+
}
|
|
2719
|
+
case ArkCxxAstNode_1.astKind.CharacterLiteral: {
|
|
2720
|
+
const constant = ValueUtil_1.CxxValueUtil.createCharConst(S(literalNode.code));
|
|
2721
|
+
return { value: constant, valueOriginalPositions: pos, stmts };
|
|
2722
|
+
}
|
|
2723
|
+
case ArkCxxAstNode_1.astKind.CXXBoolLiteralExpr: {
|
|
2724
|
+
const raw = ((_b = (_a = literalNode.value) !== null && _a !== void 0 ? _a : literalNode.code) !== null && _b !== void 0 ? _b : '').toString().trim().toLowerCase();
|
|
2725
|
+
const b = raw === 'true' || raw === '1';
|
|
2726
|
+
const constant = ValueUtil_1.CxxValueUtil.getBooleanConstant(b);
|
|
2727
|
+
return { value: constant, valueOriginalPositions: pos, stmts };
|
|
2728
|
+
}
|
|
2729
|
+
case ArkCxxAstNode_1.astKind.CXXNullPtrLiteralExpr: {
|
|
2730
|
+
const constant = Constant_1.NullConstant.getInstance();
|
|
2731
|
+
return { value: constant, valueOriginalPositions: pos, stmts };
|
|
2732
|
+
}
|
|
2733
|
+
default: {
|
|
2734
|
+
logger.warn(`ast node's syntaxKind is ${literalNode.kind}, not literalNode`);
|
|
2735
|
+
return null;
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
static isCxxCompoundAssignmentOperator(op) {
|
|
2740
|
+
return !!op && COMPOUND_BIN_OPS.has(op);
|
|
2741
|
+
}
|
|
2742
|
+
static isRelationalBinaryOperator(op) {
|
|
2743
|
+
return Object.values(Expr_1.RelationalBinaryOperator).includes(op);
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
exports.ArkCxxValueTransformer = ArkCxxValueTransformer;
|