arkanalyzer 1.0.93 → 2.0.0-beta1
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/lib/Config.d.ts +7 -0
- package/lib/Config.d.ts.map +1 -1
- package/lib/Scene.d.ts +134 -170
- package/lib/Scene.d.ts.map +1 -1
- package/lib/Scene.js +412 -976
- package/lib/callgraph/algorithm/AbstractAnalysis.js +3 -2
- package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/RapidTypeAnalysis.js +2 -3
- package/lib/callgraph/model/CallGraph.js +1 -1
- package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts +1 -3
- package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PTAUtils.js +17 -7
- package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Pag.js +4 -14
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PagBuilder.js +2 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +1 -2
- package/lib/callgraph/pointerAnalysis/plugins/WorkerPlugin.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/plugins/WorkerPlugin.js +0 -1
- package/lib/cli/commands/cg.d.ts +1 -0
- package/lib/cli/commands/cg.d.ts.map +1 -1
- package/lib/cli/commands/cg.js +22 -18
- package/lib/cli/commands/ir.d.ts +1 -0
- package/lib/cli/commands/ir.d.ts.map +1 -1
- package/lib/cli/commands/ir.js +5 -2
- package/lib/core/base/Constant.d.ts +5 -5
- package/lib/core/base/Constant.d.ts.map +1 -1
- package/lib/core/base/Constant.js +12 -9
- package/lib/core/base/Expr.d.ts +36 -20
- package/lib/core/base/Expr.d.ts.map +1 -1
- package/lib/core/base/Expr.js +206 -94
- package/lib/core/base/Local.d.ts +10 -20
- package/lib/core/base/Local.d.ts.map +1 -1
- package/lib/core/base/Local.js +25 -28
- package/lib/core/base/Position.d.ts +6 -0
- package/lib/core/base/Position.d.ts.map +1 -1
- package/lib/core/base/Position.js +37 -11
- package/lib/core/base/Ref.d.ts +45 -33
- package/lib/core/base/Ref.d.ts.map +1 -1
- package/lib/core/base/Ref.js +225 -51
- package/lib/core/base/Stmt.d.ts +19 -9
- package/lib/core/base/Stmt.d.ts.map +1 -1
- package/lib/core/base/Stmt.js +135 -52
- package/lib/core/base/Type.d.ts +67 -4
- package/lib/core/base/Type.d.ts.map +1 -1
- package/lib/core/base/Type.js +391 -20
- package/lib/core/base/TypeExpr.d.ts +6 -4
- package/lib/core/base/TypeExpr.d.ts.map +1 -1
- package/lib/core/base/TypeExpr.js +34 -10
- package/lib/core/base/Value.d.ts +20 -2
- package/lib/core/base/Value.d.ts.map +1 -1
- package/lib/core/base/Value.js +12 -0
- package/lib/core/common/ArkIRTransformer.d.ts +18 -0
- package/lib/core/common/ArkIRTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkIRTransformer.js +94 -75
- package/lib/core/common/ArkValueTransformer.d.ts +21 -3
- package/lib/core/common/ArkValueTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkValueTransformer.js +458 -266
- package/lib/core/common/Builtin.d.ts +48 -24
- package/lib/core/common/Builtin.d.ts.map +1 -1
- package/lib/core/common/Builtin.js +90 -52
- package/lib/core/common/CanonicalizerValidator.d.ts +308 -0
- package/lib/core/common/CanonicalizerValidator.d.ts.map +1 -0
- package/lib/core/common/CanonicalizerValidator.js +888 -0
- package/lib/core/common/Const.d.ts +3 -3
- package/lib/core/common/Const.d.ts.map +1 -1
- package/lib/core/common/Const.js +3 -3
- package/lib/core/common/DummyMainCreater.d.ts +2 -21
- package/lib/core/common/DummyMainCreater.d.ts.map +1 -1
- package/lib/core/common/DummyMainCreater.js +8 -105
- package/lib/core/common/IRInference.d.ts +55 -3
- package/lib/core/common/IRInference.d.ts.map +1 -1
- package/lib/core/common/IRInference.js +407 -126
- package/lib/core/common/IRUtils.d.ts +1 -0
- package/lib/core/common/IRUtils.d.ts.map +1 -1
- package/lib/core/common/IRUtils.js +44 -13
- package/lib/core/common/ModelUtils.d.ts +44 -20
- package/lib/core/common/ModelUtils.d.ts.map +1 -1
- package/lib/core/common/ModelUtils.js +378 -208
- package/lib/core/common/SdkUtils.d.ts +35 -5
- package/lib/core/common/SdkUtils.d.ts.map +1 -1
- package/lib/core/common/SdkUtils.js +203 -59
- package/lib/core/common/SignatureCanonicalizer.d.ts +95 -0
- package/lib/core/common/SignatureCanonicalizer.d.ts.map +1 -0
- package/lib/core/common/SignatureCanonicalizer.js +116 -0
- package/lib/core/common/SignatureCanonicalizerRegistry.d.ts +176 -0
- package/lib/core/common/SignatureCanonicalizerRegistry.d.ts.map +1 -0
- package/lib/core/common/SignatureCanonicalizerRegistry.js +343 -0
- package/lib/core/common/SignatureModelCanonicalizer.d.ts +69 -0
- package/lib/core/common/SignatureModelCanonicalizer.d.ts.map +1 -0
- package/lib/core/common/SignatureModelCanonicalizer.js +109 -0
- package/lib/core/common/StmtUseReplacer.d.ts +1 -0
- package/lib/core/common/StmtUseReplacer.d.ts.map +1 -1
- package/lib/core/common/StmtUseReplacer.js +9 -0
- package/lib/core/common/StringUtils.d.ts +12 -1
- package/lib/core/common/StringUtils.d.ts.map +1 -1
- package/lib/core/common/StringUtils.js +36 -17
- package/lib/core/common/TempSignatureCanonicalizer.d.ts +82 -0
- package/lib/core/common/TempSignatureCanonicalizer.d.ts.map +1 -0
- package/lib/core/common/TempSignatureCanonicalizer.js +177 -0
- package/lib/core/common/TypeInference.d.ts +24 -6
- package/lib/core/common/TypeInference.d.ts.map +1 -1
- package/lib/core/common/TypeInference.js +243 -117
- package/lib/core/common/ValueUtil.d.ts +2 -1
- package/lib/core/common/ValueUtil.d.ts.map +1 -1
- package/lib/core/common/ValueUtil.js +4 -1
- package/lib/core/graph/Cfg.d.ts.map +1 -1
- package/lib/core/graph/Cfg.js +21 -6
- package/lib/core/graph/builder/CfgBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/CfgBuilder.js +46 -33
- package/lib/core/graph/builder/IfBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/IfBuilder.js +6 -2
- package/lib/core/graph/builder/ViewTreeBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/ViewTreeBuilder.js +6 -2
- package/lib/core/inference/ModelInference.d.ts +24 -4
- package/lib/core/inference/ModelInference.d.ts.map +1 -1
- package/lib/core/inference/ModelInference.js +273 -79
- 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 +90 -40
- package/lib/core/inference/abc/AbcInference.d.ts.map +1 -1
- package/lib/core/inference/abc/AbcInference.js +28 -15
- package/lib/core/inference/arkts/ArkTsInference.d.ts +9 -3
- package/lib/core/inference/arkts/ArkTsInference.d.ts.map +1 -1
- package/lib/core/inference/arkts/ArkTsInference.js +54 -16
- package/lib/core/model/ArkClass.d.ts +192 -18
- package/lib/core/model/ArkClass.d.ts.map +1 -1
- package/lib/core/model/ArkClass.js +852 -122
- package/lib/core/model/ArkExport.d.ts.map +1 -1
- package/lib/core/model/ArkExport.js +1 -2
- package/lib/core/model/ArkField.d.ts +34 -2
- package/lib/core/model/ArkField.d.ts.map +1 -1
- package/lib/core/model/ArkField.js +89 -14
- package/lib/core/model/ArkFile.d.ts +72 -12
- package/lib/core/model/ArkFile.d.ts.map +1 -1
- package/lib/core/model/ArkFile.js +275 -65
- package/lib/core/model/ArkImport.d.ts.map +1 -1
- package/lib/core/model/ArkImport.js +1 -2
- package/lib/core/model/ArkMethod.d.ts +101 -15
- package/lib/core/model/ArkMethod.d.ts.map +1 -1
- package/lib/core/model/ArkMethod.js +252 -39
- package/lib/core/model/ArkModule.d.ts +1 -1
- package/lib/core/model/ArkModule.js +1 -1
- package/lib/core/model/ArkNamespace.d.ts +80 -10
- package/lib/core/model/ArkNamespace.d.ts.map +1 -1
- package/lib/core/model/ArkNamespace.js +309 -76
- package/lib/core/model/ArkSignature.d.ts +242 -18
- package/lib/core/model/ArkSignature.d.ts.map +1 -1
- package/lib/core/model/ArkSignature.js +725 -95
- package/lib/core/model/builder/ArkClassBuilder.d.ts +6 -3
- package/lib/core/model/builder/ArkClassBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkClassBuilder.js +119 -73
- package/lib/core/model/builder/ArkExportBuilder.d.ts +1 -1
- package/lib/core/model/builder/ArkExportBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkExportBuilder.js +1 -1
- package/lib/core/model/builder/ArkFieldBuilder.d.ts +0 -2
- package/lib/core/model/builder/ArkFieldBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkFieldBuilder.js +9 -43
- package/lib/core/model/builder/ArkFileBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkFileBuilder.js +32 -33
- package/lib/core/model/builder/ArkMethodBuilder.d.ts +10 -3
- package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkMethodBuilder.js +40 -26
- package/lib/core/model/builder/ArkNamespaceBuilder.d.ts +3 -2
- package/lib/core/model/builder/ArkNamespaceBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkNamespaceBuilder.js +45 -77
- package/lib/core/model/builder/ArkSignatureBuilder.d.ts +9 -0
- package/lib/core/model/builder/ArkSignatureBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkSignatureBuilder.js +26 -3
- package/lib/core/model/builder/BodyBuilder.d.ts +1 -0
- package/lib/core/model/builder/BodyBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/BodyBuilder.js +37 -11
- package/lib/core/model/builder/builderUtils.d.ts +11 -1
- package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
- package/lib/core/model/builder/builderUtils.js +124 -90
- package/lib/frontend/FrontendBuilder.d.ts +10 -6
- package/lib/frontend/FrontendBuilder.d.ts.map +1 -1
- package/lib/frontend/FrontendBuilder.js +19 -45
- package/lib/frontend/ModuleScene.d.ts +43 -0
- package/lib/frontend/ModuleScene.d.ts.map +1 -0
- package/lib/frontend/ModuleScene.js +143 -0
- package/lib/frontend/SceneBuildStage.d.ts +15 -0
- package/lib/frontend/SceneBuildStage.d.ts.map +1 -0
- package/lib/frontend/SceneBuildStage.js +32 -0
- package/lib/frontend/SceneBuilder.d.ts +153 -0
- package/lib/frontend/SceneBuilder.d.ts.map +1 -0
- package/lib/frontend/SceneBuilder.js +859 -0
- package/lib/frontend/arktsFrontend/ArktsFrontend.d.ts +0 -2
- package/lib/frontend/arktsFrontend/ArktsFrontend.d.ts.map +1 -1
- package/lib/frontend/arktsFrontend/ArktsFrontend.js +0 -18
- package/lib/frontend/arktsFrontend/FileBodyRemount.d.ts +17 -0
- package/lib/frontend/arktsFrontend/FileBodyRemount.d.ts.map +1 -0
- package/lib/frontend/arktsFrontend/FileBodyRemount.js +187 -0
- package/lib/frontend/common/ModuleBuilder.d.ts +4 -2
- package/lib/frontend/common/ModuleBuilder.d.ts.map +1 -1
- package/lib/frontend/common/ModuleBuilder.js +19 -9
- package/lib/frontend/cppFrontend/CppFrontend.d.ts +0 -6
- package/lib/frontend/cppFrontend/CppFrontend.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/CppFrontend.js +0 -56
- package/lib/frontend/cppFrontend/base/Type.d.ts +7 -0
- package/lib/frontend/cppFrontend/base/Type.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/base/Type.js +29 -0
- package/lib/frontend/cppFrontend/common/ArkIRTransformer.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/common/ArkIRTransformer.js +56 -56
- package/lib/frontend/cppFrontend/common/ArkValueTransformer.d.ts +1 -1
- package/lib/frontend/cppFrontend/common/ArkValueTransformer.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/common/ArkValueTransformer.js +124 -113
- package/lib/frontend/cppFrontend/common/Builtin.d.ts +29 -19
- package/lib/frontend/cppFrontend/common/Builtin.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/common/Builtin.js +56 -35
- package/lib/frontend/cppFrontend/common/IRInference.d.ts +7 -2
- package/lib/frontend/cppFrontend/common/IRInference.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/common/IRInference.js +61 -28
- package/lib/frontend/cppFrontend/common/IRUtils.d.ts +1 -0
- package/lib/frontend/cppFrontend/common/IRUtils.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/common/IRUtils.js +22 -10
- package/lib/frontend/cppFrontend/common/ModelUtils.d.ts +19 -0
- package/lib/frontend/cppFrontend/common/ModelUtils.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/common/ModelUtils.js +84 -3
- package/lib/frontend/cppFrontend/common/TypeInference.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/common/TypeInference.js +44 -54
- package/lib/frontend/cppFrontend/graph/builder/CfgBuilder.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/graph/builder/CfgBuilder.js +2 -1
- package/lib/frontend/cppFrontend/inference/CxxModelInference.d.ts +1 -1
- package/lib/frontend/cppFrontend/inference/CxxModelInference.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/inference/CxxValueInference.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/inference/CxxValueInference.js +41 -5
- package/lib/frontend/cppFrontend/model/builder/ArkClassBuilder.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/model/builder/ArkClassBuilder.js +18 -28
- package/lib/frontend/cppFrontend/model/builder/ArkFieldBuilder.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/model/builder/ArkFieldBuilder.js +2 -3
- package/lib/frontend/cppFrontend/model/builder/ArkFileBuilder.d.ts +2 -2
- package/lib/frontend/cppFrontend/model/builder/ArkFileBuilder.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/model/builder/ArkFileBuilder.js +31 -24
- package/lib/frontend/cppFrontend/model/builder/ArkMethodBuilder.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/model/builder/ArkMethodBuilder.js +10 -16
- package/lib/frontend/cppFrontend/model/builder/ArkNamespaceBuilder.d.ts +0 -2
- package/lib/frontend/cppFrontend/model/builder/ArkNamespaceBuilder.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/model/builder/ArkNamespaceBuilder.js +19 -37
- package/lib/frontend/cppFrontend/model/builder/BodyBuilder.d.ts +1 -0
- package/lib/frontend/cppFrontend/model/builder/BodyBuilder.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/model/builder/BodyBuilder.js +30 -3
- package/lib/frontend/cppFrontend/model/builder/builderUtils.d.ts.map +1 -1
- package/lib/frontend/cppFrontend/model/builder/builderUtils.js +8 -4
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +10 -2
- package/lib/save/json/JsonSerialization.js +2 -2
- package/lib/save/source/SourceStmt.js +1 -1
- package/lib/save/source/SourceTransformer.d.ts.map +1 -1
- package/lib/save/source/SourceTransformer.js +0 -9
- package/lib/statistics/StageStatistics.d.ts +195 -0
- package/lib/statistics/StageStatistics.d.ts.map +1 -0
- package/lib/statistics/StageStatistics.js +346 -0
- package/lib/statistics/StageStatisticsReporter.d.ts +58 -0
- package/lib/statistics/StageStatisticsReporter.d.ts.map +1 -0
- package/lib/statistics/StageStatisticsReporter.js +255 -0
- package/lib/utils/Canonicalizer.d.ts +9 -2
- package/lib/utils/Canonicalizer.d.ts.map +1 -1
- package/lib/utils/Canonicalizer.js +19 -2
- package/lib/utils/CxxSceneUtils.d.ts +7 -0
- package/lib/utils/CxxSceneUtils.d.ts.map +1 -1
- package/lib/utils/CxxSceneUtils.js +10 -1
- package/lib/utils/FileUtils.d.ts +0 -1
- package/lib/utils/FileUtils.d.ts.map +1 -1
- package/lib/utils/FileUtils.js +1 -9
- package/lib/utils/HashUtils.d.ts +9 -0
- package/lib/utils/HashUtils.d.ts.map +1 -0
- package/lib/utils/HashUtils.js +65 -0
- package/lib/utils/ModuleUtils.d.ts.map +1 -1
- package/lib/utils/ModuleUtils.js +24 -5
- package/lib/utils/VisitedSegment.d.ts +23 -0
- package/lib/utils/VisitedSegment.d.ts.map +1 -0
- package/lib/utils/VisitedSegment.js +64 -0
- package/lib/utils/callGraphUtils.d.ts.map +1 -1
- package/lib/utils/callGraphUtils.js +7 -7
- package/lib/utils/getAllFiles.d.ts.map +1 -1
- package/lib/utils/getAllFiles.js +11 -8
- package/lib/utils/logger.d.ts +4 -0
- package/lib/utils/logger.d.ts.map +1 -1
- package/lib/utils/logger.js +16 -0
- package/lib/utils/parseArkSourceFile.d.ts +33 -0
- package/lib/utils/parseArkSourceFile.d.ts.map +1 -0
- package/lib/utils/parseArkSourceFile.js +131 -0
- package/package.json +1 -1
- package/lib/node_modules/ohos-typescript/README.OpenSource +0 -11
- package/lib/node_modules/ohos-typescript/README.md +0 -81
- package/lib/node_modules/ohos-typescript/SECURITY.md +0 -41
- package/lib/node_modules/ohos-typescript/ThirdPartyNoticeText.txt +0 -193
- package/lib/node_modules/ohos-typescript/bin/tsc +0 -2
- package/lib/node_modules/ohos-typescript/bin/tsserver +0 -2
- package/lib/node_modules/ohos-typescript/lib/README.md +0 -5
- package/lib/node_modules/ohos-typescript/lib/cancellationToken.js +0 -86
- package/lib/node_modules/ohos-typescript/lib/cs/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/de/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/es/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/fr/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/it/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/ja/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/ko/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/lib.dom.d.ts +0 -18505
- package/lib/node_modules/ohos-typescript/lib/lib.dom.iterable.d.ts +0 -341
- package/lib/node_modules/ohos-typescript/lib/lib.scripthost.d.ts +0 -327
- package/lib/node_modules/ohos-typescript/lib/lib.webworker.d.ts +0 -6192
- package/lib/node_modules/ohos-typescript/lib/lib.webworker.importscripts.d.ts +0 -26
- package/lib/node_modules/ohos-typescript/lib/lib.webworker.iterable.d.ts +0 -175
- package/lib/node_modules/ohos-typescript/lib/pl/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/pt-br/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/ru/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/tr/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/tsc.js +0 -114551
- package/lib/node_modules/ohos-typescript/lib/tsserver.js +0 -179691
- package/lib/node_modules/ohos-typescript/lib/tsserverlibrary.d.ts +0 -13648
- package/lib/node_modules/ohos-typescript/lib/tsserverlibrary.js +0 -178688
- package/lib/node_modules/ohos-typescript/lib/typesMap.json +0 -497
- package/lib/node_modules/ohos-typescript/lib/typingsInstaller.js +0 -39871
- package/lib/node_modules/ohos-typescript/lib/watchGuard.js +0 -49
- package/lib/node_modules/ohos-typescript/lib/zh-cn/diagnosticMessages.generated.json +0 -1880
- package/lib/node_modules/ohos-typescript/lib/zh-tw/diagnosticMessages.generated.json +0 -1880
- package/lib/utils/DependenciesSort.d.ts +0 -3
- package/lib/utils/DependenciesSort.d.ts.map +0 -1
- package/lib/utils/DependenciesSort.js +0 -72
- package/lib/utils/crypto_utils.d.ts +0 -6
- package/lib/utils/crypto_utils.d.ts.map +0 -1
- package/lib/utils/crypto_utils.js +0 -57
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2024-2026 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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.StageStatistics = exports.StageName = void 0;
|
|
18
|
+
const SignatureCanonicalizerRegistry_1 = require("../core/common/SignatureCanonicalizerRegistry");
|
|
19
|
+
/**
|
|
20
|
+
* Stage Statistics Module
|
|
21
|
+
*
|
|
22
|
+
* Collects time and memory metrics for execution stages (e.g. builder, inferTypes).
|
|
23
|
+
* Designed as a generic, stage-name-agnostic collector so that future modules
|
|
24
|
+
* (CG, PTA, etc.) can plug in via `startStage(name)` without interface changes.
|
|
25
|
+
*
|
|
26
|
+
* Key design points:
|
|
27
|
+
* - `enabled` switch: every public method early-returns when disabled (zero overhead).
|
|
28
|
+
* - Named timers via `startStage(name)` / `endStage(name)`; repeated names auto-suffix
|
|
29
|
+
* with `#2`, `#3`, ... so multiple `inferTypes()` calls are distinguished.
|
|
30
|
+
* - Stage nesting: a stage started while another is still running becomes its child
|
|
31
|
+
* (stack top at start time = parent); the report renders children indented.
|
|
32
|
+
* - Memory peak tracked via synchronous checkpoint sampling at key points
|
|
33
|
+
* (`start`, `startStage`, `endStage`, `finish`, and `recordMemoryCheckpoint`).
|
|
34
|
+
* No `setInterval` is used — Node.js single-threaded event loop cannot schedule
|
|
35
|
+
* timer callbacks during CPU-intensive synchronous operations (AST parsing, IR
|
|
36
|
+
* construction, type inference), making interval-based sampling unreliable.
|
|
37
|
+
* - `customCounters` Map for extensible, module-specific counters.
|
|
38
|
+
* - `recordSignatureStats(label)`: signature-space snapshots (formal canonicalizer
|
|
39
|
+
* sizes + temp index-table stats) at checkpoints like post-build / post-infer.
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Built-in stage names used by ArkAnalyzer's core pipeline.
|
|
43
|
+
*
|
|
44
|
+
* `startStage` / `endStage` accept any `string`, so external modules and
|
|
45
|
+
* future stages (e.g. CG, PTA) can pass their own names or extend this enum.
|
|
46
|
+
* Using the enum provides compile-time safety and IDE autocompletion for
|
|
47
|
+
* well-known stages, while the string overload keeps the interface open.
|
|
48
|
+
*
|
|
49
|
+
* Hierarchy: a stage started while another stage is still running becomes its
|
|
50
|
+
* child (nesting is captured automatically; the report renders indentation).
|
|
51
|
+
*/
|
|
52
|
+
var StageName;
|
|
53
|
+
(function (StageName) {
|
|
54
|
+
/** 构建总阶段(Scene 构建入口整体,含其下全部细分阶段)。 */
|
|
55
|
+
StageName["Builder"] = "builder";
|
|
56
|
+
/** 细分:构建期配置解析(build-profile / oh-package / tsconfig,SceneBuilder.parseProjectConfigs)。 */
|
|
57
|
+
StageName["BuilderParseConfigs"] = "builderParseConfigs";
|
|
58
|
+
/** 细分:SDK 构建与推断阶段(SceneBuilder.buildSdkStage)。 */
|
|
59
|
+
StageName["BuilderSdk"] = "builderSdk";
|
|
60
|
+
/** 细分(BuilderSdk 子阶段):SDK 源文件注册构建(buildSdk 逐文件解析注册)。 */
|
|
61
|
+
StageName["BuilderSdkFiles"] = "builderSdkFiles";
|
|
62
|
+
/** 细分(BuilderSdk 子阶段):SDK 类型推导与 global API 合并(doInfer + mergeGlobalAPI + postInferredSdk)。 */
|
|
63
|
+
StageName["BuilderSdkInfer"] = "builderSdkInfer";
|
|
64
|
+
/** 细分:project 文件 DFS 构建(SceneBuilder.buildProjectFiles)。 */
|
|
65
|
+
StageName["BuilderFiles"] = "builderFiles";
|
|
66
|
+
/** 细分:方法体构建(SceneBuilder.buildAllMethodBodies)。 */
|
|
67
|
+
StageName["BuilderBodies"] = "builderBodies";
|
|
68
|
+
/** 推断单轮(inferTypes 的每轮遍历,多轮自动 #2/#3 后缀)。 */
|
|
69
|
+
StageName["InferTypes"] = "inferTypes";
|
|
70
|
+
/** 推断收尾(buildStage 推进 + temp 完整性检查 + validate + 各 dispose)。 */
|
|
71
|
+
StageName["InferTypesFinalize"] = "inferTypesFinalize";
|
|
72
|
+
})(StageName = exports.StageName || (exports.StageName = {}));
|
|
73
|
+
function emptySnapshot() {
|
|
74
|
+
return { rssMB: 0, heapUsedMB: 0, heapTotalMB: 0 };
|
|
75
|
+
}
|
|
76
|
+
function captureMemory() {
|
|
77
|
+
const m = process.memoryUsage();
|
|
78
|
+
return {
|
|
79
|
+
rssMB: m.rss / 1024 / 1024,
|
|
80
|
+
heapUsedMB: m.heapUsed / 1024 / 1024,
|
|
81
|
+
heapTotalMB: m.heapTotal / 1024 / 1024,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function maxSnapshot(a, b) {
|
|
85
|
+
return {
|
|
86
|
+
rssMB: Math.max(a.rssMB, b.rssMB),
|
|
87
|
+
heapUsedMB: Math.max(a.heapUsedMB, b.heapUsedMB),
|
|
88
|
+
heapTotalMB: Math.max(a.heapTotalMB, b.heapTotalMB),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
class StageStatistics {
|
|
92
|
+
constructor(enabled = false) {
|
|
93
|
+
this.runningStages = new Map();
|
|
94
|
+
this.stageNameCounts = new Map();
|
|
95
|
+
this.completedStages = [];
|
|
96
|
+
this.customCounters = new Map();
|
|
97
|
+
this.signatureSnapshots = [];
|
|
98
|
+
this.enabled = enabled;
|
|
99
|
+
this.startTime = 0;
|
|
100
|
+
this.endTime = 0;
|
|
101
|
+
this.globalSampledPeak = emptySnapshot();
|
|
102
|
+
this.globalMemBefore = emptySnapshot();
|
|
103
|
+
this.globalMemAfter = emptySnapshot();
|
|
104
|
+
this.finished = false;
|
|
105
|
+
}
|
|
106
|
+
enable() {
|
|
107
|
+
this.enabled = true;
|
|
108
|
+
}
|
|
109
|
+
disable() {
|
|
110
|
+
this.enabled = false;
|
|
111
|
+
}
|
|
112
|
+
isEnabled() {
|
|
113
|
+
return this.enabled;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Start global timing and memory sampling.
|
|
117
|
+
*/
|
|
118
|
+
start() {
|
|
119
|
+
if (!this.enabled) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
this.startTime = Date.now();
|
|
123
|
+
this.globalMemBefore = captureMemory();
|
|
124
|
+
this.globalSampledPeak = Object.assign({}, this.globalMemBefore);
|
|
125
|
+
this.finished = false;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Start a named stage. If the same name has been used before, a suffix `#N` is appended.
|
|
129
|
+
*
|
|
130
|
+
* Nesting: the most recently started still-running stage (stack top) becomes
|
|
131
|
+
* this stage's parent — the report renders children indented under it.
|
|
132
|
+
*/
|
|
133
|
+
startStage(name) {
|
|
134
|
+
if (!this.enabled) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const uniqueName = this.resolveUniqueName(name);
|
|
138
|
+
const memBefore = captureMemory();
|
|
139
|
+
this.globalSampledPeak = maxSnapshot(this.globalSampledPeak, memBefore);
|
|
140
|
+
this.runningStages.set(uniqueName, {
|
|
141
|
+
name: uniqueName,
|
|
142
|
+
startTime: Date.now(),
|
|
143
|
+
memBefore,
|
|
144
|
+
sampledPeak: Object.assign({}, memBefore),
|
|
145
|
+
parentName: this.currentStackTop(uniqueName),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* End a named stage and record its entry.
|
|
150
|
+
* Looks up the running stage whose unique name equals `name` or matches the `name#N` pattern.
|
|
151
|
+
*/
|
|
152
|
+
endStage(name) {
|
|
153
|
+
if (!this.enabled) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const uniqueName = this.findRunningStageName(name);
|
|
157
|
+
if (!uniqueName) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const rs = this.runningStages.get(uniqueName);
|
|
161
|
+
if (!rs) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
this.runningStages.delete(uniqueName);
|
|
165
|
+
const memAfter = captureMemory();
|
|
166
|
+
this.globalSampledPeak = maxSnapshot(this.globalSampledPeak, memAfter);
|
|
167
|
+
const memPeak = maxSnapshot(rs.sampledPeak, memAfter);
|
|
168
|
+
this.completedStages.push({
|
|
169
|
+
name: uniqueName,
|
|
170
|
+
parent: rs.parentName,
|
|
171
|
+
durationMs: Date.now() - rs.startTime,
|
|
172
|
+
memBefore: rs.memBefore,
|
|
173
|
+
memPeak,
|
|
174
|
+
memAfter,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Record a memory checkpoint inside the current running stage.
|
|
179
|
+
*
|
|
180
|
+
* Synchronously captures memory and updates both the global peak and the
|
|
181
|
+
* current running stage's peak. Use this at fine-grained points within
|
|
182
|
+
* long-running stages (e.g. inside per-method or per-file loops) to track
|
|
183
|
+
* memory growth that `startStage`/`endStage` alone would miss.
|
|
184
|
+
*/
|
|
185
|
+
recordMemoryCheckpoint() {
|
|
186
|
+
if (!this.enabled) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const cur = captureMemory();
|
|
190
|
+
this.globalSampledPeak = maxSnapshot(this.globalSampledPeak, cur);
|
|
191
|
+
for (const rs of this.runningStages.values()) {
|
|
192
|
+
rs.sampledPeak = maxSnapshot(rs.sampledPeak, cur);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Finish global timing and records final memory.
|
|
197
|
+
*/
|
|
198
|
+
finish() {
|
|
199
|
+
if (!this.enabled || this.finished) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
this.runningStages.clear();
|
|
203
|
+
this.globalMemAfter = captureMemory();
|
|
204
|
+
this.globalSampledPeak = maxSnapshot(this.globalSampledPeak, this.globalMemAfter);
|
|
205
|
+
this.endTime = Date.now();
|
|
206
|
+
this.finished = true;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Increment a custom counter (extensible for future modules).
|
|
210
|
+
*/
|
|
211
|
+
incrementCustomCounter(name, value = 1) {
|
|
212
|
+
var _a;
|
|
213
|
+
if (!this.enabled) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
this.customCounters.set(name, ((_a = this.customCounters.get(name)) !== null && _a !== void 0 ? _a : 0) + value);
|
|
217
|
+
}
|
|
218
|
+
getCustomCounter(name) {
|
|
219
|
+
var _a;
|
|
220
|
+
return (_a = this.customCounters.get(name)) !== null && _a !== void 0 ? _a : 0;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Snapshot the signature-space sizes at a checkpoint (e.g. 'post-build' /
|
|
224
|
+
* 'post-infer'): formal canonicalizer entry counts per space + temp
|
|
225
|
+
* index-table stats (live/retired/replaced). Read-only against the registry.
|
|
226
|
+
*/
|
|
227
|
+
recordSignatureStats(label) {
|
|
228
|
+
if (!this.enabled) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const reg = SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance();
|
|
232
|
+
this.signatureSnapshots.push({
|
|
233
|
+
label,
|
|
234
|
+
formal: {
|
|
235
|
+
file: reg.fileSigCanonicalizer.size(),
|
|
236
|
+
class: reg.classSigCanonicalizer.size(),
|
|
237
|
+
namespace: reg.namespaceSigCanonicalizer.size(),
|
|
238
|
+
field: reg.fieldSigCanonicalizer.size(),
|
|
239
|
+
method: reg.methodSigCanonicalizer.size(),
|
|
240
|
+
},
|
|
241
|
+
temp: SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance().getTempSpacesStats(),
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get the complete statistics data. Auto-finishes if still running.
|
|
246
|
+
*/
|
|
247
|
+
getStatistics() {
|
|
248
|
+
if (this.enabled && !this.finished) {
|
|
249
|
+
this.finish();
|
|
250
|
+
}
|
|
251
|
+
const totalDurationMs = this.startTime > 0 && this.endTime > 0 ? this.endTime - this.startTime : 0;
|
|
252
|
+
return {
|
|
253
|
+
stages: this.completedStages.map(s => (Object.assign({}, s))),
|
|
254
|
+
totalDurationMs,
|
|
255
|
+
globalMemBefore: Object.assign({}, this.globalMemBefore),
|
|
256
|
+
globalMemPeak: Object.assign({}, this.globalSampledPeak),
|
|
257
|
+
globalMemAfter: Object.assign({}, this.globalMemAfter),
|
|
258
|
+
customCounters: new Map(this.customCounters),
|
|
259
|
+
signatureSnapshots: this.signatureSnapshots.map(s => ({
|
|
260
|
+
label: s.label,
|
|
261
|
+
formal: Object.assign({}, s.formal),
|
|
262
|
+
temp: { class: Object.assign({}, s.temp.class), method: Object.assign({}, s.temp.method), field: Object.assign({}, s.temp.field) },
|
|
263
|
+
})),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Reset all collected data.
|
|
268
|
+
*/
|
|
269
|
+
reset() {
|
|
270
|
+
this.runningStages.clear();
|
|
271
|
+
this.stageNameCounts.clear();
|
|
272
|
+
this.completedStages.length = 0;
|
|
273
|
+
this.customCounters.clear();
|
|
274
|
+
this.signatureSnapshots.length = 0;
|
|
275
|
+
this.startTime = 0;
|
|
276
|
+
this.endTime = 0;
|
|
277
|
+
this.globalSampledPeak = emptySnapshot();
|
|
278
|
+
this.globalMemBefore = emptySnapshot();
|
|
279
|
+
this.globalMemAfter = emptySnapshot();
|
|
280
|
+
this.finished = false;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Export statistics as a JSON string (Map is converted to a plain object).
|
|
284
|
+
*/
|
|
285
|
+
exportToJson() {
|
|
286
|
+
const data = this.getStatistics();
|
|
287
|
+
const customCounters = {};
|
|
288
|
+
data.customCounters.forEach((v, k) => {
|
|
289
|
+
customCounters[k] = v;
|
|
290
|
+
});
|
|
291
|
+
return JSON.stringify(Object.assign(Object.assign({}, data), { customCounters }), null, 2);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Resolve a unique stage name by appending `#N` if the name was used before.
|
|
295
|
+
* The first use keeps the original name; subsequent uses get `#2`, `#3`, ...
|
|
296
|
+
*/
|
|
297
|
+
resolveUniqueName(name) {
|
|
298
|
+
var _a;
|
|
299
|
+
const count = ((_a = this.stageNameCounts.get(name)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
300
|
+
this.stageNameCounts.set(name, count);
|
|
301
|
+
if (count === 1) {
|
|
302
|
+
return name;
|
|
303
|
+
}
|
|
304
|
+
return `${name}#${count}`;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* The most recently started still-running stage (Map insertion order = start
|
|
308
|
+
* order; the last key is the stack top). The stage being started itself is
|
|
309
|
+
* excluded from the candidate set.
|
|
310
|
+
*/
|
|
311
|
+
currentStackTop(excludeName) {
|
|
312
|
+
let top;
|
|
313
|
+
for (const key of this.runningStages.keys()) {
|
|
314
|
+
if (key !== excludeName) {
|
|
315
|
+
top = key;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return top;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Find the unique name of a currently running stage that matches the given base name.
|
|
322
|
+
* Matches `name` exactly or the `name#N` pattern. Returns the most recently started match.
|
|
323
|
+
*/
|
|
324
|
+
findRunningStageName(name) {
|
|
325
|
+
if (this.runningStages.size === 0) {
|
|
326
|
+
return undefined;
|
|
327
|
+
}
|
|
328
|
+
let exact;
|
|
329
|
+
let suffixed;
|
|
330
|
+
let suffixedNum = -1;
|
|
331
|
+
for (const key of this.runningStages.keys()) {
|
|
332
|
+
if (key === name) {
|
|
333
|
+
exact = key;
|
|
334
|
+
}
|
|
335
|
+
else if (key.startsWith(`${name}#`)) {
|
|
336
|
+
const num = parseInt(key.slice(name.length + 1), 10);
|
|
337
|
+
if (!isNaN(num) && num > suffixedNum) {
|
|
338
|
+
suffixedNum = num;
|
|
339
|
+
suffixed = key;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return suffixed !== null && suffixed !== void 0 ? suffixed : exact;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
exports.StageStatistics = StageStatistics;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { StageStatisticsData } from './StageStatistics';
|
|
2
|
+
/**
|
|
3
|
+
* A logical section of the statistics report.
|
|
4
|
+
*/
|
|
5
|
+
export interface ReportSection {
|
|
6
|
+
title: string;
|
|
7
|
+
data: Record<string, string | number>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Structured statistics report.
|
|
11
|
+
*/
|
|
12
|
+
export interface StageStatisticsReport {
|
|
13
|
+
title: string;
|
|
14
|
+
timestamp: string;
|
|
15
|
+
summary: ReportSection;
|
|
16
|
+
stages: ReportSection;
|
|
17
|
+
signatures: ReportSection;
|
|
18
|
+
custom: ReportSection;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generates text reports from {@link StageStatisticsData}.
|
|
22
|
+
*
|
|
23
|
+
* Output format is a human-readable, sectioned text block suitable for
|
|
24
|
+
* file output or logger.info.
|
|
25
|
+
*/
|
|
26
|
+
export declare class StageStatisticsReporter {
|
|
27
|
+
/**
|
|
28
|
+
* Build a structured report from raw statistics data.
|
|
29
|
+
*/
|
|
30
|
+
static generateReport(data: StageStatisticsData, title?: string): StageStatisticsReport;
|
|
31
|
+
private static generateSummarySection;
|
|
32
|
+
private static generateStagesSection;
|
|
33
|
+
private static generateSignatureSection;
|
|
34
|
+
private static generateCustomSection;
|
|
35
|
+
/**
|
|
36
|
+
* Render a report as a text string.
|
|
37
|
+
*/
|
|
38
|
+
static exportToText(report: StageStatisticsReport): string;
|
|
39
|
+
private static formatSection;
|
|
40
|
+
/**
|
|
41
|
+
* Format the stages section: values are pre-formatted multi-line strings
|
|
42
|
+
* stored as numbered keys; render them directly without `key: value`.
|
|
43
|
+
*/
|
|
44
|
+
private static formatStageSection;
|
|
45
|
+
/**
|
|
46
|
+
* Save a text report to a file.
|
|
47
|
+
*/
|
|
48
|
+
static saveReportToFile(report: StageStatisticsReport, filePath: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Check whether statistics data contains meaningful values.
|
|
51
|
+
*/
|
|
52
|
+
static isStatisticsValid(data: StageStatisticsData): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Generate a one-line status message.
|
|
55
|
+
*/
|
|
56
|
+
static generateStatusMessage(data: StageStatisticsData): string;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=StageStatisticsReporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StageStatisticsReporter.d.ts","sourceRoot":"","sources":["../../src/statistics/StageStatisticsReporter.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAkC,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,aAAa,CAAC;IAC1B,MAAM,EAAE,aAAa,CAAC;CACzB;AAgCD;;;;;GAKG;AACH,qBAAa,uBAAuB;IAChC;;OAEG;WACW,cAAc,CAAC,IAAI,EAAE,mBAAmB,EAAE,KAAK,GAAE,MAA8C,GAAG,qBAAqB;IAWrI,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAerC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IA8CpC,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAgCvC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAWpC;;OAEG;WACW,YAAY,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM;IAkBjE,OAAO,CAAC,MAAM,CAAC,aAAa;IAc5B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAUjC;;OAEG;WACW,gBAAgB,CAAC,MAAM,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IASrF;;OAEG;WACW,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO;IAInE;;OAEG;WACW,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM;CAMzE"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2024-2026 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.StageStatisticsReporter = void 0;
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
function formatLocalTimestamp(date = new Date()) {
|
|
43
|
+
const pad2 = (n) => n.toString().padStart(2, '0');
|
|
44
|
+
const pad3 = (n) => n.toString().padStart(3, '0');
|
|
45
|
+
const y = date.getFullYear();
|
|
46
|
+
const mo = pad2(date.getMonth() + 1);
|
|
47
|
+
const d = pad2(date.getDate());
|
|
48
|
+
const h = pad2(date.getHours());
|
|
49
|
+
const mi = pad2(date.getMinutes());
|
|
50
|
+
const s = pad2(date.getSeconds());
|
|
51
|
+
const ms = pad3(date.getMilliseconds());
|
|
52
|
+
const offsetMin = -date.getTimezoneOffset();
|
|
53
|
+
const sign = offsetMin >= 0 ? '+' : '-';
|
|
54
|
+
const abs = Math.abs(offsetMin);
|
|
55
|
+
const offH = pad2(Math.floor(abs / 60));
|
|
56
|
+
const offM = pad2(abs % 60);
|
|
57
|
+
return `${y}-${mo}-${d}T${h}:${mi}:${s}.${ms}${sign}${offH}:${offM}`;
|
|
58
|
+
}
|
|
59
|
+
function fmtMB(v) {
|
|
60
|
+
return v.toFixed(2);
|
|
61
|
+
}
|
|
62
|
+
function fmtMs(v) {
|
|
63
|
+
return `${v} ms`;
|
|
64
|
+
}
|
|
65
|
+
function memLine(label, m) {
|
|
66
|
+
return `${label}: RSS ${fmtMB(m.rssMB)} MB | Heap ${fmtMB(m.heapUsedMB)} MB`;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Generates text reports from {@link StageStatisticsData}.
|
|
70
|
+
*
|
|
71
|
+
* Output format is a human-readable, sectioned text block suitable for
|
|
72
|
+
* file output or logger.info.
|
|
73
|
+
*/
|
|
74
|
+
class StageStatisticsReporter {
|
|
75
|
+
/**
|
|
76
|
+
* Build a structured report from raw statistics data.
|
|
77
|
+
*/
|
|
78
|
+
static generateReport(data, title = 'ArkAnalyzer Stage Statistics Report') {
|
|
79
|
+
return {
|
|
80
|
+
title,
|
|
81
|
+
timestamp: formatLocalTimestamp(),
|
|
82
|
+
summary: this.generateSummarySection(data),
|
|
83
|
+
stages: this.generateStagesSection(data),
|
|
84
|
+
signatures: this.generateSignatureSection(data),
|
|
85
|
+
custom: this.generateCustomSection(data),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
static generateSummarySection(data) {
|
|
89
|
+
const incremental = data.globalMemPeak.rssMB - data.globalMemBefore.rssMB;
|
|
90
|
+
return {
|
|
91
|
+
title: 'Summary',
|
|
92
|
+
data: {
|
|
93
|
+
'Total Time': fmtMs(data.totalDurationMs),
|
|
94
|
+
[memLine('Start', data.globalMemBefore)]: '',
|
|
95
|
+
[memLine('Peak', data.globalMemPeak)]: '',
|
|
96
|
+
[memLine('End', data.globalMemAfter)]: '',
|
|
97
|
+
'Incremental RSS': `${fmtMB(incremental)} MB`,
|
|
98
|
+
'Stage Count': data.stages.length,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
static generateStagesSection(data) {
|
|
103
|
+
// 层级树形渲染:按 parent 关系组树(完成序天然子先于父,平铺会散乱),
|
|
104
|
+
// DFS 先序输出——父阶段在前,子阶段按各自完成序缩进跟随。两遍扫描(先
|
|
105
|
+
// 建全量索引再连边——完成序中父后于子,单遍会误判 root)。parent 链断落
|
|
106
|
+
// (如父阶段未记录)按顶层渲染,防御不崩。
|
|
107
|
+
const byName = new Map();
|
|
108
|
+
for (const stage of data.stages) {
|
|
109
|
+
byName.set(stage.name, { stage, children: [] });
|
|
110
|
+
}
|
|
111
|
+
const roots = [];
|
|
112
|
+
for (const stage of data.stages) {
|
|
113
|
+
const p = stage.parent;
|
|
114
|
+
if (p !== undefined && byName.has(p)) {
|
|
115
|
+
byName.get(p).children.push(stage);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
roots.push(stage);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const entries = [];
|
|
122
|
+
const render = (stage, depth) => {
|
|
123
|
+
const indent = ' '.repeat(depth);
|
|
124
|
+
entries.push(`${indent}[${stage.name}]`);
|
|
125
|
+
entries.push(`${indent} Duration: ${fmtMs(stage.durationMs)}`);
|
|
126
|
+
entries.push(`${indent} ${memLine(' Before', stage.memBefore)}`);
|
|
127
|
+
entries.push(`${indent} ${memLine(' Peak', stage.memPeak)}`);
|
|
128
|
+
entries.push(`${indent} ${memLine(' After', stage.memAfter)}`);
|
|
129
|
+
for (const child of byName.get(stage.name).children) {
|
|
130
|
+
render(child, depth + 1);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
for (const root of roots) {
|
|
134
|
+
render(root, 0);
|
|
135
|
+
}
|
|
136
|
+
if (entries.length === 0) {
|
|
137
|
+
entries.push('(no stages recorded)');
|
|
138
|
+
}
|
|
139
|
+
const dataMap = {};
|
|
140
|
+
entries.forEach((line, i) => {
|
|
141
|
+
dataMap[`line${i}`] = line;
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
title: 'Stage Statistics',
|
|
145
|
+
data: dataMap,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
static generateSignatureSection(data) {
|
|
149
|
+
const entries = [];
|
|
150
|
+
for (const snap of data.signatureSnapshots) {
|
|
151
|
+
const formalTotal = snap.formal.file + snap.formal.class + snap.formal.namespace + snap.formal.field + snap.formal.method;
|
|
152
|
+
entries.push(`[${snap.label}]`);
|
|
153
|
+
entries.push(` Formal: file=${snap.formal.file.toLocaleString()} class=${snap.formal.class.toLocaleString()} namespace=${snap.formal.namespace.toLocaleString()}` +
|
|
154
|
+
` field=${snap.formal.field.toLocaleString()} method=${snap.formal.method.toLocaleString()} (total=${formalTotal.toLocaleString()})`);
|
|
155
|
+
entries.push(` Temp class : live=${snap.temp.class.liveCount.toLocaleString()} total=${snap.temp.class.totalRegistered.toLocaleString()}` +
|
|
156
|
+
` retired=${snap.temp.class.retiredCount.toLocaleString()} replaced=${snap.temp.class.replacedCount.toLocaleString()}`);
|
|
157
|
+
entries.push(` Temp method: live=${snap.temp.method.liveCount.toLocaleString()} total=${snap.temp.method.totalRegistered.toLocaleString()}` +
|
|
158
|
+
` retired=${snap.temp.method.retiredCount.toLocaleString()} replaced=${snap.temp.method.replacedCount.toLocaleString()}`);
|
|
159
|
+
entries.push(` Temp field : live=${snap.temp.field.liveCount.toLocaleString()} total=${snap.temp.field.totalRegistered.toLocaleString()}` +
|
|
160
|
+
` retired=${snap.temp.field.retiredCount.toLocaleString()} replaced=${snap.temp.field.replacedCount.toLocaleString()}`);
|
|
161
|
+
}
|
|
162
|
+
const dataMap = {};
|
|
163
|
+
entries.forEach((line, i) => {
|
|
164
|
+
dataMap[`line${i}`] = line;
|
|
165
|
+
});
|
|
166
|
+
return {
|
|
167
|
+
title: 'Signature Statistics',
|
|
168
|
+
data: dataMap,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
static generateCustomSection(data) {
|
|
172
|
+
const dataMap = {};
|
|
173
|
+
data.customCounters.forEach((value, key) => {
|
|
174
|
+
dataMap[key] = value.toLocaleString();
|
|
175
|
+
});
|
|
176
|
+
return {
|
|
177
|
+
title: 'Custom Statistics',
|
|
178
|
+
data: dataMap,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Render a report as a text string.
|
|
183
|
+
*/
|
|
184
|
+
static exportToText(report) {
|
|
185
|
+
const sep = '='.repeat(40);
|
|
186
|
+
let out = `${sep}\n`;
|
|
187
|
+
out += `${report.title}\n`;
|
|
188
|
+
out += `${sep}\n`;
|
|
189
|
+
out += `Generated Time: ${report.timestamp}\n\n`;
|
|
190
|
+
out += this.formatSection(report.summary);
|
|
191
|
+
out += this.formatStageSection(report.stages);
|
|
192
|
+
if (Object.keys(report.signatures.data).length > 0) {
|
|
193
|
+
out += this.formatStageSection(report.signatures);
|
|
194
|
+
}
|
|
195
|
+
if (Object.keys(report.custom.data).length > 0) {
|
|
196
|
+
out += this.formatSection(report.custom);
|
|
197
|
+
}
|
|
198
|
+
out += `${sep}\n`;
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
static formatSection(section) {
|
|
202
|
+
let out = `${section.title}\n`;
|
|
203
|
+
out += '-'.repeat(section.title.length) + '\n';
|
|
204
|
+
for (const [key, value] of Object.entries(section.data)) {
|
|
205
|
+
if (value === '') {
|
|
206
|
+
out += `${key}\n`;
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
out += `${key}: ${value}\n`;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
out += '\n';
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Format the stages section: values are pre-formatted multi-line strings
|
|
217
|
+
* stored as numbered keys; render them directly without `key: value`.
|
|
218
|
+
*/
|
|
219
|
+
static formatStageSection(section) {
|
|
220
|
+
let out = `${section.title}\n`;
|
|
221
|
+
out += '-'.repeat(section.title.length) + '\n';
|
|
222
|
+
for (const value of Object.values(section.data)) {
|
|
223
|
+
out += `${value}\n`;
|
|
224
|
+
}
|
|
225
|
+
out += '\n';
|
|
226
|
+
return out;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Save a text report to a file.
|
|
230
|
+
*/
|
|
231
|
+
static saveReportToFile(report, filePath) {
|
|
232
|
+
const text = this.exportToText(report);
|
|
233
|
+
const dir = filePath.substring(0, Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\')));
|
|
234
|
+
if (dir) {
|
|
235
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
236
|
+
}
|
|
237
|
+
fs.writeFileSync(filePath, text, 'utf-8');
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Check whether statistics data contains meaningful values.
|
|
241
|
+
*/
|
|
242
|
+
static isStatisticsValid(data) {
|
|
243
|
+
return data.totalDurationMs > 0 || data.stages.length > 0;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Generate a one-line status message.
|
|
247
|
+
*/
|
|
248
|
+
static generateStatusMessage(data) {
|
|
249
|
+
if (!this.isStatisticsValid(data)) {
|
|
250
|
+
return 'No valid statistics data collected.';
|
|
251
|
+
}
|
|
252
|
+
return `Analysis completed in ${data.totalDurationMs} ms across ${data.stages.length} stage(s).`;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
exports.StageStatisticsReporter = StageStatisticsReporter;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type CanonicalizerStrategy = 'uninitialized' | 'objectIdentity' | 'numberWithEquality' | 'stringIdentity';
|
|
2
|
-
interface CanonicalizerStats {
|
|
2
|
+
export interface CanonicalizerStats {
|
|
3
3
|
strategy: CanonicalizerStrategy;
|
|
4
4
|
size: number;
|
|
5
5
|
bucketCount: number;
|
|
@@ -57,7 +57,14 @@ export declare class Canonicalizer<T> {
|
|
|
57
57
|
*/
|
|
58
58
|
get(id: number): T | undefined;
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
60
|
+
* Remove the item at the given ID by setting the slot to undefined.
|
|
61
|
+
* The ID is NOT recycled — subsequent registrations still get fresh dense IDs.
|
|
62
|
+
* Note: does NOT remove the Symbol property from the object (if objectIdentity strategy);
|
|
63
|
+
* the Symbol remains for audit traceability.
|
|
64
|
+
*/
|
|
65
|
+
removeAt(id: number): void;
|
|
66
|
+
/**
|
|
67
|
+
* Get the total number of unique items seen so far (includes removed slots).
|
|
61
68
|
*/
|
|
62
69
|
size(): number;
|
|
63
70
|
getStats(): CanonicalizerStats;
|