arkanalyzer 1.0.94 → 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.js +1 -1
- 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 +455 -265
- 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 +181 -53
- 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 +116 -71
- 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/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
package/lib/Scene.js
CHANGED
|
@@ -40,7 +40,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
40
40
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
41
|
};
|
|
42
42
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
-
exports.
|
|
43
|
+
exports.Scene = exports.ModuleScene = exports.SceneBuildStage = void 0;
|
|
44
44
|
const fs_1 = __importDefault(require("fs"));
|
|
45
45
|
const path_1 = __importDefault(require("path"));
|
|
46
46
|
const ModelUtils_1 = require("./core/common/ModelUtils");
|
|
@@ -48,53 +48,74 @@ const TypeInference_1 = require("./core/common/TypeInference");
|
|
|
48
48
|
const VisibleValue_1 = require("./core/common/VisibleValue");
|
|
49
49
|
const ArkFile_1 = require("./core/model/ArkFile");
|
|
50
50
|
const ArkNamespace_1 = require("./core/model/ArkNamespace");
|
|
51
|
-
const ArkSignature_1 = require("./core/model/ArkSignature");
|
|
52
51
|
const ModuleAnalysisConfig_1 = require("./frontend/common/ModuleAnalysisConfig");
|
|
53
52
|
const ModuleBuilder_1 = require("./frontend/common/ModuleBuilder");
|
|
54
53
|
const logger_1 = __importStar(require("./utils/logger"));
|
|
55
|
-
const json5parser_1 = require("./utils/json5parser");
|
|
56
|
-
const getAllFiles_1 = require("./utils/getAllFiles");
|
|
57
|
-
const FileUtils_1 = require("./utils/FileUtils");
|
|
58
54
|
const ArkExport_1 = require("./core/model/ArkExport");
|
|
59
|
-
const ArkMethodBuilder_1 = require("./core/model/builder/ArkMethodBuilder");
|
|
60
|
-
const ArkMethodBuilder_2 = require("./frontend/cppFrontend/model/builder/ArkMethodBuilder");
|
|
61
55
|
const builderUtils_1 = require("./frontend/cppFrontend/model/builder/builderUtils");
|
|
56
|
+
const ArkFileBuilder_1 = require("./frontend/cppFrontend/model/builder/ArkFileBuilder");
|
|
62
57
|
const Const_1 = require("./core/common/Const");
|
|
63
58
|
const CallGraph_1 = require("./callgraph/model/CallGraph");
|
|
64
59
|
const CallGraphBuilder_1 = require("./callgraph/model/builder/CallGraphBuilder");
|
|
65
60
|
const IRInference_1 = require("./frontend/cppFrontend/common/IRInference");
|
|
66
|
-
const
|
|
67
|
-
const FrontendBuilder_1 = require("./frontend/FrontendBuilder");
|
|
68
|
-
const TSConst_1 = require("./core/common/TSConst");
|
|
69
|
-
const EtsConst_1 = require("./core/common/EtsConst");
|
|
61
|
+
const SceneBuilder_1 = require("./frontend/SceneBuilder");
|
|
70
62
|
const SdkUtils_1 = require("./core/common/SdkUtils");
|
|
71
63
|
const PointerAnalysisConfig_1 = require("./callgraph/pointerAnalysis/PointerAnalysisConfig");
|
|
72
64
|
const ValueUtil_1 = require("./core/common/ValueUtil");
|
|
73
65
|
const Inference_1 = require("./core/inference/Inference");
|
|
74
66
|
const IRInference_2 = require("./core/common/IRInference");
|
|
75
67
|
const ModuleUtils_1 = require("./utils/ModuleUtils");
|
|
76
|
-
const DependenciesSort_1 = require("./utils/DependenciesSort");
|
|
77
68
|
const Canonicalizer_1 = require("./utils/Canonicalizer");
|
|
78
69
|
const ModuleDepGraph_1 = require("./core/graph/ModuleDepGraph");
|
|
70
|
+
const SignatureCanonicalizerRegistry_1 = require("./core/common/SignatureCanonicalizerRegistry");
|
|
71
|
+
const CanonicalizerValidator_1 = require("./core/common/CanonicalizerValidator");
|
|
72
|
+
const ArkSignatureBuilder_1 = require("./core/model/builder/ArkSignatureBuilder");
|
|
73
|
+
const StageStatistics_1 = require("./statistics/StageStatistics");
|
|
74
|
+
const StageStatisticsReporter_1 = require("./statistics/StageStatisticsReporter");
|
|
79
75
|
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'Scene');
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
SceneBuildStage[SceneBuildStage["METHOD_COLLECTED"] = 5] = "METHOD_COLLECTED";
|
|
88
|
-
SceneBuildStage[SceneBuildStage["TYPE_INFERRED"] = 6] = "TYPE_INFERRED";
|
|
89
|
-
})(SceneBuildStage = exports.SceneBuildStage || (exports.SceneBuildStage = {}));
|
|
76
|
+
// 枚举与 ModuleScene 已拆至 frontend 独立文件(解 Scene↔frontend 值导入循环),
|
|
77
|
+
// 此处 re-export 保持对外兼容。
|
|
78
|
+
var SceneBuildStage_1 = require("./frontend/SceneBuildStage");
|
|
79
|
+
Object.defineProperty(exports, "SceneBuildStage", { enumerable: true, get: function () { return SceneBuildStage_1.SceneBuildStage; } });
|
|
80
|
+
var ModuleScene_1 = require("./frontend/ModuleScene");
|
|
81
|
+
Object.defineProperty(exports, "ModuleScene", { enumerable: true, get: function () { return ModuleScene_1.ModuleScene; } });
|
|
82
|
+
const SceneBuildStage_2 = require("./frontend/SceneBuildStage");
|
|
90
83
|
/**
|
|
91
84
|
* The Scene class includes everything in the analyzed project.
|
|
92
85
|
* We should be able to re-generate the project's code based on this class.
|
|
93
86
|
*/
|
|
94
87
|
class Scene {
|
|
88
|
+
// --- Canonicalizers moved to SignatureCanonicalizerRegistry (global singleton) ---
|
|
89
|
+
/** @internal Get the Registry singleton. */
|
|
90
|
+
get registry() {
|
|
91
|
+
return SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance();
|
|
92
|
+
}
|
|
93
|
+
// --- 构建期上下文(SceneBuilder)生命周期 ---
|
|
94
|
+
/** @internal 惰性创建/复用构建期上下文(幂等:同一构建流程内共享工作态)。 */
|
|
95
|
+
getOrCreateSceneBuilder(sceneConfig) {
|
|
96
|
+
if (!this.activeBuilder) {
|
|
97
|
+
const config = sceneConfig !== null && sceneConfig !== void 0 ? sceneConfig : this.sceneConfig;
|
|
98
|
+
if (!config) {
|
|
99
|
+
throw new Error('SceneBuilder requires a SceneConfig (call buildBasicInfo first).');
|
|
100
|
+
}
|
|
101
|
+
this.activeBuilder = new SceneBuilder_1.SceneBuilder(this, config);
|
|
102
|
+
}
|
|
103
|
+
return this.activeBuilder;
|
|
104
|
+
}
|
|
105
|
+
/** @internal 释放构建期上下文:在构建机械全部完成后调用,工作态随上下文被 GC 回收。*/
|
|
106
|
+
releaseSceneBuilder() {
|
|
107
|
+
this.activeBuilder = undefined;
|
|
108
|
+
}
|
|
109
|
+
/** @internal 当前活跃构建上下文(无则 undefined)。ModuleScene 等构建通道使用。 */
|
|
110
|
+
getActiveSceneBuilder() {
|
|
111
|
+
return this.activeBuilder;
|
|
112
|
+
}
|
|
113
|
+
/** @internal 模块路径 → 模块名映射(构建产物;SceneBuilder.parseBuildProfile 写入)。 */
|
|
114
|
+
getModulePath2NameMap() {
|
|
115
|
+
return this.modulePath2NameMap;
|
|
116
|
+
}
|
|
95
117
|
constructor() {
|
|
96
118
|
this.projectName = '';
|
|
97
|
-
this.projectFiles = [];
|
|
98
119
|
this.realProjectDir = '';
|
|
99
120
|
this.includeDirs = []; // Include directories that the C++ project depends on.
|
|
100
121
|
this.ccjsonPath = '';
|
|
@@ -105,42 +126,78 @@ class Scene {
|
|
|
105
126
|
this.projectSdkMap = new Map();
|
|
106
127
|
// values that are visible in curr scope
|
|
107
128
|
this.visibleValue = new VisibleValue_1.VisibleValue();
|
|
108
|
-
// signature string to model
|
|
109
|
-
this.filesMap = new Map();
|
|
110
|
-
this.namespacesMap = new Map();
|
|
111
|
-
this.classesMap = new Map();
|
|
112
|
-
this.methodsMap = new Map();
|
|
113
|
-
/** Custom @Component name → ClassSignature; written at ArkClass build, kept after module unload for ViewTree stubs. */
|
|
114
|
-
this.customComponentMap = new Map();
|
|
115
|
-
// TODO: type of key should be signature object
|
|
116
|
-
this.sdkArkFilesMap = new Map();
|
|
117
|
-
this.sdkGlobalMap = new Map();
|
|
118
|
-
this.ohPkgContentMap = new Map();
|
|
119
|
-
this.ohPkgFilePath = '';
|
|
120
|
-
this.ohPkgContent = {};
|
|
121
129
|
this.overRides = new Map();
|
|
122
130
|
this.overRideDependencyMap = new Map();
|
|
123
|
-
this.buildStage = SceneBuildStage.BUILD_INIT;
|
|
131
|
+
this.buildStage = SceneBuildStage_2.SceneBuildStage.BUILD_INIT;
|
|
124
132
|
this.fileLanguages = new Map();
|
|
125
133
|
/** Maps ArkModule objects to dense integer ModuleIDs via the objectIdentity strategy. */
|
|
126
134
|
this.moduleCanonicalizer = new Canonicalizer_1.Canonicalizer();
|
|
127
135
|
/** Whether module preparation has completed (prepareModules + analyzeModuleDependencies, idempotent). */
|
|
128
136
|
this.modulesRegistered = false;
|
|
137
|
+
/** Prevents duplicate report output (set by manual API or exit hook). */
|
|
138
|
+
this.statsReportWritten = false;
|
|
129
139
|
this.unhandledFilePaths = new Set();
|
|
130
140
|
this.unhandledSdkFilePaths = [];
|
|
141
|
+
/**
|
|
142
|
+
* project 文件的构建完成序(setFile 时记录的 FileSigID 序列)。
|
|
143
|
+
*
|
|
144
|
+
* 构建走 {@link getDependencyFilesDeeply}(DFS):每个文件在自己的全部 import/export 依赖构建完成之后才 setFile(后序)——因此本序列是严格的拓扑序(被依赖者在前)。
|
|
145
|
+
* 这是推断期零排序遍历的事实源(见 {@link inferTypes})。注意 FileSigID 本身的前序 intern 序不具拓扑性质(多入口/菱形场景依赖方可能晚于被依赖方 intern),不可用于排序。
|
|
146
|
+
*/
|
|
147
|
+
this.builtFileOrder = [];
|
|
148
|
+
/** 根 oh-package.json5 内容快照(SceneBuilder.parseOhPackage 结束回填)。 */
|
|
149
|
+
this.ohPkgContentSnapshot = {};
|
|
150
|
+
SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.dispose();
|
|
131
151
|
}
|
|
132
152
|
/*
|
|
133
153
|
* Set all static field to be null, then all related objects could be freed by GC.
|
|
134
154
|
* This method could be called before drop Scene.
|
|
135
155
|
*/
|
|
136
156
|
dispose() {
|
|
157
|
+
var _a;
|
|
137
158
|
PointerAnalysisConfig_1.PointerAnalysisConfig.dispose();
|
|
138
159
|
SdkUtils_1.SdkUtils.dispose();
|
|
139
160
|
ValueUtil_1.ValueUtil.dispose();
|
|
140
161
|
ModelUtils_1.ModelUtils.dispose();
|
|
141
162
|
(0, builderUtils_1.clearCxxTypeStringCache)();
|
|
163
|
+
(0, ArkFileBuilder_1.disposeClassMap)();
|
|
142
164
|
this.moduleCache = undefined;
|
|
143
165
|
this.memoryMonitor = undefined;
|
|
166
|
+
this.releaseSceneBuilder();
|
|
167
|
+
this.builtFileOrder = [];
|
|
168
|
+
this.moduleScenesMap.clear();
|
|
169
|
+
this.modulePath2NameMap.clear();
|
|
170
|
+
this.moduleSdkMap.clear();
|
|
171
|
+
this.projectSdkMap.clear();
|
|
172
|
+
if (this.statsExitHandler) {
|
|
173
|
+
process.removeListener('exit', this.statsExitHandler);
|
|
174
|
+
this.statsExitHandler = undefined;
|
|
175
|
+
}
|
|
176
|
+
(_a = this.stageStatistics) === null || _a === void 0 ? void 0 : _a.finish();
|
|
177
|
+
this.stageStatistics = undefined;
|
|
178
|
+
SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.dispose();
|
|
179
|
+
// 组件名 stub 缓存随 Registry 同点清理(缓存实例的 temp symbol 属旧空间)。
|
|
180
|
+
ArkSignatureBuilder_1.ArkSignatureBuilder.clearComponentStubCache();
|
|
181
|
+
}
|
|
182
|
+
/** @internal Get the formal FileSignature canonicalizer. */
|
|
183
|
+
getFileSigCanonicalizer() {
|
|
184
|
+
return this.registry.fileSigCanonicalizer;
|
|
185
|
+
}
|
|
186
|
+
/** @internal Get the formal ClassSignature canonicalizer. */
|
|
187
|
+
getClassSigCanonicalizer() {
|
|
188
|
+
return this.registry.classSigCanonicalizer;
|
|
189
|
+
}
|
|
190
|
+
/** @internal Get the formal MethodSignature canonicalizer. */
|
|
191
|
+
getMethodSigCanonicalizer() {
|
|
192
|
+
return this.registry.methodSigCanonicalizer;
|
|
193
|
+
}
|
|
194
|
+
/** @internal Get the formal NamespaceSignature canonicalizer. */
|
|
195
|
+
getNamespaceSigCanonicalizer() {
|
|
196
|
+
return this.registry.namespaceSigCanonicalizer;
|
|
197
|
+
}
|
|
198
|
+
/** @internal Get the formal FieldSignature canonicalizer. */
|
|
199
|
+
getFieldSigCanonicalizer() {
|
|
200
|
+
return this.registry.fieldSigCanonicalizer;
|
|
144
201
|
}
|
|
145
202
|
getOptions() {
|
|
146
203
|
return this.options;
|
|
@@ -154,23 +211,9 @@ class Scene {
|
|
|
154
211
|
getOverRideDependencyMap() {
|
|
155
212
|
return this.overRideDependencyMap;
|
|
156
213
|
}
|
|
214
|
+
/** @deprecated Use {@link dispose} instead. */
|
|
157
215
|
clear() {
|
|
158
|
-
|
|
159
|
-
this.projectFiles = [];
|
|
160
|
-
this.moduleScenesMap.clear();
|
|
161
|
-
this.modulePath2NameMap.clear();
|
|
162
|
-
this.moduleSdkMap.clear();
|
|
163
|
-
this.projectSdkMap.clear();
|
|
164
|
-
this.filesMap.clear();
|
|
165
|
-
this.namespacesMap.clear();
|
|
166
|
-
this.classesMap.clear();
|
|
167
|
-
this.methodsMap.clear();
|
|
168
|
-
this.customComponentMap.clear();
|
|
169
|
-
this.sdkArkFilesMap.clear();
|
|
170
|
-
this.sdkGlobalMap.clear();
|
|
171
|
-
this.ohPkgContentMap.clear();
|
|
172
|
-
this.ohPkgContent = {};
|
|
173
|
-
(_a = this.moduleCache) === null || _a === void 0 ? void 0 : _a.clear();
|
|
216
|
+
this.dispose();
|
|
174
217
|
}
|
|
175
218
|
getStage() {
|
|
176
219
|
return this.buildStage;
|
|
@@ -204,12 +247,30 @@ class Scene {
|
|
|
204
247
|
```
|
|
205
248
|
*/
|
|
206
249
|
buildSceneFromProjectDir(sceneConfig) {
|
|
250
|
+
var _a, _b, _c, _d;
|
|
251
|
+
this.config(sceneConfig);
|
|
252
|
+
(_a = this.stageStatistics) === null || _a === void 0 ? void 0 : _a.start();
|
|
253
|
+
(_b = this.stageStatistics) === null || _b === void 0 ? void 0 : _b.startStage(StageStatistics_1.StageName.Builder);
|
|
207
254
|
this.buildBasicInfo(sceneConfig);
|
|
208
255
|
this.genArkFiles();
|
|
256
|
+
// 完整构建结束:释放构建期上下文(工作态随 GC 回收)。
|
|
257
|
+
this.releaseSceneBuilder();
|
|
258
|
+
(_c = this.stageStatistics) === null || _c === void 0 ? void 0 : _c.endStage(StageStatistics_1.StageName.Builder);
|
|
259
|
+
// 签名空间快照(时点 1):构建完成后的 formal/temp 数据进报告。
|
|
260
|
+
(_d = this.stageStatistics) === null || _d === void 0 ? void 0 : _d.recordSignatureStats('post-build');
|
|
209
261
|
}
|
|
210
262
|
buildSceneFromFiles(sceneConfig) {
|
|
263
|
+
var _a, _b, _c, _d;
|
|
264
|
+
this.config(sceneConfig);
|
|
265
|
+
(_a = this.stageStatistics) === null || _a === void 0 ? void 0 : _a.start();
|
|
266
|
+
(_b = this.stageStatistics) === null || _b === void 0 ? void 0 : _b.startStage(StageStatistics_1.StageName.Builder);
|
|
211
267
|
this.buildBasicInfo(sceneConfig);
|
|
212
|
-
this.
|
|
268
|
+
this.genArkFiles();
|
|
269
|
+
// 完整构建结束:释放构建期上下文(工作态随 GC 回收)。
|
|
270
|
+
this.releaseSceneBuilder();
|
|
271
|
+
(_c = this.stageStatistics) === null || _c === void 0 ? void 0 : _c.endStage(StageStatistics_1.StageName.Builder);
|
|
272
|
+
// 签名空间快照(时点 1):构建完成后的 formal/temp 数据进报告。
|
|
273
|
+
(_d = this.stageStatistics) === null || _d === void 0 ? void 0 : _d.recordSignatureStats('post-build');
|
|
213
274
|
}
|
|
214
275
|
/**
|
|
215
276
|
* Set the basic information of the scene using a config,
|
|
@@ -217,529 +278,21 @@ class Scene {
|
|
|
217
278
|
* @param sceneConfig - the config used to set the basic information of scene.
|
|
218
279
|
*/
|
|
219
280
|
buildBasicInfo(sceneConfig) {
|
|
220
|
-
var _a;
|
|
221
281
|
this.sceneConfig = sceneConfig;
|
|
222
282
|
this.options = sceneConfig.getOptions();
|
|
223
283
|
this.projectName = sceneConfig.getTargetProjectName();
|
|
224
284
|
this.realProjectDir = fs_1.default.realpathSync(sceneConfig.getTargetProjectDirectory());
|
|
225
|
-
this.projectFiles = sceneConfig.getProjectFiles();
|
|
226
285
|
this.includeDirs = sceneConfig.getIncludeDirs();
|
|
227
286
|
this.ccjsonPath = sceneConfig.getCcjsonPath();
|
|
228
287
|
this.cppAstPath = sceneConfig.getCppAstPath();
|
|
229
|
-
this.
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (this.options.tsconfig) {
|
|
233
|
-
tsConfigFilePath = path_1.default.join(sceneConfig.getTargetProjectDirectory(), this.options.tsconfig);
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
tsConfigFilePath = path_1.default.join(sceneConfig.getTargetProjectDirectory(), TSConst_1.TSCONFIG_JSON);
|
|
237
|
-
}
|
|
238
|
-
if (fs_1.default.existsSync(tsConfigFilePath)) {
|
|
239
|
-
const tsConfigObj = (0, json5parser_1.fetchDependenciesFromFile)(tsConfigFilePath);
|
|
240
|
-
this.findTsConfigInfoDeeply(tsConfigObj, tsConfigFilePath);
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
logger.warn('This project has no tsconfig.json!');
|
|
244
|
-
}
|
|
245
|
-
this.buildOhPkgContentMap();
|
|
246
|
-
ModuleUtils_1.ModuleUtils.generateModuleMap(this.ohPkgContentMap);
|
|
247
|
-
// handle sdks
|
|
248
|
-
if (this.options.enableBuiltIn && !sceneConfig.getSdksObj().find(sdk => sdk.name === SdkUtils_1.SdkUtils.BUILT_IN_NAME)) {
|
|
249
|
-
sceneConfig.getSdksObj().unshift(SdkUtils_1.SdkUtils.getBuiltInSdk());
|
|
250
|
-
}
|
|
251
|
-
(_a = sceneConfig.getSdksObj()) === null || _a === void 0 ? void 0 : _a.forEach(sdk => {
|
|
252
|
-
if (!sdk.moduleName) {
|
|
253
|
-
this.buildSdk(sdk.name, path_1.default.normalize(sdk.path));
|
|
254
|
-
this.projectSdkMap.set(sdk.name, sdk);
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
let moduleSdks = this.moduleSdkMap.get(sdk.moduleName);
|
|
258
|
-
if (moduleSdks) {
|
|
259
|
-
moduleSdks.push(sdk);
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
this.moduleSdkMap.set(sdk.moduleName, [sdk]);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
if (this.buildStage < SceneBuildStage.SDK_INFERRED) {
|
|
267
|
-
this.sdkArkFilesMap.forEach(file => {
|
|
268
|
-
// CXXTodo: C++ does not handle SDK files.
|
|
269
|
-
if (file.getLanguage() === ArkFile_1.Language.CXX) {
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
Inference_1.InferenceManager.getInstance().getInference(file.getLanguage()).doInfer(file);
|
|
273
|
-
SdkUtils_1.SdkUtils.mergeGlobalAPI(file, this.sdkGlobalMap);
|
|
274
|
-
});
|
|
275
|
-
this.sdkArkFilesMap.forEach(file => {
|
|
276
|
-
SdkUtils_1.SdkUtils.postInferredSdk(file, this.sdkGlobalMap);
|
|
277
|
-
});
|
|
278
|
-
this.buildStage = SceneBuildStage.SDK_INFERRED;
|
|
279
|
-
}
|
|
280
|
-
this.fileLanguages = sceneConfig.getFileLanguages();
|
|
281
|
-
SdkUtils_1.SdkUtils.extendArkUI(this);
|
|
282
|
-
}
|
|
283
|
-
parseBuildProfile() {
|
|
284
|
-
const buildProfile = path_1.default.join(this.realProjectDir, EtsConst_1.BUILD_PROFILE_JSON5);
|
|
285
|
-
if (fs_1.default.existsSync(buildProfile)) {
|
|
286
|
-
let configurationsText;
|
|
287
|
-
try {
|
|
288
|
-
configurationsText = fs_1.default.readFileSync(buildProfile, 'utf-8');
|
|
289
|
-
}
|
|
290
|
-
catch (error) {
|
|
291
|
-
logger.error(`Error reading file: ${error}`);
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
const buildProfileJson = (0, json5parser_1.parseJsonText)(configurationsText);
|
|
295
|
-
SdkUtils_1.SdkUtils.setEsVersion(buildProfileJson);
|
|
296
|
-
const modules = buildProfileJson.modules;
|
|
297
|
-
if (modules instanceof Array) {
|
|
298
|
-
modules.forEach(module => {
|
|
299
|
-
this.modulePath2NameMap.set(path_1.default.resolve(this.realProjectDir, path_1.default.join(module.srcPath)), module.name);
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
logger.warn('There is no build-profile.json5 for this project.');
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
parseOhPackage() {
|
|
308
|
-
const OhPkgFilePath = path_1.default.join(this.realProjectDir, EtsConst_1.OH_PACKAGE_JSON5);
|
|
309
|
-
if (fs_1.default.existsSync(OhPkgFilePath)) {
|
|
310
|
-
this.ohPkgFilePath = OhPkgFilePath;
|
|
311
|
-
this.ohPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(this.ohPkgFilePath);
|
|
312
|
-
this.ohPkgContentMap.set(OhPkgFilePath, this.ohPkgContent);
|
|
313
|
-
if (this.ohPkgContent.overrides) {
|
|
314
|
-
let overRides = this.ohPkgContent.overrides;
|
|
315
|
-
for (const [key, value] of Object.entries(overRides)) {
|
|
316
|
-
this.overRides.set(key, value);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
if (this.ohPkgContent.overrideDependencyMap) {
|
|
320
|
-
let globalOverRideDependencyMap = this.ohPkgContent.overrideDependencyMap;
|
|
321
|
-
for (const [key, value] of Object.entries(globalOverRideDependencyMap)) {
|
|
322
|
-
let globalDependency = (0, json5parser_1.fetchDependenciesFromFile)(value);
|
|
323
|
-
this.overRideDependencyMap.set(key, globalDependency);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
else {
|
|
328
|
-
logger.warn('This project has no oh-package.json5!');
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
findTsConfigInfoDeeply(tsConfigObj, tsConfigFilePath) {
|
|
332
|
-
if (tsConfigObj.extends) {
|
|
333
|
-
const extTsConfigFilePath = path_1.default.join(path_1.default.dirname(tsConfigFilePath), tsConfigObj.extends);
|
|
334
|
-
const extTsConfigObj = (0, json5parser_1.fetchDependenciesFromFile)(extTsConfigFilePath);
|
|
335
|
-
this.findTsConfigInfoDeeply(extTsConfigObj, extTsConfigFilePath);
|
|
336
|
-
if (!this.baseUrl && !this.globalModule2PathMapping) {
|
|
337
|
-
this.addTsConfigInfo(extTsConfigObj);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
if (!this.baseUrl && !this.globalModule2PathMapping) {
|
|
341
|
-
this.addTsConfigInfo(tsConfigObj);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
addTsConfigInfo(tsConfigObj) {
|
|
345
|
-
if (tsConfigObj.compilerOptions && tsConfigObj.compilerOptions.paths) {
|
|
346
|
-
const paths = tsConfigObj.compilerOptions.paths;
|
|
347
|
-
if (paths) {
|
|
348
|
-
this.globalModule2PathMapping = paths;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
if (tsConfigObj.compilerOptions && tsConfigObj.compilerOptions.baseUrl) {
|
|
352
|
-
this.baseUrl = tsConfigObj.compilerOptions.baseUrl;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Update or add default constructors for all classes in the scene.
|
|
357
|
-
*
|
|
358
|
-
* This function iterates through all files and classes in the scene,
|
|
359
|
-
* builds default constructors for each class, and processes existing constructors
|
|
360
|
-
* by replacing super constructor calls and adding initialization logic.
|
|
361
|
-
*
|
|
362
|
-
* @returns {void}
|
|
363
|
-
*/
|
|
364
|
-
updateOrAddDefaultConstructors() {
|
|
365
|
-
for (const file of this.getFiles()) {
|
|
366
|
-
// CXXTodo: Select the appropriate initialization function based on file type
|
|
367
|
-
const initInConstructorFn = file.getLanguage() === ArkFile_1.Language.CXX ? ArkMethodBuilder_2.addInitInConstructor : ArkMethodBuilder_1.addInitInConstructor;
|
|
368
|
-
for (const cls of ModelUtils_1.ModelUtils.getAllClassesInFile(file)) {
|
|
369
|
-
(0, ArkMethodBuilder_1.buildDefaultConstructor)(cls);
|
|
370
|
-
// CXXTodo: Use the interface 'getAllMethodsWithName' for obtaining all methods with the same name.
|
|
371
|
-
const constructors = cls.getAllMethodsWithName(TSConst_1.CONSTRUCTOR_NAME);
|
|
372
|
-
if (cls.isDefaultArkClass()) {
|
|
373
|
-
continue;
|
|
374
|
-
}
|
|
375
|
-
constructors.forEach(constructor => {
|
|
376
|
-
(0, ArkMethodBuilder_1.replaceSuper2Constructor)(constructor);
|
|
377
|
-
initInConstructorFn(constructor);
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
collectAllMethods() {
|
|
383
|
-
const methods = [];
|
|
384
|
-
for (const file of this.getFiles()) {
|
|
385
|
-
if (!this.options.enableOhModulesBody && file.getName().includes(EtsConst_1.OH_MODULES)) {
|
|
386
|
-
const defaultArkMethod = file.getDefaultClass().getDefaultArkMethod();
|
|
387
|
-
if (defaultArkMethod) {
|
|
388
|
-
methods.push(defaultArkMethod);
|
|
389
|
-
}
|
|
390
|
-
continue;
|
|
391
|
-
}
|
|
392
|
-
for (const cls of file.getClasses()) {
|
|
393
|
-
for (const method of cls.getMethods(true)) {
|
|
394
|
-
methods.push(method);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
for (const namespace of this.getNamespacesMap().values()) {
|
|
399
|
-
if (!this.options.enableOhModulesBody && namespace.getDeclaringArkFile().getName().includes(EtsConst_1.OH_MODULES)) {
|
|
400
|
-
const defaultArkMethod = namespace.getDefaultClass().getDefaultArkMethod();
|
|
401
|
-
if (defaultArkMethod) {
|
|
402
|
-
methods.push(defaultArkMethod);
|
|
403
|
-
}
|
|
404
|
-
continue;
|
|
405
|
-
}
|
|
406
|
-
for (const cls of namespace.getClasses()) {
|
|
407
|
-
for (const method of cls.getMethods(true)) {
|
|
408
|
-
methods.push(method);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
return methods;
|
|
413
|
-
}
|
|
414
|
-
static freeMethodBodyBuilder(method) {
|
|
415
|
-
var _a;
|
|
416
|
-
const isCxxFile = ((_a = method.getDeclaringArkFile()) === null || _a === void 0 ? void 0 : _a.getLanguage()) === ArkFile_1.Language.CXX;
|
|
417
|
-
if (isCxxFile) {
|
|
418
|
-
method.freeCxxBodyBuilder();
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
method.freeBodyBuilder();
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
buildAllMethodBody() {
|
|
425
|
-
this.buildStage = SceneBuildStage.CLASS_DONE;
|
|
426
|
-
const methods = this.collectAllMethods();
|
|
427
|
-
for (const method of methods) {
|
|
428
|
-
try {
|
|
429
|
-
method.buildBody();
|
|
430
|
-
}
|
|
431
|
-
catch (error) {
|
|
432
|
-
logger.error('Error building body:', method.getSignature(), error);
|
|
433
|
-
}
|
|
434
|
-
finally {
|
|
435
|
-
Scene.freeMethodBodyBuilder(method);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
ModelUtils_1.ModelUtils.dispose();
|
|
439
|
-
this.buildStage = SceneBuildStage.METHOD_DONE;
|
|
440
|
-
}
|
|
441
|
-
freeAllBodyBuilders() {
|
|
442
|
-
const methods = this.collectAllMethods();
|
|
443
|
-
for (const method of methods) {
|
|
444
|
-
Scene.freeMethodBodyBuilder(method);
|
|
445
|
-
}
|
|
288
|
+
const builder = this.getOrCreateSceneBuilder(sceneConfig);
|
|
289
|
+
builder.parseProjectConfigs();
|
|
290
|
+
builder.buildSdkStage();
|
|
446
291
|
}
|
|
447
292
|
genArkFiles() {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
this.buildAllMethodBody();
|
|
452
|
-
this.updateOrAddDefaultConstructors();
|
|
453
|
-
}
|
|
454
|
-
else {
|
|
455
|
-
this.freeAllBodyBuilders();
|
|
456
|
-
ModelUtils_1.ModelUtils.dispose();
|
|
457
|
-
this.buildStage = SceneBuildStage.METHOD_DONE;
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
getFilesOrderByDependency() {
|
|
461
|
-
var _a;
|
|
462
|
-
for (const projectFile of this.projectFiles) {
|
|
463
|
-
this.getDependencyFilesDeeply(projectFile);
|
|
464
|
-
}
|
|
465
|
-
if ((_a = this.options.enableMethodBodyBuild) !== null && _a !== void 0 ? _a : true) {
|
|
466
|
-
this.buildAllMethodBody();
|
|
467
|
-
this.updateOrAddDefaultConstructors();
|
|
468
|
-
}
|
|
469
|
-
else {
|
|
470
|
-
this.freeAllBodyBuilders();
|
|
471
|
-
ModelUtils_1.ModelUtils.dispose();
|
|
472
|
-
this.buildStage = SceneBuildStage.METHOD_DONE;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
getDependencyFilesDeeply(projectFile) {
|
|
476
|
-
if (!this.options.supportFileExts.includes(path_1.default.extname(projectFile))) {
|
|
477
|
-
return;
|
|
478
|
-
}
|
|
479
|
-
const fileSignature = new ArkSignature_1.FileSignature(this.getProjectName(), path_1.default.relative(this.getRealProjectDir(), projectFile));
|
|
480
|
-
if (this.filesMap.has(fileSignature.toMapKey()) || this.isRepeatBuildFile(projectFile) || this.unhandledFilePaths.has(projectFile)) {
|
|
481
|
-
return;
|
|
482
|
-
}
|
|
483
|
-
// Here use unhandledFilePaths to temporarily store current file until add it to fileMaps to avoid recursively import issue.
|
|
484
|
-
this.unhandledFilePaths.add(projectFile);
|
|
485
|
-
try {
|
|
486
|
-
const arkFile = new ArkFile_1.ArkFile(FileUtils_1.FileUtils.getFileLanguage(projectFile, this.fileLanguages));
|
|
487
|
-
arkFile.setScene(this);
|
|
488
|
-
FrontendBuilder_1.FrontendBuilder.buildProjectFileIntoArkFile(this, projectFile, arkFile);
|
|
489
|
-
for (const [modulePath, moduleName] of this.modulePath2NameMap) {
|
|
490
|
-
if (arkFile.getFilePath().startsWith(modulePath)) {
|
|
491
|
-
this.addArkFile2ModuleScene(modulePath, moduleName, arkFile);
|
|
492
|
-
break;
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
const importInfos = arkFile.getImportInfos();
|
|
496
|
-
const repeatFroms = [];
|
|
497
|
-
this.findDependencyFiles(importInfos, arkFile, repeatFroms);
|
|
498
|
-
const exportInfos = arkFile.getExportInfos();
|
|
499
|
-
this.findDependencyFiles(exportInfos, arkFile, repeatFroms);
|
|
500
|
-
// add currently file to files map after adding all its dependencies, and remove it from unhandledFilePaths
|
|
501
|
-
this.setFile(arkFile);
|
|
502
|
-
this.unhandledFilePaths.delete(projectFile);
|
|
503
|
-
}
|
|
504
|
-
catch (error) {
|
|
505
|
-
logger.error('Error parsing file:', projectFile, error);
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
isRepeatBuildFile(projectFile) {
|
|
510
|
-
const relativePath = path_1.default.relative(this.getRealProjectDir(), projectFile);
|
|
511
|
-
if (!relativePath.startsWith('..') && !path_1.default.isAbsolute(relativePath)) {
|
|
512
|
-
const mapKey = (0, FileUtils_1.getFileSignatureMapKey)(this.getProjectName(), relativePath);
|
|
513
|
-
return this.filesMap.has(mapKey);
|
|
514
|
-
}
|
|
515
|
-
return false;
|
|
516
|
-
}
|
|
517
|
-
addArkFile2ModuleScene(modulePath, moduleName, arkFile) {
|
|
518
|
-
if (this.moduleScenesMap.has(moduleName)) {
|
|
519
|
-
let curModuleScene = this.moduleScenesMap.get(moduleName);
|
|
520
|
-
if (curModuleScene) {
|
|
521
|
-
curModuleScene.addArkFile(arkFile);
|
|
522
|
-
arkFile.setModuleScene(curModuleScene);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
else {
|
|
526
|
-
let moduleScene = new ModuleScene(this);
|
|
527
|
-
moduleScene.ModuleScenePartiallyBuilder(moduleName, modulePath);
|
|
528
|
-
moduleScene.addArkFile(arkFile);
|
|
529
|
-
this.moduleScenesMap.set(moduleName, moduleScene);
|
|
530
|
-
arkFile.setModuleScene(moduleScene);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
findDependencyFiles(importOrExportInfos, arkFile, repeatFroms) {
|
|
534
|
-
for (const importOrExportInfo of importOrExportInfos) {
|
|
535
|
-
const from = importOrExportInfo.getFrom();
|
|
536
|
-
if (from && !repeatFroms.includes(from)) {
|
|
537
|
-
this.parseFrom(from, arkFile);
|
|
538
|
-
repeatFroms.push(from);
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
parseFrom(from, arkFile) {
|
|
543
|
-
if (/^@[a-z|\-]+?\/?/.test(from) || /^[a-z][a-z0-9._-]*[a-z0-9]$/.test(from)) {
|
|
544
|
-
// TODO: if there are more than one modules with the same name e.g. @lib1, here may got the wrong dependency
|
|
545
|
-
// It is better to loop all oh pkg with priority rather than the map key order. But it should be very complicated.
|
|
546
|
-
// Currently it is ok because it's with low probability and order error only affects type accuracy but has no other impact.
|
|
547
|
-
for (const [ohPkgContentPath, ohPkgContent] of this.ohPkgContentMap) {
|
|
548
|
-
this.findDependenciesByOhPkg(ohPkgContentPath, ohPkgContent, from);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
else if (/^([^@]*\/)([^\/]*)$/.test(from) || /^[\.\./|\.\.]+$/.test(from)) {
|
|
552
|
-
this.findRelativeDependenciesByOhPkg(from, arkFile);
|
|
553
|
-
}
|
|
554
|
-
else if (/^[@a-zA-Z0-9]+(\/[a-zA-Z0-9]+)*$/.test(from)) {
|
|
555
|
-
this.findDependenciesByTsConfig(from);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
findDependenciesByTsConfig(from) {
|
|
559
|
-
if (this.globalModule2PathMapping) {
|
|
560
|
-
const paths = this.globalModule2PathMapping;
|
|
561
|
-
Object.keys(paths).forEach(key => this.parseTsConfigParms(paths, key, from));
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
parseTsConfigParms(paths, key, from) {
|
|
565
|
-
const module2pathMapping = paths[key];
|
|
566
|
-
if (key.includes(TSConst_1.ALL)) {
|
|
567
|
-
this.processFuzzyMapping(key, from, module2pathMapping);
|
|
568
|
-
}
|
|
569
|
-
else if (from.startsWith(key)) {
|
|
570
|
-
let tail = from.substring(key.length, from.length);
|
|
571
|
-
module2pathMapping.forEach(pathMapping => {
|
|
572
|
-
let originPath = path_1.default.join(this.getRealProjectDir(), pathMapping, tail);
|
|
573
|
-
if (this.baseUrl) {
|
|
574
|
-
originPath = path_1.default.resolve(this.baseUrl, originPath);
|
|
575
|
-
}
|
|
576
|
-
this.findDependenciesByRule(originPath);
|
|
577
|
-
});
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
processFuzzyMapping(key, from, module2pathMapping) {
|
|
581
|
-
key = key.substring(0, key.indexOf(TSConst_1.ALL) - 1);
|
|
582
|
-
if (from.substring(0, key.indexOf(TSConst_1.ALL) - 1) === key) {
|
|
583
|
-
let tail = from.substring(key.indexOf(TSConst_1.ALL) - 1, from.length);
|
|
584
|
-
module2pathMapping.forEach(pathMapping => {
|
|
585
|
-
pathMapping = pathMapping.substring(0, pathMapping.indexOf(TSConst_1.ALL) - 1);
|
|
586
|
-
let originPath = path_1.default.join(this.getRealProjectDir(), pathMapping, tail);
|
|
587
|
-
if (this.baseUrl) {
|
|
588
|
-
originPath = path_1.default.join(this.baseUrl, originPath);
|
|
589
|
-
}
|
|
590
|
-
this.findDependenciesByRule(originPath);
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
findDependenciesByRule(originPath) {
|
|
595
|
-
if (!this.findFilesByPathArray(originPath) && !this.findFilesByExtNameArray(originPath, this.options.supportFileExts)) {
|
|
596
|
-
logger.trace(originPath + 'module mapperInfo is not found!');
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
findFilesByPathArray(originPath) {
|
|
600
|
-
if (!fs_1.default.existsSync(originPath)) {
|
|
601
|
-
return false;
|
|
602
|
-
}
|
|
603
|
-
const dirname = path_1.default.dirname(originPath);
|
|
604
|
-
const indexFileName = FileUtils_1.FileUtils.getIndexFileName(dirname);
|
|
605
|
-
if (indexFileName === '') {
|
|
606
|
-
return false;
|
|
607
|
-
}
|
|
608
|
-
const curPath = path_1.default.join(dirname, indexFileName);
|
|
609
|
-
if (!this.isRepeatBuildFile(curPath)) {
|
|
610
|
-
this.addFileNode2DependencyGrap(curPath);
|
|
611
|
-
return true;
|
|
612
|
-
}
|
|
613
|
-
return false;
|
|
614
|
-
}
|
|
615
|
-
findFilesByExtNameArray(originPath, pathArray) {
|
|
616
|
-
for (const pathInfo of pathArray) {
|
|
617
|
-
const curPath = originPath + pathInfo;
|
|
618
|
-
if (fs_1.default.existsSync(curPath) && !this.isRepeatBuildFile(curPath)) {
|
|
619
|
-
this.addFileNode2DependencyGrap(curPath);
|
|
620
|
-
return true;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
return false;
|
|
624
|
-
}
|
|
625
|
-
findRelativeDependenciesByOhPkg(from, arkFile) {
|
|
626
|
-
//relative path ../from ./from
|
|
627
|
-
//order
|
|
628
|
-
//1. ../from/oh-package.json5 -> [[name]] -> overRides/overRideDependencyMap? ->
|
|
629
|
-
//[[main]] -> file path ->dependencies(priority)+devDependencies? dynamicDependencies(not support) ->
|
|
630
|
-
//key overRides/overRideDependencyMap?
|
|
631
|
-
//2. ../from/index.ets(ts)
|
|
632
|
-
//3. ../from/index.d.ets(ts)
|
|
633
|
-
//4. ../from.ets(ts)
|
|
634
|
-
//5. ../from.d.ets(ts)
|
|
635
|
-
//2.3.4.5 random order
|
|
636
|
-
let originPath = this.getOriginPath(from, arkFile);
|
|
637
|
-
if (fs_1.default.existsSync(path_1.default.join(originPath, EtsConst_1.OH_PACKAGE_JSON5))) {
|
|
638
|
-
for (const [ohPkgContentPath, ohPkgContent] of this.ohPkgContentMap) {
|
|
639
|
-
this.findDependenciesByOhPkg(ohPkgContentPath, ohPkgContent, from);
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
this.findDependenciesByRule(originPath);
|
|
643
|
-
}
|
|
644
|
-
findDependenciesByOhPkg(ohPkgContentPath, ohPkgContentInfo, from) {
|
|
645
|
-
//module name @ohos/from
|
|
646
|
-
const ohPkgContent = ohPkgContentInfo;
|
|
647
|
-
//module main name is must be
|
|
648
|
-
if (ohPkgContent && ohPkgContent.name && from.startsWith(ohPkgContent.name.toString())) {
|
|
649
|
-
let originPath = ohPkgContentPath.toString().replace(EtsConst_1.OH_PACKAGE_JSON5, '');
|
|
650
|
-
if (ohPkgContent.main) {
|
|
651
|
-
originPath = path_1.default.join(ohPkgContentPath.toString().replace(EtsConst_1.OH_PACKAGE_JSON5, ''), ohPkgContent.main.toString());
|
|
652
|
-
if (ohPkgContent.dependencies) {
|
|
653
|
-
this.getDependenciesMapping(ohPkgContent.dependencies, ohPkgContentPath, from);
|
|
654
|
-
}
|
|
655
|
-
else if (ohPkgContent.devDependencies) {
|
|
656
|
-
this.getDependenciesMapping(ohPkgContent.devDependencies, ohPkgContentPath, from);
|
|
657
|
-
}
|
|
658
|
-
else if (ohPkgContent.dynamicDependencies) {
|
|
659
|
-
// dynamicDependencies not support
|
|
660
|
-
}
|
|
661
|
-
this.addFileNode2DependencyGrap(originPath);
|
|
662
|
-
}
|
|
663
|
-
if (!this.findFilesByPathArray(originPath)) {
|
|
664
|
-
logger.trace(originPath + 'module mapperInfo is not found!');
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
getDependenciesMapping(dependencies, ohPkgContentPath, from) {
|
|
669
|
-
for (let [moduleName, modulePath] of Object.entries(dependencies)) {
|
|
670
|
-
logger.debug('dependencies:' + moduleName);
|
|
671
|
-
if (modulePath.startsWith('file:')) {
|
|
672
|
-
modulePath = modulePath.replace(/^file:/, '');
|
|
673
|
-
}
|
|
674
|
-
const innerOhpackagePath = path_1.default.join(ohPkgContentPath.replace(EtsConst_1.OH_PACKAGE_JSON5, ''), modulePath.toString(), EtsConst_1.OH_PACKAGE_JSON5);
|
|
675
|
-
if (!this.ohPkgContentMap.has(innerOhpackagePath)) {
|
|
676
|
-
const innerModuleOhPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(innerOhpackagePath);
|
|
677
|
-
this.findDependenciesByOhPkg(innerOhpackagePath, innerModuleOhPkgContent, from);
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
getOriginPath(from, arkFile) {
|
|
682
|
-
const parentPath = /^\.{1,2}\//.test(from) ? path_1.default.dirname(arkFile.getFilePath()) : arkFile.getProjectDir();
|
|
683
|
-
return path_1.default.resolve(parentPath, from);
|
|
684
|
-
}
|
|
685
|
-
addFileNode2DependencyGrap(filePath) {
|
|
686
|
-
this.getDependencyFilesDeeply(filePath);
|
|
687
|
-
}
|
|
688
|
-
/**
|
|
689
|
-
* Loads SDK sources into the scene. C++ SDK files are intentionally skipped: they are not parsed or registered
|
|
690
|
-
* here (only non-C++ SDK sources are processed).
|
|
691
|
-
*/
|
|
692
|
-
buildSdk(sdkName, sdkPath) {
|
|
693
|
-
const allFiles = this.collectSdkFiles(sdkName, sdkPath);
|
|
694
|
-
allFiles.forEach(file => {
|
|
695
|
-
if (FileUtils_1.FileUtils.getFileLanguage(file, this.fileLanguages) === ArkFile_1.Language.CXX) {
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
this.parseAndRegisterSdkFile(file, sdkPath, sdkName);
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
|
-
collectSdkFiles(sdkName, sdkPath) {
|
|
702
|
-
var _a;
|
|
703
|
-
if (sdkName === SdkUtils_1.SdkUtils.BUILT_IN_NAME) {
|
|
704
|
-
const builtInFiles = SdkUtils_1.SdkUtils.fetchBuiltInFiles(sdkPath);
|
|
705
|
-
if (builtInFiles.length > 0) {
|
|
706
|
-
(_a = this.getOptions().sdkGlobalFolders) === null || _a === void 0 ? void 0 : _a.push(sdkPath);
|
|
707
|
-
}
|
|
708
|
-
return builtInFiles;
|
|
709
|
-
}
|
|
710
|
-
SdkUtils_1.SdkUtils.loadSystemComponentsFromSdk(sdkPath);
|
|
711
|
-
return (0, getAllFiles_1.getAllFiles)(sdkPath, this.options.supportFileExts, this.options.ignoreFileNames);
|
|
712
|
-
}
|
|
713
|
-
parseAndRegisterSdkFile(file, sdkPath, sdkName) {
|
|
714
|
-
logger.trace('=== parse sdk file:', file);
|
|
715
|
-
try {
|
|
716
|
-
const arkFile = new ArkFile_1.ArkFile(FileUtils_1.FileUtils.getFileLanguage(file, this.fileLanguages));
|
|
717
|
-
arkFile.setScene(this);
|
|
718
|
-
ArktsFrontend_1.ArktsFrontend.buildArkFileFromSdkPath(file, sdkPath, arkFile, sdkName);
|
|
719
|
-
ModelUtils_1.ModelUtils.getAllClassesInFile(arkFile).forEach(cls => {
|
|
720
|
-
var _a, _b;
|
|
721
|
-
(_a = cls.getDefaultArkMethod()) === null || _a === void 0 ? void 0 : _a.buildBody();
|
|
722
|
-
(_b = cls.getDefaultArkMethod()) === null || _b === void 0 ? void 0 : _b.freeBodyBuilder();
|
|
723
|
-
});
|
|
724
|
-
// Release all method builders in SDK file to avoid retaining AST/build context in memory.
|
|
725
|
-
ModelUtils_1.ModelUtils.getAllMethodsInFile(arkFile).forEach(method => {
|
|
726
|
-
var _a;
|
|
727
|
-
if (((_a = method.getDeclaringArkFile()) === null || _a === void 0 ? void 0 : _a.getLanguage()) === ArkFile_1.Language.CXX) {
|
|
728
|
-
method.freeCxxBodyBuilder();
|
|
729
|
-
}
|
|
730
|
-
else {
|
|
731
|
-
method.freeBodyBuilder();
|
|
732
|
-
}
|
|
733
|
-
});
|
|
734
|
-
const fileSig = arkFile.getFileSignature().toMapKey();
|
|
735
|
-
this.sdkArkFilesMap.set(fileSig, arkFile);
|
|
736
|
-
SdkUtils_1.SdkUtils.buildSdkImportMap(arkFile);
|
|
737
|
-
SdkUtils_1.SdkUtils.loadGlobalAPI(arkFile, this.sdkGlobalMap);
|
|
738
|
-
}
|
|
739
|
-
catch (error) {
|
|
740
|
-
logger.error('Error parsing file:', file, error);
|
|
741
|
-
this.unhandledSdkFilePaths.push(file);
|
|
742
|
-
}
|
|
293
|
+
const builder = this.getOrCreateSceneBuilder();
|
|
294
|
+
builder.buildProjectFiles();
|
|
295
|
+
builder.buildAllMethodBodies();
|
|
743
296
|
}
|
|
744
297
|
/**
|
|
745
298
|
* Build the scene for harmony project. It resolves the file path of the project first, and then fetches
|
|
@@ -747,83 +300,14 @@ class Scene {
|
|
|
747
300
|
* it build bodies of all methods, generate extended classes, and add DefaultConstructors.
|
|
748
301
|
*/
|
|
749
302
|
buildScene4HarmonyProject() {
|
|
750
|
-
|
|
751
|
-
this.
|
|
752
|
-
let moduleScene = new ModuleScene(this);
|
|
753
|
-
moduleScene.ModuleSceneBuilder(value, key, this.options.supportFileExts);
|
|
754
|
-
this.moduleScenesMap.set(value, moduleScene);
|
|
755
|
-
});
|
|
756
|
-
if ((_a = this.options.enableMethodBodyBuild) !== null && _a !== void 0 ? _a : true) {
|
|
757
|
-
this.buildAllMethodBody();
|
|
758
|
-
this.updateOrAddDefaultConstructors();
|
|
759
|
-
}
|
|
760
|
-
else {
|
|
761
|
-
this.freeAllBodyBuilders();
|
|
762
|
-
ModelUtils_1.ModelUtils.dispose();
|
|
763
|
-
this.buildStage = SceneBuildStage.METHOD_DONE;
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
buildOhPkgContentMap() {
|
|
767
|
-
this.modulePath2NameMap.forEach((value, key) => {
|
|
768
|
-
const moduleOhPkgFilePath = path_1.default.resolve(key, EtsConst_1.OH_PACKAGE_JSON5);
|
|
769
|
-
if (fs_1.default.existsSync(moduleOhPkgFilePath)) {
|
|
770
|
-
const moduleOhPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(moduleOhPkgFilePath);
|
|
771
|
-
this.ohPkgContentMap.set(moduleOhPkgFilePath, moduleOhPkgContent);
|
|
772
|
-
}
|
|
773
|
-
});
|
|
303
|
+
this.getOrCreateSceneBuilder().buildScene4HarmonyProject();
|
|
304
|
+
this.releaseSceneBuilder();
|
|
774
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* 单模块构建(增量式入口,可连续调用构建多个模块):ohpkg 依赖递归 + 模块 DFS + body 构建,全部经构建期上下文。此处不释放上下文(连续构建共享工作态)。
|
|
308
|
+
*/
|
|
775
309
|
buildModuleScene(moduleName, modulePath, supportFileExts) {
|
|
776
|
-
|
|
777
|
-
if (this.moduleScenesMap.get(moduleName)) {
|
|
778
|
-
return;
|
|
779
|
-
}
|
|
780
|
-
// get oh-package.json5
|
|
781
|
-
const moduleOhPkgFilePath = path_1.default.resolve(this.realProjectDir, path_1.default.join(modulePath, EtsConst_1.OH_PACKAGE_JSON5));
|
|
782
|
-
if (fs_1.default.existsSync(moduleOhPkgFilePath)) {
|
|
783
|
-
const moduleOhPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(moduleOhPkgFilePath);
|
|
784
|
-
this.ohPkgContentMap.set(moduleOhPkgFilePath, moduleOhPkgContent);
|
|
785
|
-
}
|
|
786
|
-
else {
|
|
787
|
-
logger.warn('Module: ', moduleName, 'has no oh-package.json5.');
|
|
788
|
-
}
|
|
789
|
-
// parse moduleOhPkgContent, get dependencies and build dependent module
|
|
790
|
-
const moduleOhPkgContent = this.ohPkgContentMap.get(moduleOhPkgFilePath);
|
|
791
|
-
if (moduleOhPkgContent) {
|
|
792
|
-
if (moduleOhPkgContent.dependencies instanceof Object) {
|
|
793
|
-
this.processModuleOhPkgContent(moduleOhPkgContent.dependencies, moduleOhPkgFilePath, supportFileExts);
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
let moduleScene = new ModuleScene(this);
|
|
797
|
-
moduleScene.ModuleSceneBuilder(moduleName, modulePath, supportFileExts);
|
|
798
|
-
this.moduleScenesMap.set(moduleName, moduleScene);
|
|
799
|
-
if ((_a = this.options.enableMethodBodyBuild) !== null && _a !== void 0 ? _a : true) {
|
|
800
|
-
this.buildAllMethodBody();
|
|
801
|
-
}
|
|
802
|
-
else {
|
|
803
|
-
this.freeAllBodyBuilders();
|
|
804
|
-
ModelUtils_1.ModelUtils.dispose();
|
|
805
|
-
this.buildStage = SceneBuildStage.METHOD_DONE;
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
processModuleOhPkgContent(dependencies, moduleOhPkgFilePath, supportFileExts) {
|
|
809
|
-
Object.entries(dependencies).forEach(([k, v]) => {
|
|
810
|
-
const pattern = new RegExp('^(\\.\\.\\/\|\\.\\/)');
|
|
811
|
-
if (typeof v === 'string') {
|
|
812
|
-
let dependencyModulePath = '';
|
|
813
|
-
if (pattern.test(v)) {
|
|
814
|
-
dependencyModulePath = path_1.default.join(moduleOhPkgFilePath, v);
|
|
815
|
-
}
|
|
816
|
-
else if (v.startsWith('file:')) {
|
|
817
|
-
const dependencyFilePath = path_1.default.join(moduleOhPkgFilePath, v.replace(/^file:/, ''));
|
|
818
|
-
const dependencyOhPkgPath = (0, FileUtils_1.getFileRecursively)(path_1.default.dirname(dependencyFilePath), EtsConst_1.OH_PACKAGE_JSON5);
|
|
819
|
-
dependencyModulePath = path_1.default.dirname(dependencyOhPkgPath);
|
|
820
|
-
}
|
|
821
|
-
const dependencyModuleName = this.modulePath2NameMap.get(dependencyModulePath);
|
|
822
|
-
if (dependencyModuleName) {
|
|
823
|
-
this.buildModuleScene(dependencyModuleName, dependencyModulePath, supportFileExts);
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
});
|
|
310
|
+
this.getOrCreateSceneBuilder().buildModuleScene(moduleName, modulePath, supportFileExts);
|
|
827
311
|
}
|
|
828
312
|
/**
|
|
829
313
|
* Get the absolute path of current project.
|
|
@@ -859,6 +343,14 @@ class Scene {
|
|
|
859
343
|
this.realProjectDir = fs_1.default.realpathSync(dir);
|
|
860
344
|
}
|
|
861
345
|
this.fileLanguages = sceneConfig.getFileLanguages();
|
|
346
|
+
if (this.options.enableStatistics && !this.stageStatistics) {
|
|
347
|
+
this.stageStatistics = new StageStatistics_1.StageStatistics(true);
|
|
348
|
+
this.registerStatsExitHook();
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/** @internal 供构建期上下文(SceneBuilder)打点使用:返回统计收集器,未启用统计时为 undefined(各打点调用自动 no-op)。 */
|
|
352
|
+
getStageStatisticsCollector() {
|
|
353
|
+
return this.stageStatistics;
|
|
862
354
|
}
|
|
863
355
|
/**
|
|
864
356
|
* Returns all registered {@link ArkModule} objects.
|
|
@@ -922,9 +414,9 @@ class Scene {
|
|
|
922
414
|
* Perform module-level analysis by iterating modules in topological order and invoking
|
|
923
415
|
* the callback for each module.
|
|
924
416
|
*
|
|
925
|
-
* Flow: prepareModules → analyzeModuleDependencies → buildSdkModules (SDK
|
|
926
|
-
* inferred first) → resolveTargetModuleIds → computeModuleClosureByIds →
|
|
927
|
-
* → loadModule → callback.
|
|
417
|
+
* Flow: prepareModules → analyzeModuleDependencies → buildSdkModules (SDK loaded
|
|
418
|
+
* inferred first) → resolveTargetModuleIds → computeModuleClosureByIds →
|
|
419
|
+
* getFilteredTopoOrder → loadModule → callback.
|
|
928
420
|
* Each step is idempotent; repeated calls do not repeat preprocessing.
|
|
929
421
|
*
|
|
930
422
|
* - SDK modules are registered and built in one fused step by {@link ModuleBuilder.buildSdkModules}
|
|
@@ -947,7 +439,7 @@ class Scene {
|
|
|
947
439
|
builder.analyzeModuleDependencies();
|
|
948
440
|
this.setModulesRegistered(true);
|
|
949
441
|
}
|
|
950
|
-
// 2. Build SDK modules
|
|
442
|
+
// 2. Build SDK modules → fused registration + building (idempotent). SDK loaded FIRST so
|
|
951
443
|
// that global APIs are available when project/oh_modules modules are loaded.
|
|
952
444
|
builder.buildSdkModules();
|
|
953
445
|
// 3. Resolve target modules and compute closure (unified flow, no branching)
|
|
@@ -983,7 +475,7 @@ class Scene {
|
|
|
983
475
|
}
|
|
984
476
|
callback(module, this);
|
|
985
477
|
}
|
|
986
|
-
// 7. No unload, no dispose
|
|
478
|
+
// 7. No unload, no dispose → modules persist in cache for cross-call reuse
|
|
987
479
|
}
|
|
988
480
|
/**
|
|
989
481
|
* Returns the **string** name of the project.
|
|
@@ -992,41 +484,20 @@ class Scene {
|
|
|
992
484
|
getProjectName() {
|
|
993
485
|
return this.projectName;
|
|
994
486
|
}
|
|
995
|
-
|
|
996
|
-
return this.projectFiles;
|
|
997
|
-
}
|
|
487
|
+
/** @deprecated Compatibility delegate only — no longer used internally. Use {@link SdkUtils.getSdkGlobal} instead. */
|
|
998
488
|
getSdkGlobal(globalName) {
|
|
999
|
-
return
|
|
489
|
+
return SdkUtils_1.SdkUtils.getSdkGlobal(globalName);
|
|
1000
490
|
}
|
|
491
|
+
/** @deprecated Compatibility delegate only — no longer used internally. Use `SignatureCanonicalizerRegistry.getInstance().sdkGlobalMap` instead. */
|
|
1001
492
|
getSdkGlobalMap() {
|
|
1002
|
-
return
|
|
493
|
+
return SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance().sdkGlobalMap;
|
|
1003
494
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
* project's dir, file's signature etc.
|
|
1009
|
-
* @param fileSignature - the signature of file.
|
|
1010
|
-
* @returns a file defined by ArkAnalyzer. **null** will be returned if no file could be found.
|
|
1011
|
-
* @example
|
|
1012
|
-
* 1. get ArkFile based on file signature.
|
|
1013
|
-
|
|
1014
|
-
```typescript
|
|
1015
|
-
if (...) {
|
|
1016
|
-
const fromSignature = new FileSignature();
|
|
1017
|
-
fromSignature.setProjectName(im.getDeclaringArkFile().getProjectName());
|
|
1018
|
-
fromSignature.setFileName(fileName);
|
|
1019
|
-
return scene.getFile(fromSignature);
|
|
1020
|
-
}
|
|
1021
|
-
```
|
|
1022
|
-
*/
|
|
1023
|
-
getFile(fileSignature) {
|
|
1024
|
-
if (this.projectName === fileSignature.getProjectName()) {
|
|
1025
|
-
return this.filesMap.get(fileSignature.toMapKey()) || null;
|
|
1026
|
-
}
|
|
1027
|
-
else {
|
|
1028
|
-
return this.sdkArkFilesMap.get(fileSignature.toMapKey()) || null;
|
|
495
|
+
getFile(fileSigOrId) {
|
|
496
|
+
var _a, _b;
|
|
497
|
+
if (typeof fileSigOrId === 'number') {
|
|
498
|
+
return (_a = this.registry.fileSigCanonicalizer.getModel(fileSigOrId)) !== null && _a !== void 0 ? _a : null;
|
|
1029
499
|
}
|
|
500
|
+
return (_b = this.registry.fileSigCanonicalizer.getModel(this.registry.fileSigCanonicalizer.getExistingId(fileSigOrId))) !== null && _b !== void 0 ? _b : null;
|
|
1030
501
|
}
|
|
1031
502
|
/*
|
|
1032
503
|
* Returns the absolute file paths that cannot be handled currently.
|
|
@@ -1034,8 +505,9 @@ class Scene {
|
|
|
1034
505
|
getUnhandledFilePaths() {
|
|
1035
506
|
return Array.from(this.unhandledFilePaths);
|
|
1036
507
|
}
|
|
1037
|
-
|
|
1038
|
-
|
|
508
|
+
/** @internal 原始引用(Set):构建期上下文作防环工作集复用(成功 delete、失败残留)。 */
|
|
509
|
+
getUnhandledFileSet() {
|
|
510
|
+
return this.unhandledFilePaths;
|
|
1039
511
|
}
|
|
1040
512
|
/*
|
|
1041
513
|
* Returns the absolute sdk file paths that cannot be handled currently.
|
|
@@ -1043,55 +515,75 @@ class Scene {
|
|
|
1043
515
|
getUnhandledSdkFilePaths() {
|
|
1044
516
|
return this.unhandledSdkFilePaths;
|
|
1045
517
|
}
|
|
518
|
+
/** @internal 非用户 API。*/
|
|
1046
519
|
setFile(file) {
|
|
1047
|
-
|
|
520
|
+
file.setScene(this);
|
|
521
|
+
file.setProjectFile(true);
|
|
522
|
+
// 记录构建完成序(后序 = 拓扑序),见字段注释与 inferTypes。
|
|
523
|
+
this.builtFileOrder.push(file.getFileSigID());
|
|
1048
524
|
}
|
|
1049
|
-
/**
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
525
|
+
/** @internal project 文件的构建完成序(拓扑序:被依赖者在前)。推断期遍历事实源。 */
|
|
526
|
+
getBuiltFileOrder() {
|
|
527
|
+
return this.builtFileOrder;
|
|
528
|
+
}
|
|
529
|
+
/** @internal 非用户 API。*/
|
|
1053
530
|
addSdkArkFile(arkFile) {
|
|
1054
|
-
|
|
531
|
+
// 防御断言:边界已设置后不应再注册 SDK 文件(构建时序破坏,理论不可达)。
|
|
532
|
+
if (this.registry.getFirstProjectFileSigID() !== -1) {
|
|
533
|
+
logger.warn(`SDK file registered after the project/SDK ID boundary was marked: ${arkFile.getName()}`);
|
|
534
|
+
}
|
|
535
|
+
arkFile.setScene(this);
|
|
536
|
+
arkFile.setProjectFile(false);
|
|
1055
537
|
}
|
|
1056
|
-
hasSdkFile(
|
|
1057
|
-
|
|
538
|
+
hasSdkFile(fileSigOrId) {
|
|
539
|
+
let file;
|
|
540
|
+
if (typeof fileSigOrId === 'number') {
|
|
541
|
+
file = this.registry.fileSigCanonicalizer.getModel(fileSigOrId);
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
file = this.registry.fileSigCanonicalizer.getModel(this.registry.fileSigCanonicalizer.getExistingId(fileSigOrId));
|
|
545
|
+
}
|
|
546
|
+
return file !== undefined && !file.isProjectFile();
|
|
1058
547
|
}
|
|
1059
548
|
/**
|
|
1060
|
-
*
|
|
1061
|
-
* class. We need to generate {@link ArkFile} objects from these ets/ts files.
|
|
1062
|
-
* @returns The array of {@link ArkFile} from `scene.filesMap.values()`.
|
|
1063
|
-
* @example
|
|
1064
|
-
* 1. In inferSimpleTypes() to check arkClass and arkMethod.
|
|
1065
|
-
* ```typescript
|
|
1066
|
-
* public inferSimpleTypes(): void {
|
|
1067
|
-
* for (let arkFile of this.getFiles()) {
|
|
1068
|
-
* for (let arkClass of arkFile.getClasses()) {
|
|
1069
|
-
* for (let arkMethod of arkClass.getMethods()) {
|
|
1070
|
-
* // ... ...;
|
|
1071
|
-
* }
|
|
1072
|
-
* }
|
|
1073
|
-
* }
|
|
1074
|
-
* }
|
|
1075
|
-
* ```
|
|
1076
|
-
* 2. To iterate each method
|
|
1077
|
-
* ```typescript
|
|
1078
|
-
* for (const file of this.getFiles()) {
|
|
1079
|
-
* for (const cls of file.getClasses()) {
|
|
1080
|
-
* for (const method of cls.getMethods()) {
|
|
1081
|
-
* // ... ...
|
|
1082
|
-
* }
|
|
1083
|
-
* }
|
|
1084
|
-
* }
|
|
1085
|
-
*```
|
|
549
|
+
* 获取全部 project 文件(不含 SDK 文件)。
|
|
1086
550
|
*/
|
|
1087
551
|
getFiles() {
|
|
1088
|
-
|
|
552
|
+
const first = this.registry.getFirstProjectFileSigID();
|
|
553
|
+
if (first === -1) {
|
|
554
|
+
return [];
|
|
555
|
+
}
|
|
556
|
+
const size = this.registry.fileSigCanonicalizer.size();
|
|
557
|
+
const result = [];
|
|
558
|
+
for (let id = first; id < size; id++) {
|
|
559
|
+
const model = this.registry.fileSigCanonicalizer.getModel(id);
|
|
560
|
+
if (model !== undefined) {
|
|
561
|
+
result.push(model);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return result;
|
|
1089
565
|
}
|
|
1090
566
|
getFileLanguages() {
|
|
1091
567
|
return this.fileLanguages;
|
|
1092
568
|
}
|
|
569
|
+
/** @internal 构建期上下文在 SDK 阶段末尾回填语言表(保持与迁移前一致的赋值时序)。 */
|
|
570
|
+
setFileLanguages(fileLanguages) {
|
|
571
|
+
this.fileLanguages = fileLanguages;
|
|
572
|
+
}
|
|
573
|
+
/** 获取全部 SDK 文件。 */
|
|
1093
574
|
getSdkArkFiles() {
|
|
1094
|
-
|
|
575
|
+
const first = this.registry.getFirstProjectFileSigID();
|
|
576
|
+
if (first === -1) {
|
|
577
|
+
return [];
|
|
578
|
+
}
|
|
579
|
+
const result = [];
|
|
580
|
+
for (let id = 1; id < first; id++) {
|
|
581
|
+
const model = this.registry.fileSigCanonicalizer.getModel(id);
|
|
582
|
+
if (model !== undefined) {
|
|
583
|
+
result.push(model);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return result;
|
|
1095
587
|
}
|
|
1096
588
|
getModuleSdkMap() {
|
|
1097
589
|
return this.moduleSdkMap;
|
|
@@ -1099,159 +591,83 @@ class Scene {
|
|
|
1099
591
|
getProjectSdkMap() {
|
|
1100
592
|
return this.projectSdkMap;
|
|
1101
593
|
}
|
|
594
|
+
/**
|
|
595
|
+
* Returns the namespace according to the input namespace signature.
|
|
596
|
+
* @param namespaceSignature - signature of the namespace to be obtained.
|
|
597
|
+
* @returns A namespace, or null when the signature was never interned.
|
|
598
|
+
*/
|
|
1102
599
|
getNamespace(namespaceSignature) {
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
if (
|
|
1106
|
-
|
|
1107
|
-
}
|
|
1108
|
-
if (namespace) {
|
|
1109
|
-
return namespace;
|
|
1110
|
-
}
|
|
1111
|
-
namespace = this.getNamespaceBySignature(namespaceSignature);
|
|
1112
|
-
if (isProject && namespace) {
|
|
1113
|
-
this.namespacesMap.set(namespaceSignature.toMapKey(), namespace);
|
|
1114
|
-
}
|
|
1115
|
-
return namespace || null;
|
|
1116
|
-
}
|
|
1117
|
-
getNamespaceBySignature(signature) {
|
|
1118
|
-
const parentSignature = signature.getDeclaringNamespaceSignature();
|
|
1119
|
-
if (parentSignature) {
|
|
1120
|
-
const parentNamespace = this.getNamespaceBySignature(parentSignature);
|
|
1121
|
-
return (parentNamespace === null || parentNamespace === void 0 ? void 0 : parentNamespace.getNamespace(signature)) || null;
|
|
1122
|
-
}
|
|
1123
|
-
else {
|
|
1124
|
-
const arkFile = this.getFile(signature.getDeclaringFileSignature());
|
|
1125
|
-
return (arkFile === null || arkFile === void 0 ? void 0 : arkFile.getNamespace(signature)) || null;
|
|
600
|
+
var _a;
|
|
601
|
+
const id = this.registry.namespaceSigCanonicalizer.getExistingId(namespaceSignature);
|
|
602
|
+
if (id === -1) {
|
|
603
|
+
return null;
|
|
1126
604
|
}
|
|
605
|
+
return (_a = this.registry.namespaceSigCanonicalizer.getModel(id)) !== null && _a !== void 0 ? _a : null;
|
|
1127
606
|
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
607
|
+
/** 获取全部 project 文件的 ArkNamespace(不含 SDK,含嵌套层级摊平)。*/
|
|
608
|
+
getNamespaces() {
|
|
609
|
+
const reg = this.registry;
|
|
610
|
+
const size = reg.namespaceSigCanonicalizer.size();
|
|
611
|
+
const result = [];
|
|
612
|
+
for (let id = 1; id < size; id++) {
|
|
613
|
+
const ns = reg.namespaceSigCanonicalizer.getModel(id);
|
|
614
|
+
if (ns === undefined) {
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
617
|
+
if (!ns.getDeclaringArkFile().isProjectFile()) {
|
|
618
|
+
continue;
|
|
1134
619
|
}
|
|
620
|
+
result.push(ns);
|
|
1135
621
|
}
|
|
1136
|
-
return
|
|
1137
|
-
}
|
|
1138
|
-
getNamespaces() {
|
|
1139
|
-
return Array.from(this.getNamespacesMap().values());
|
|
622
|
+
return result;
|
|
1140
623
|
}
|
|
1141
624
|
/**
|
|
1142
625
|
* Returns the class according to the input class signature.
|
|
1143
626
|
* @param classSignature - signature of the class to be obtained.
|
|
1144
|
-
* @returns A class.
|
|
627
|
+
* @returns A class, or null when the signature was never interned.
|
|
1145
628
|
*/
|
|
1146
629
|
getClass(classSignature) {
|
|
1147
630
|
var _a;
|
|
1148
|
-
const
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
arkClass = this.classesMap.get(classSignature.toMapKey());
|
|
1152
|
-
}
|
|
1153
|
-
if (arkClass) {
|
|
1154
|
-
return arkClass;
|
|
1155
|
-
}
|
|
1156
|
-
const namespaceSignature = classSignature.getDeclaringNamespaceSignature();
|
|
1157
|
-
if (namespaceSignature) {
|
|
1158
|
-
arkClass = ((_a = this.getNamespaceBySignature(namespaceSignature)) === null || _a === void 0 ? void 0 : _a.getClass(classSignature)) || null;
|
|
1159
|
-
}
|
|
1160
|
-
else {
|
|
1161
|
-
const arkFile = this.getFile(classSignature.getDeclaringFileSignature());
|
|
1162
|
-
arkClass = arkFile === null || arkFile === void 0 ? void 0 : arkFile.getClass(classSignature);
|
|
1163
|
-
}
|
|
1164
|
-
if (isProject && arkClass) {
|
|
1165
|
-
this.classesMap.set(classSignature.toMapKey(), arkClass);
|
|
1166
|
-
}
|
|
1167
|
-
return arkClass || null;
|
|
1168
|
-
}
|
|
1169
|
-
/**
|
|
1170
|
-
* Register a custom {@code @Component} into {@link customComponentMap}.
|
|
1171
|
-
* Called from ArkClass builders (full Scene build and module load share the same path).
|
|
1172
|
-
* Entries intentionally survive module unload so ViewTree can still resolve signatures.
|
|
1173
|
-
*/
|
|
1174
|
-
registerCustomComponent(cls) {
|
|
1175
|
-
if (!cls.hasComponentDecorator()) {
|
|
1176
|
-
return;
|
|
1177
|
-
}
|
|
1178
|
-
const name = cls.getName();
|
|
1179
|
-
if (!name || name.startsWith('%')) {
|
|
1180
|
-
return;
|
|
1181
|
-
}
|
|
1182
|
-
this.customComponentMap.set(name, cls.getSignature());
|
|
1183
|
-
}
|
|
1184
|
-
/**
|
|
1185
|
-
* Remove a custom component entry. Not called on module unload — the map must outlive IR.
|
|
1186
|
-
* Used when an ArkClass is explicitly removed from a live Scene, or via {@link clear}.
|
|
1187
|
-
*/
|
|
1188
|
-
unregisterCustomComponent(cls) {
|
|
1189
|
-
const name = cls.getName();
|
|
1190
|
-
if (!name || !cls.hasComponentDecorator()) {
|
|
1191
|
-
return;
|
|
1192
|
-
}
|
|
1193
|
-
const existing = this.customComponentMap.get(name);
|
|
1194
|
-
if (existing && existing.toMapKey() === cls.getSignature().toMapKey()) {
|
|
1195
|
-
this.customComponentMap.delete(name);
|
|
631
|
+
const id = this.registry.classSigCanonicalizer.getExistingId(classSignature);
|
|
632
|
+
if (id === -1) {
|
|
633
|
+
return null;
|
|
1196
634
|
}
|
|
635
|
+
return (_a = this.registry.classSigCanonicalizer.getModel(id)) !== null && _a !== void 0 ? _a : null;
|
|
1197
636
|
}
|
|
1198
637
|
getCustomComponent(name) {
|
|
1199
|
-
return name ? this.customComponentMap.get(name) : undefined;
|
|
638
|
+
return name ? this.registry.customComponentMap.get(name) : undefined;
|
|
1200
639
|
}
|
|
1201
640
|
getCustomComponentMap() {
|
|
1202
|
-
return this.customComponentMap;
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
for (const cls of namespace.getClasses()) {
|
|
1214
|
-
this.classesMap.set(cls.getSignature().toMapKey(), cls);
|
|
1215
|
-
}
|
|
641
|
+
return this.registry.customComponentMap;
|
|
642
|
+
}
|
|
643
|
+
/** 获取全部 project 文件的 ArkClass(不含 SDK 类)。*/
|
|
644
|
+
getClasses() {
|
|
645
|
+
const reg = this.registry;
|
|
646
|
+
const size = reg.classSigCanonicalizer.size();
|
|
647
|
+
const result = [];
|
|
648
|
+
for (let id = 1; id < size; id++) {
|
|
649
|
+
const cls = reg.classSigCanonicalizer.getModel(id);
|
|
650
|
+
if (cls === undefined) {
|
|
651
|
+
continue;
|
|
1216
652
|
}
|
|
1217
|
-
if (
|
|
1218
|
-
|
|
653
|
+
if (!cls.getDeclaringArkFile().isProjectFile()) {
|
|
654
|
+
continue;
|
|
1219
655
|
}
|
|
656
|
+
result.push(cls);
|
|
1220
657
|
}
|
|
1221
|
-
return
|
|
1222
|
-
}
|
|
1223
|
-
getClasses() {
|
|
1224
|
-
return Array.from(this.getClassesMap().values());
|
|
658
|
+
return result;
|
|
1225
659
|
}
|
|
1226
|
-
getMethod(methodSignature,
|
|
1227
|
-
var _a;
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
if (
|
|
1231
|
-
arkMethod = this.methodsMap.get(methodSignature.toMapKey());
|
|
1232
|
-
}
|
|
1233
|
-
if (arkMethod) {
|
|
660
|
+
getMethod(methodSignature, _refresh) {
|
|
661
|
+
var _a, _b;
|
|
662
|
+
// Fast path: O(1) model lookup (read-only, never interns the signature).
|
|
663
|
+
const arkMethod = this.registry.getMethodBySig(methodSignature);
|
|
664
|
+
if (arkMethod !== undefined) {
|
|
1234
665
|
return arkMethod;
|
|
1235
666
|
}
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
return arkMethod || null;
|
|
1241
|
-
}
|
|
1242
|
-
getMethodsMap(refresh) {
|
|
1243
|
-
if (refresh || (this.buildStage >= SceneBuildStage.METHOD_DONE && this.buildStage < SceneBuildStage.METHOD_COLLECTED)) {
|
|
1244
|
-
this.methodsMap.clear();
|
|
1245
|
-
for (const cls of this.getClassesMap(refresh).values()) {
|
|
1246
|
-
for (const method of cls.getMethods(true)) {
|
|
1247
|
-
this.methodsMap.set(method.getSignature().toMapKey(), method);
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
if (this.buildStage < SceneBuildStage.METHOD_COLLECTED) {
|
|
1251
|
-
this.buildStage = SceneBuildStage.METHOD_COLLECTED;
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
return this.methodsMap;
|
|
667
|
+
// Fallback: closure-rebuilt signatures may not be registered as models yet —
|
|
668
|
+
// resolve via the declaring class's local traversal (isMatch-based). Read-only:
|
|
669
|
+
// no interning and no model back-fill (query paths must not write).
|
|
670
|
+
return (_b = (_a = this.getClass(methodSignature.getDeclaringClassSignature())) === null || _a === void 0 ? void 0 : _a.getMethod(methodSignature)) !== null && _b !== void 0 ? _b : null;
|
|
1255
671
|
}
|
|
1256
672
|
/**
|
|
1257
673
|
* Returns the method associated with the method signature.
|
|
@@ -1265,7 +681,6 @@ class Scene {
|
|
|
1265
681
|
* - View tree: the view tree of the method.
|
|
1266
682
|
* - ...
|
|
1267
683
|
*
|
|
1268
|
-
* @param methodSignature - the signature of method.
|
|
1269
684
|
* @returns The method associated with the method signature.
|
|
1270
685
|
* @example
|
|
1271
686
|
* 1. get method from getMethod.
|
|
@@ -1279,29 +694,19 @@ class Scene {
|
|
|
1279
694
|
```
|
|
1280
695
|
*/
|
|
1281
696
|
getMethods() {
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
return
|
|
1289
|
-
}
|
|
1290
|
-
removeClass(arkClass) {
|
|
1291
|
-
this.unregisterCustomComponent(arkClass);
|
|
1292
|
-
return this.classesMap.delete(arkClass.getSignature().toMapKey());
|
|
1293
|
-
}
|
|
1294
|
-
removeNamespace(namespace) {
|
|
1295
|
-
return this.namespacesMap.delete(namespace.getSignature().toMapKey());
|
|
1296
|
-
}
|
|
1297
|
-
removeFile(file) {
|
|
1298
|
-
return this.filesMap.delete(file.getFileSignature().toMapKey());
|
|
697
|
+
const methods = [];
|
|
698
|
+
for (const cls of this.getClasses()) {
|
|
699
|
+
for (const method of cls.getMethods(true)) {
|
|
700
|
+
methods.push(method);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
return methods;
|
|
1299
704
|
}
|
|
1300
705
|
/**
|
|
1301
706
|
* Dispose a module's data from all global indices.
|
|
1302
707
|
*
|
|
1303
708
|
* Removes the module's ArkFiles, ArkClasses, ArkMethods, and ArkNamespaces from the Scene's
|
|
1304
|
-
* global
|
|
709
|
+
* global canonicalizers and clears
|
|
1305
710
|
* the oh-package.json5 content cache. After this call, the module's heavy data is no longer
|
|
1306
711
|
* reachable via Scene's global indices and can be garbage-collected.
|
|
1307
712
|
*
|
|
@@ -1311,33 +716,37 @@ class Scene {
|
|
|
1311
716
|
* @param module - The module whose data should be removed from global indices.
|
|
1312
717
|
*/
|
|
1313
718
|
disposeModule(module) {
|
|
719
|
+
var _a;
|
|
1314
720
|
for (const arkFile of module.getFilesMap().values()) {
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
for (const ns of ModelUtils_1.ModelUtils.getAllNamespacesInFile(arkFile)) {
|
|
1319
|
-
this.namespacesMap.delete(ns.getNamespaceSignature().toMapKey());
|
|
721
|
+
this.registry.removeFile(arkFile);
|
|
722
|
+
for (const ns of arkFile.getAllNamespacesUnderThisFile()) {
|
|
723
|
+
this.registry.removeNamespace(ns);
|
|
1320
724
|
}
|
|
1321
725
|
for (const cls of ModelUtils_1.ModelUtils.getAllClassesInFile(arkFile)) {
|
|
1322
|
-
this.
|
|
1323
|
-
for (const
|
|
1324
|
-
this.
|
|
1325
|
-
|
|
1326
|
-
|
|
726
|
+
this.registry.removeClassModel(cls);
|
|
727
|
+
for (const fld of cls.getFields()) {
|
|
728
|
+
this.registry.removeField(fld);
|
|
729
|
+
}
|
|
730
|
+
for (const mtd of cls.getMethods(true)) {
|
|
731
|
+
this.registry.removeMethod(mtd);
|
|
732
|
+
// Release heavy per-method IR (ArkBody/CFG/Stmt/Locals + ViewTree) so it can be
|
|
733
|
+
// GC'd on eviction, even if the ArkMethod/ArkFile skeleton is still referenced
|
|
1327
734
|
// by residual back-edges. Bodies/viewTrees are rebuilt on reload.
|
|
1328
735
|
mtd.clearBodyAndSupplementary();
|
|
1329
736
|
}
|
|
1330
|
-
// Sever back-references: remove this class from its base classes'
|
|
737
|
+
// Sever back-references: remove this class from its base classes' extended classes,
|
|
1331
738
|
// otherwise base classes (e.g. SDK) keep evicted project classes alive (memory leak).
|
|
1332
739
|
for (const base of cls.getAllHeritageClasses()) {
|
|
1333
|
-
base.
|
|
740
|
+
base.removeExtendedClass(cls);
|
|
1334
741
|
}
|
|
1335
742
|
}
|
|
1336
743
|
// Release the TS AST (SourceFile) and cached source text; getCode() re-reads from disk.
|
|
1337
744
|
arkFile.setAST(null);
|
|
1338
745
|
arkFile.clearSourceCode();
|
|
1339
746
|
}
|
|
1340
|
-
|
|
747
|
+
// 驱逐模块的 oh-package 表项清理:经活跃构建上下文 best-effort(增量路径
|
|
748
|
+
// 上下文通常已释放,此时无 DFS 消费该表,跳过安全)。
|
|
749
|
+
(_a = this.getActiveSceneBuilder()) === null || _a === void 0 ? void 0 : _a.getOhPkgContentMap().delete(module.getOhPkgPath());
|
|
1341
750
|
}
|
|
1342
751
|
hasMainMethod() {
|
|
1343
752
|
return false;
|
|
@@ -1350,15 +759,6 @@ class Scene {
|
|
|
1350
759
|
getVisibleValue() {
|
|
1351
760
|
return this.visibleValue;
|
|
1352
761
|
}
|
|
1353
|
-
getOhPkgContent() {
|
|
1354
|
-
return this.ohPkgContent;
|
|
1355
|
-
}
|
|
1356
|
-
getOhPkgContentMap() {
|
|
1357
|
-
return this.ohPkgContentMap;
|
|
1358
|
-
}
|
|
1359
|
-
getOhPkgFilePath() {
|
|
1360
|
-
return this.ohPkgFilePath;
|
|
1361
|
-
}
|
|
1362
762
|
makeCallGraphCHA(entryPoints) {
|
|
1363
763
|
let callGraph = new CallGraph_1.CallGraph(this);
|
|
1364
764
|
let callGraphBuilder = new CallGraphBuilder_1.CallGraphBuilder(callGraph, this);
|
|
@@ -1397,27 +797,53 @@ class Scene {
|
|
|
1397
797
|
```
|
|
1398
798
|
*/
|
|
1399
799
|
inferTypes(times = 1) {
|
|
800
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1400
801
|
if (times < 1) {
|
|
1401
802
|
return;
|
|
1402
803
|
}
|
|
1403
804
|
else if (times > 5) {
|
|
1404
805
|
times = 5;
|
|
1405
806
|
}
|
|
1406
|
-
const sortedFiles = (0, DependenciesSort_1.sortByDependency)(this.filesMap, this.projectName);
|
|
1407
807
|
while (times > 0) {
|
|
1408
|
-
|
|
808
|
+
(_a = this.stageStatistics) === null || _a === void 0 ? void 0 : _a.startStage(StageStatistics_1.StageName.InferTypes);
|
|
809
|
+
for (const fileSigID of this.builtFileOrder) {
|
|
810
|
+
const file = this.registry.fileSigCanonicalizer.getModel(fileSigID);
|
|
811
|
+
if (file === undefined) {
|
|
812
|
+
continue;
|
|
813
|
+
}
|
|
1409
814
|
Inference_1.InferenceManager.getInstance().getInference(file.getLanguage()).doInfer(file);
|
|
815
|
+
(_b = this.stageStatistics) === null || _b === void 0 ? void 0 : _b.recordMemoryCheckpoint();
|
|
1410
816
|
}
|
|
817
|
+
(_c = this.stageStatistics) === null || _c === void 0 ? void 0 : _c.endStage(StageStatistics_1.StageName.InferTypes);
|
|
1411
818
|
times--;
|
|
1412
819
|
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
this.buildStage = SceneBuildStage.TYPE_INFERRED;
|
|
820
|
+
(_d = this.stageStatistics) === null || _d === void 0 ? void 0 : _d.startStage(StageStatistics_1.StageName.InferTypesFinalize);
|
|
821
|
+
if (this.buildStage < SceneBuildStage_2.SceneBuildStage.TYPE_INFERRED) {
|
|
822
|
+
this.buildStage = SceneBuildStage_2.SceneBuildStage.TYPE_INFERRED;
|
|
823
|
+
}
|
|
824
|
+
this.checkTempSignatureCompleteness();
|
|
825
|
+
if (this.getOptions().validateCanonicalizers === true) {
|
|
826
|
+
CanonicalizerValidator_1.CanonicalizerValidator.validateAll();
|
|
1416
827
|
}
|
|
1417
828
|
SdkUtils_1.SdkUtils.dispose();
|
|
1418
829
|
ModuleUtils_1.ModuleUtils.dispose();
|
|
1419
830
|
ValueUtil_1.ValueUtil.dispose();
|
|
1420
831
|
(0, builderUtils_1.clearCxxTypeStringCache)();
|
|
832
|
+
(_e = this.stageStatistics) === null || _e === void 0 ? void 0 : _e.endStage(StageStatistics_1.StageName.InferTypesFinalize);
|
|
833
|
+
// 签名空间快照(时点 2):推导完成后的 formal/temp 数据进报告。
|
|
834
|
+
(_f = this.stageStatistics) === null || _f === void 0 ? void 0 : _f.recordSignatureStats('post-infer');
|
|
835
|
+
}
|
|
836
|
+
checkTempSignatureCompleteness() {
|
|
837
|
+
const stats = this.registry.getTempSpacesStats();
|
|
838
|
+
const liveTotal = stats.class.liveCount + stats.method.liveCount + stats.field.liveCount;
|
|
839
|
+
if (liveTotal > 0) {
|
|
840
|
+
const brief = {
|
|
841
|
+
class: { live: stats.class.liveCount, retired: stats.class.retiredCount },
|
|
842
|
+
method: { live: stats.method.liveCount, retired: stats.method.retiredCount },
|
|
843
|
+
field: { live: stats.field.liveCount, retired: stats.field.retiredCount },
|
|
844
|
+
};
|
|
845
|
+
logger.warn(`Unresolved signatures still alive after type inference (index-table exact stats): ${JSON.stringify(brief)}`);
|
|
846
|
+
}
|
|
1421
847
|
}
|
|
1422
848
|
/**
|
|
1423
849
|
* @deprecated This method is deprecated and will be removed in the next major release.
|
|
@@ -1428,7 +854,7 @@ class Scene {
|
|
|
1428
854
|
inferTypesOld() {
|
|
1429
855
|
// CXXTodo: Building the mapping between declarations and implementations of C++ functions in cross-file scenarios.
|
|
1430
856
|
IRInference_1.IRInference.mapCxxDeclAndImpl(this);
|
|
1431
|
-
this.
|
|
857
|
+
this.getFiles().forEach(file => {
|
|
1432
858
|
try {
|
|
1433
859
|
// CXXTodo: Distinguish between C++ and TS/ArkTS.
|
|
1434
860
|
file.getLanguage() === ArkFile_1.Language.CXX ? IRInference_1.IRInference.inferFile(file) : IRInference_2.IRInference.inferFile(file);
|
|
@@ -1437,26 +863,12 @@ class Scene {
|
|
|
1437
863
|
logger.error('Error inferring types of project file:', file.getFileSignature(), error);
|
|
1438
864
|
}
|
|
1439
865
|
});
|
|
1440
|
-
if (this.buildStage < SceneBuildStage.TYPE_INFERRED) {
|
|
1441
|
-
this.
|
|
1442
|
-
this.buildStage = SceneBuildStage.TYPE_INFERRED;
|
|
866
|
+
if (this.buildStage < SceneBuildStage_2.SceneBuildStage.TYPE_INFERRED) {
|
|
867
|
+
this.buildStage = SceneBuildStage_2.SceneBuildStage.TYPE_INFERRED;
|
|
1443
868
|
}
|
|
1444
869
|
SdkUtils_1.SdkUtils.dispose();
|
|
1445
870
|
}
|
|
1446
|
-
/**
|
|
1447
|
-
* Iterate all assignment statements in methods,
|
|
1448
|
-
* and set the type of left operand based on the type of right operand
|
|
1449
|
-
* if the left operand is a local variable as well as an unknown.
|
|
1450
|
-
* @Deprecated
|
|
1451
|
-
* @example
|
|
1452
|
-
* 1. Infer simple type when scene building.
|
|
1453
|
-
|
|
1454
|
-
```typescript
|
|
1455
|
-
let scene = new Scene();
|
|
1456
|
-
scene.buildSceneFromProjectDir(config);
|
|
1457
|
-
scene.inferSimpleTypes();
|
|
1458
|
-
```
|
|
1459
|
-
*/
|
|
871
|
+
/** @deprecated 请改用 {@link inferTypes}(完整类型推断含 simple type 推断能力)。 */
|
|
1460
872
|
inferSimpleTypes() {
|
|
1461
873
|
for (let arkFile of this.getFiles()) {
|
|
1462
874
|
for (let arkClass of arkFile.getClasses()) {
|
|
@@ -1556,6 +968,7 @@ class Scene {
|
|
|
1556
968
|
}
|
|
1557
969
|
}
|
|
1558
970
|
}
|
|
971
|
+
/** @deprecated 如需全部 project 类请使用 {@link getClasses}。*/
|
|
1559
972
|
getClassMap() {
|
|
1560
973
|
const classMap = new Map();
|
|
1561
974
|
for (const file of this.getFiles()) {
|
|
@@ -1689,6 +1102,7 @@ class Scene {
|
|
|
1689
1102
|
}
|
|
1690
1103
|
}
|
|
1691
1104
|
}
|
|
1105
|
+
/** @deprecated 依赖 file→ns→class 结构骨架遍历,与 registry 事实源化的方向不一致。*/
|
|
1692
1106
|
getGlobalVariableMap() {
|
|
1693
1107
|
var _a, _b;
|
|
1694
1108
|
const globalVariableMap = new Map();
|
|
@@ -1720,15 +1134,17 @@ class Scene {
|
|
|
1720
1134
|
}
|
|
1721
1135
|
getStaticInitMethods() {
|
|
1722
1136
|
const staticInitMethods = [];
|
|
1723
|
-
for (const
|
|
1724
|
-
|
|
1725
|
-
|
|
1137
|
+
for (const cls of this.getClasses()) {
|
|
1138
|
+
for (const method of cls.getMethods(true)) {
|
|
1139
|
+
if (method.getName() === Const_1.STATIC_INIT_METHOD_NAME) {
|
|
1140
|
+
staticInitMethods.push(method);
|
|
1141
|
+
}
|
|
1726
1142
|
}
|
|
1727
1143
|
}
|
|
1728
1144
|
return staticInitMethods;
|
|
1729
1145
|
}
|
|
1730
1146
|
buildClassDone() {
|
|
1731
|
-
return this.buildStage >= SceneBuildStage.CLASS_DONE;
|
|
1147
|
+
return this.buildStage >= SceneBuildStage_2.SceneBuildStage.CLASS_DONE;
|
|
1732
1148
|
}
|
|
1733
1149
|
getModuleScene(moduleName) {
|
|
1734
1150
|
return this.moduleScenesMap.get(moduleName);
|
|
@@ -1736,82 +1152,102 @@ class Scene {
|
|
|
1736
1152
|
getModuleSceneMap() {
|
|
1737
1153
|
return this.moduleScenesMap;
|
|
1738
1154
|
}
|
|
1155
|
+
/** @internal 构建期上下文回填配置产物快照(构建后 getGlobalModule2PathMapping/getbaseUrl 可查)。 */
|
|
1156
|
+
setTsConfigSnapshot(paths, baseUrl) {
|
|
1157
|
+
this.tsConfigPathsSnapshot = paths;
|
|
1158
|
+
this.baseUrlSnapshot = baseUrl;
|
|
1159
|
+
}
|
|
1739
1160
|
getGlobalModule2PathMapping() {
|
|
1740
|
-
return this.
|
|
1161
|
+
return this.tsConfigPathsSnapshot;
|
|
1741
1162
|
}
|
|
1742
1163
|
getbaseUrl() {
|
|
1743
|
-
return this.
|
|
1164
|
+
return this.baseUrlSnapshot;
|
|
1744
1165
|
}
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
constructor(projectScene) {
|
|
1749
|
-
this.moduleName = '';
|
|
1750
|
-
this.modulePath = '';
|
|
1751
|
-
this.moduleFileMap = new Map();
|
|
1752
|
-
this.moduleOhPkgFilePath = '';
|
|
1753
|
-
this.ohPkgContent = {};
|
|
1754
|
-
this.projectScene = projectScene;
|
|
1755
|
-
}
|
|
1756
|
-
getProjectScene() {
|
|
1757
|
-
return this.projectScene;
|
|
1758
|
-
}
|
|
1759
|
-
ModuleSceneBuilder(moduleName, modulePath, supportFileExts, recursively = false) {
|
|
1760
|
-
this.moduleName = moduleName;
|
|
1761
|
-
this.modulePath = modulePath;
|
|
1762
|
-
this.getModuleOhPkgFilePath();
|
|
1763
|
-
if (this.moduleOhPkgFilePath) {
|
|
1764
|
-
this.ohPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(this.moduleOhPkgFilePath);
|
|
1765
|
-
}
|
|
1766
|
-
else {
|
|
1767
|
-
logger.warn('This module has no oh-package.json5!');
|
|
1768
|
-
}
|
|
1769
|
-
this.genArkFiles(supportFileExts);
|
|
1166
|
+
/** @internal 构建期上下文回填根 oh-package 内容快照(构建后 getOhPkgContent 可查)。 */
|
|
1167
|
+
setOhPkgContentSnapshot(content) {
|
|
1168
|
+
this.ohPkgContentSnapshot = content;
|
|
1770
1169
|
}
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
}
|
|
1170
|
+
/**
|
|
1171
|
+
* Get the parsed content of the project's root `oh-package.json5`.
|
|
1172
|
+
* Returns an empty object when the project has no oh-package.json5 or before the
|
|
1173
|
+
* scene is built.
|
|
1174
|
+
* @returns The oh-package.json5 content.
|
|
1175
|
+
*/
|
|
1176
|
+
getOhPkgContent() {
|
|
1177
|
+
return this.ohPkgContentSnapshot;
|
|
1780
1178
|
}
|
|
1781
1179
|
/**
|
|
1782
|
-
*
|
|
1180
|
+
* Get the collected stage statistics data, or undefined if statistics is disabled.
|
|
1181
|
+
* Auto-finalizes the collector if still running.
|
|
1783
1182
|
*/
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
this.moduleOhPkgFilePath = moduleOhPkgFilePath;
|
|
1183
|
+
getStageStatistics() {
|
|
1184
|
+
if (!this.stageStatistics) {
|
|
1185
|
+
return undefined;
|
|
1788
1186
|
}
|
|
1187
|
+
return this.stageStatistics.getStatistics();
|
|
1789
1188
|
}
|
|
1790
1189
|
/**
|
|
1791
|
-
*
|
|
1792
|
-
* @returns return module name
|
|
1190
|
+
* Print stage statistics to the logger.
|
|
1793
1191
|
*/
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
}
|
|
1803
|
-
getOhPkgContent() {
|
|
1804
|
-
return this.ohPkgContent;
|
|
1192
|
+
printStageStatistics() {
|
|
1193
|
+
if (!this.stageStatistics) {
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
const data = this.stageStatistics.getStatistics();
|
|
1197
|
+
const report = StageStatisticsReporter_1.StageStatisticsReporter.generateReport(data);
|
|
1198
|
+
logger.info(StageStatisticsReporter_1.StageStatisticsReporter.exportToText(report));
|
|
1199
|
+
this.statsReportWritten = true;
|
|
1805
1200
|
}
|
|
1806
|
-
|
|
1807
|
-
|
|
1201
|
+
/**
|
|
1202
|
+
* Export stage statistics as a text report to the given file path.
|
|
1203
|
+
* @returns true if the report was written, false if statistics is disabled.
|
|
1204
|
+
*/
|
|
1205
|
+
exportStageStatisticsReport(filePath) {
|
|
1206
|
+
if (!this.stageStatistics) {
|
|
1207
|
+
return false;
|
|
1208
|
+
}
|
|
1209
|
+
const data = this.stageStatistics.getStatistics();
|
|
1210
|
+
const report = StageStatisticsReporter_1.StageStatisticsReporter.generateReport(data);
|
|
1211
|
+
StageStatisticsReporter_1.StageStatisticsReporter.saveReportToFile(report, filePath);
|
|
1212
|
+
this.statsReportWritten = true;
|
|
1213
|
+
return true;
|
|
1808
1214
|
}
|
|
1809
|
-
|
|
1810
|
-
|
|
1215
|
+
/**
|
|
1216
|
+
* Register a process 'exit' hook that auto-writes the statistics report
|
|
1217
|
+
* when the process terminates, so users only need `enableStatistics: true`
|
|
1218
|
+
* without calling any output API manually.
|
|
1219
|
+
*/
|
|
1220
|
+
registerStatsExitHook() {
|
|
1221
|
+
if (this.statsExitHandler) {
|
|
1222
|
+
return;
|
|
1223
|
+
}
|
|
1224
|
+
this.statsExitHandler = () => {
|
|
1225
|
+
if (!this.stageStatistics || this.statsReportWritten) {
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
this.statsReportWritten = true;
|
|
1229
|
+
this.stageStatistics.finish();
|
|
1230
|
+
const data = this.stageStatistics.getStatistics();
|
|
1231
|
+
const report = StageStatisticsReporter_1.StageStatisticsReporter.generateReport(data);
|
|
1232
|
+
const reportPath = this.getStatisticsReportPath();
|
|
1233
|
+
StageStatisticsReporter_1.StageStatisticsReporter.saveReportToFile(report, reportPath);
|
|
1234
|
+
process.stdout.write(`Statistics report auto-saved to: ${reportPath}\n`);
|
|
1235
|
+
};
|
|
1236
|
+
process.on('exit', this.statsExitHandler);
|
|
1811
1237
|
}
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1238
|
+
/**
|
|
1239
|
+
* Resolve the default statistics report file path.
|
|
1240
|
+
* Uses `SceneOptions.statisticsOutputPath` if provided, otherwise
|
|
1241
|
+
* defaults to `out/<projectName>_statistics.txt` under the current working directory.
|
|
1242
|
+
*/
|
|
1243
|
+
getStatisticsReportPath() {
|
|
1244
|
+
var _a;
|
|
1245
|
+
const custom = (_a = this.options) === null || _a === void 0 ? void 0 : _a.statisticsOutputPath;
|
|
1246
|
+
if (custom) {
|
|
1247
|
+
return custom;
|
|
1248
|
+
}
|
|
1249
|
+
const dir = path_1.default.join(process.cwd(), 'out');
|
|
1250
|
+
return path_1.default.join(dir, `${this.projectName || 'arkanalyzer'}_statistics.txt`);
|
|
1815
1251
|
}
|
|
1816
1252
|
}
|
|
1817
|
-
exports.
|
|
1253
|
+
exports.Scene = Scene;
|