arkanalyzer 1.0.20 → 1.0.21
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 +70 -70
- package/lib/Config.js +198 -198
- package/lib/Scene.d.ts +316 -316
- package/lib/Scene.js +1316 -1316
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts +28 -28
- package/lib/callgraph/algorithm/AbstractAnalysis.js +144 -144
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.d.ts +10 -10
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.js +69 -69
- package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts +15 -15
- package/lib/callgraph/algorithm/RapidTypeAnalysis.js +146 -146
- package/lib/callgraph/common/Statistics.d.ts +57 -57
- package/lib/callgraph/common/Statistics.js +228 -228
- package/lib/callgraph/model/CallGraph.d.ts +96 -96
- package/lib/callgraph/model/CallGraph.js +354 -354
- package/lib/callgraph/model/builder/CallGraphBuilder.d.ts +15 -15
- package/lib/callgraph/model/builder/CallGraphBuilder.js +106 -106
- package/lib/callgraph/pointerAnalysis/Context.d.ts +37 -37
- package/lib/callgraph/pointerAnalysis/Context.js +155 -155
- package/lib/callgraph/pointerAnalysis/DummyCallCreator.d.ts +22 -22
- package/lib/callgraph/pointerAnalysis/DummyCallCreator.js +104 -104
- package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts +5 -5
- package/lib/callgraph/pointerAnalysis/PTAUtils.js +46 -46
- package/lib/callgraph/pointerAnalysis/Pag.d.ts +261 -261
- package/lib/callgraph/pointerAnalysis/Pag.js +930 -930
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +157 -157
- package/lib/callgraph/pointerAnalysis/PagBuilder.js +1399 -1399
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts +72 -72
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +573 -573
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.d.ts +15 -15
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.js +81 -81
- package/lib/callgraph/pointerAnalysis/PtsDS.d.ts +80 -80
- package/lib/callgraph/pointerAnalysis/PtsDS.js +308 -308
- package/lib/core/base/Constant.d.ts +48 -48
- package/lib/core/base/Constant.js +103 -103
- package/lib/core/base/Decorator.d.ts +15 -15
- package/lib/core/base/Decorator.js +46 -46
- package/lib/core/base/DefUseChain.d.ts +8 -8
- package/lib/core/base/DefUseChain.js +25 -25
- package/lib/core/base/Expr.d.ts +340 -340
- package/lib/core/base/Expr.js +917 -917
- package/lib/core/base/Local.d.ts +104 -104
- package/lib/core/base/Local.js +176 -176
- package/lib/core/base/Position.d.ts +30 -30
- package/lib/core/base/Position.js +147 -147
- package/lib/core/base/Ref.d.ts +173 -173
- package/lib/core/base/Ref.js +374 -374
- package/lib/core/base/Stmt.d.ts +237 -237
- package/lib/core/base/Stmt.js +525 -525
- package/lib/core/base/Trap.d.ts +8 -8
- package/lib/core/base/Trap.js +30 -30
- package/lib/core/base/Type.d.ts +308 -308
- package/lib/core/base/Type.js +639 -639
- package/lib/core/base/TypeExpr.d.ts +71 -71
- package/lib/core/base/TypeExpr.js +155 -155
- package/lib/core/base/Value.d.ts +32 -32
- package/lib/core/base/Value.js +16 -16
- package/lib/core/common/ArkError.d.ts +14 -14
- package/lib/core/common/ArkError.js +28 -28
- package/lib/core/common/ArkIRTransformer.d.ts +67 -67
- package/lib/core/common/ArkIRTransformer.js +690 -690
- package/lib/core/common/ArkValueTransformer.d.ts +89 -89
- package/lib/core/common/ArkValueTransformer.js +1478 -1478
- package/lib/core/common/Builtin.d.ts +36 -36
- package/lib/core/common/Builtin.js +81 -81
- package/lib/core/common/Const.d.ts +21 -21
- package/lib/core/common/Const.js +43 -43
- package/lib/core/common/DummyMainCreater.d.ts +46 -46
- package/lib/core/common/DummyMainCreater.js +319 -319
- package/lib/core/common/EtsConst.d.ts +73 -73
- package/lib/core/common/EtsConst.js +1021 -1021
- package/lib/core/common/ExprUseReplacer.d.ts +21 -21
- package/lib/core/common/ExprUseReplacer.js +124 -124
- package/lib/core/common/IRInference.d.ts +36 -36
- package/lib/core/common/IRInference.d.ts.map +1 -1
- package/lib/core/common/IRInference.js +651 -648
- package/lib/core/common/IRUtils.d.ts +18 -18
- package/lib/core/common/IRUtils.js +141 -141
- package/lib/core/common/ModelUtils.d.ts +70 -70
- package/lib/core/common/ModelUtils.js +712 -712
- package/lib/core/common/RefUseReplacer.d.ts +13 -13
- package/lib/core/common/RefUseReplacer.js +52 -52
- package/lib/core/common/SdkUtils.d.ts +8 -8
- package/lib/core/common/SdkUtils.js +105 -105
- package/lib/core/common/StmtDefReplacer.d.ts +12 -12
- package/lib/core/common/StmtDefReplacer.js +41 -41
- package/lib/core/common/StmtUseReplacer.d.ts +16 -16
- package/lib/core/common/StmtUseReplacer.js +108 -108
- package/lib/core/common/TSConst.d.ts +18 -18
- package/lib/core/common/TSConst.js +36 -36
- package/lib/core/common/TypeInference.d.ts +102 -102
- package/lib/core/common/TypeInference.js +748 -748
- package/lib/core/common/ValueUtil.d.ts +12 -12
- package/lib/core/common/ValueUtil.js +54 -54
- package/lib/core/common/VisibleValue.d.ts +36 -36
- package/lib/core/common/VisibleValue.js +212 -212
- package/lib/core/dataflow/DataflowProblem.d.ts +20 -20
- package/lib/core/dataflow/DataflowProblem.js +20 -20
- package/lib/core/dataflow/DataflowResult.d.ts +7 -7
- package/lib/core/dataflow/DataflowResult.js +26 -26
- package/lib/core/dataflow/DataflowSolver.d.ts +43 -43
- package/lib/core/dataflow/DataflowSolver.js +307 -307
- package/lib/core/dataflow/Edge.d.ts +11 -11
- package/lib/core/dataflow/Edge.js +31 -31
- package/lib/core/dataflow/Fact.d.ts +6 -6
- package/lib/core/dataflow/Fact.js +24 -24
- package/lib/core/dataflow/GenericDataFlow.d.ts +142 -142
- package/lib/core/dataflow/GenericDataFlow.js +109 -109
- package/lib/core/dataflow/ReachingDef.d.ts +62 -62
- package/lib/core/dataflow/ReachingDef.js +168 -168
- package/lib/core/dataflow/UndefinedVariable.d.ts +45 -45
- package/lib/core/dataflow/UndefinedVariable.js +288 -288
- package/lib/core/dataflow/Util.d.ts +9 -9
- package/lib/core/dataflow/Util.js +64 -64
- package/lib/core/graph/BaseExplicitGraph.d.ts +58 -58
- package/lib/core/graph/BaseExplicitGraph.js +157 -157
- package/lib/core/graph/BaseImplicitGraph.d.ts +77 -77
- package/lib/core/graph/BaseImplicitGraph.js +78 -78
- package/lib/core/graph/BasicBlock.d.ts +104 -104
- package/lib/core/graph/BasicBlock.js +280 -280
- package/lib/core/graph/Cfg.d.ts +59 -59
- package/lib/core/graph/Cfg.js +282 -282
- package/lib/core/graph/DependsGraph.d.ts +35 -35
- package/lib/core/graph/DependsGraph.js +87 -87
- package/lib/core/graph/DominanceFinder.d.ts +15 -15
- package/lib/core/graph/DominanceFinder.js +121 -121
- package/lib/core/graph/DominanceTree.d.ts +12 -12
- package/lib/core/graph/DominanceTree.js +70 -70
- package/lib/core/graph/GraphTraits.d.ts +7 -7
- package/lib/core/graph/GraphTraits.js +16 -16
- package/lib/core/graph/Scc.d.ts +61 -61
- package/lib/core/graph/Scc.js +222 -222
- package/lib/core/graph/ViewTree.d.ts +114 -114
- package/lib/core/graph/ViewTree.js +16 -16
- package/lib/core/graph/builder/CfgBuilder.d.ts +176 -176
- package/lib/core/graph/builder/CfgBuilder.js +1139 -1139
- package/lib/core/graph/builder/ConditionBuilder.d.ts +15 -15
- package/lib/core/graph/builder/ConditionBuilder.js +252 -252
- package/lib/core/graph/builder/LoopBuilder.d.ts +20 -20
- package/lib/core/graph/builder/LoopBuilder.js +251 -251
- package/lib/core/graph/builder/SwitchBuilder.d.ts +11 -11
- package/lib/core/graph/builder/SwitchBuilder.js +152 -152
- package/lib/core/graph/builder/TrapBuilder.d.ts +16 -16
- package/lib/core/graph/builder/TrapBuilder.js +272 -272
- package/lib/core/graph/builder/ViewTreeBuilder.d.ts +203 -203
- package/lib/core/graph/builder/ViewTreeBuilder.js +1055 -1055
- package/lib/core/model/ArkBaseModel.d.ts +59 -59
- package/lib/core/model/ArkBaseModel.js +274 -274
- package/lib/core/model/ArkBody.d.ts +24 -24
- package/lib/core/model/ArkBody.js +65 -65
- package/lib/core/model/ArkClass.d.ts +206 -206
- package/lib/core/model/ArkClass.js +439 -439
- package/lib/core/model/ArkExport.d.ts +72 -72
- package/lib/core/model/ArkExport.js +147 -147
- package/lib/core/model/ArkField.d.ts +62 -62
- package/lib/core/model/ArkField.js +113 -113
- package/lib/core/model/ArkFile.d.ts +131 -131
- package/lib/core/model/ArkFile.js +267 -267
- package/lib/core/model/ArkImport.d.ts +44 -44
- package/lib/core/model/ArkImport.js +108 -108
- package/lib/core/model/ArkMetadata.d.ts +31 -31
- package/lib/core/model/ArkMetadata.js +55 -55
- package/lib/core/model/ArkMethod.d.ts +261 -261
- package/lib/core/model/ArkMethod.js +592 -592
- package/lib/core/model/ArkNamespace.d.ts +66 -66
- package/lib/core/model/ArkNamespace.js +209 -209
- package/lib/core/model/ArkSignature.d.ts +162 -162
- package/lib/core/model/ArkSignature.js +379 -379
- package/lib/core/model/builder/ArkClassBuilder.d.ts +12 -12
- package/lib/core/model/builder/ArkClassBuilder.js +454 -454
- package/lib/core/model/builder/ArkExportBuilder.d.ts +24 -24
- package/lib/core/model/builder/ArkExportBuilder.js +210 -210
- package/lib/core/model/builder/ArkFieldBuilder.d.ts +8 -8
- package/lib/core/model/builder/ArkFieldBuilder.js +193 -193
- package/lib/core/model/builder/ArkFileBuilder.d.ts +9 -9
- package/lib/core/model/builder/ArkFileBuilder.js +165 -165
- package/lib/core/model/builder/ArkImportBuilder.d.ts +4 -4
- package/lib/core/model/builder/ArkImportBuilder.js +128 -128
- package/lib/core/model/builder/ArkMethodBuilder.d.ts +63 -63
- package/lib/core/model/builder/ArkMethodBuilder.js +486 -486
- package/lib/core/model/builder/ArkNamespaceBuilder.d.ts +5 -5
- package/lib/core/model/builder/ArkNamespaceBuilder.js +205 -205
- package/lib/core/model/builder/ArkSignatureBuilder.d.ts +8 -8
- package/lib/core/model/builder/ArkSignatureBuilder.js +40 -40
- package/lib/core/model/builder/BodyBuilder.d.ts +55 -30
- package/lib/core/model/builder/BodyBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/BodyBuilder.js +542 -371
- package/lib/core/model/builder/builderUtils.d.ts +18 -18
- package/lib/core/model/builder/builderUtils.js +558 -558
- package/lib/index.d.ts +82 -80
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +201 -196
- package/lib/save/ArkStream.d.ts +23 -23
- package/lib/save/ArkStream.js +83 -83
- package/lib/save/DotPrinter.d.ts +43 -43
- package/lib/save/DotPrinter.js +170 -170
- package/lib/save/GraphPrinter.d.ts +16 -16
- package/lib/save/GraphPrinter.js +134 -134
- package/lib/save/JsonPrinter.d.ts +30 -30
- package/lib/save/JsonPrinter.js +580 -580
- package/lib/save/Printer.d.ts +12 -12
- package/lib/save/Printer.js +27 -27
- package/lib/save/PrinterBuilder.d.ts +53 -53
- package/lib/save/PrinterBuilder.js +145 -145
- package/lib/save/ViewTreePrinter.d.ts +14 -14
- package/lib/save/ViewTreePrinter.js +123 -123
- package/lib/save/arkir/ArkIRClassPrinter.d.ts +13 -13
- package/lib/save/arkir/ArkIRClassPrinter.js +92 -92
- package/lib/save/arkir/ArkIRFieldPrinter.d.ts +11 -11
- package/lib/save/arkir/ArkIRFieldPrinter.js +64 -64
- package/lib/save/arkir/ArkIRFilePrinter.d.ts +12 -12
- package/lib/save/arkir/ArkIRFilePrinter.js +54 -54
- package/lib/save/arkir/ArkIRMethodPrinter.d.ts +16 -16
- package/lib/save/arkir/ArkIRMethodPrinter.js +159 -159
- package/lib/save/arkir/ArkIRNamespacePrinter.d.ts +11 -11
- package/lib/save/arkir/ArkIRNamespacePrinter.js +66 -66
- package/lib/save/base/BasePrinter.d.ts +23 -23
- package/lib/save/base/BasePrinter.js +70 -70
- package/lib/save/base/ExportPrinter.d.ts +8 -8
- package/lib/save/base/ExportPrinter.js +67 -67
- package/lib/save/base/ImportPrinter.d.ts +9 -9
- package/lib/save/base/ImportPrinter.js +92 -92
- package/lib/save/base/PrinterUtils.d.ts +24 -24
- package/lib/save/base/PrinterUtils.js +208 -208
- package/lib/save/serializeArkIR.d.ts +8 -8
- package/lib/save/serializeArkIR.js +294 -294
- package/lib/save/source/SourceBase.d.ts +22 -22
- package/lib/save/source/SourceBase.js +64 -64
- package/lib/save/source/SourceBody.d.ts +58 -58
- package/lib/save/source/SourceBody.js +296 -296
- package/lib/save/source/SourceClass.d.ts +25 -25
- package/lib/save/source/SourceClass.js +187 -187
- package/lib/save/source/SourceField.d.ts +13 -13
- package/lib/save/source/SourceField.js +73 -73
- package/lib/save/source/SourceFilePrinter.d.ts +12 -12
- package/lib/save/source/SourceFilePrinter.js +69 -69
- package/lib/save/source/SourceMethod.d.ts +22 -22
- package/lib/save/source/SourceMethod.d.ts.map +1 -1
- package/lib/save/source/SourceMethod.js +196 -193
- package/lib/save/source/SourceNamespace.d.ts +11 -11
- package/lib/save/source/SourceNamespace.js +83 -83
- package/lib/save/source/SourceStmt.d.ts +178 -178
- package/lib/save/source/SourceStmt.js +838 -838
- package/lib/save/source/SourceTransformer.d.ts +46 -46
- package/lib/save/source/SourceTransformer.js +446 -446
- package/lib/transformer/FunctionTransformer.d.ts +2 -2
- package/lib/transformer/FunctionTransformer.js +17 -17
- package/lib/transformer/SceneTransformer.d.ts +2 -2
- package/lib/transformer/SceneTransformer.js +17 -17
- package/lib/transformer/StaticSingleAssignmentFormer.d.ts +12 -12
- package/lib/transformer/StaticSingleAssignmentFormer.js +259 -259
- package/lib/transformer/Transformer.d.ts +6 -6
- package/lib/transformer/Transformer.js +22 -22
- package/lib/utils/AstTreeUtils.d.ts +4 -4
- package/lib/utils/AstTreeUtils.js +26 -26
- package/lib/utils/CfgStructualAnalysis.d.ts +110 -110
- package/lib/utils/CfgStructualAnalysis.js +1277 -1277
- package/lib/utils/FileUtils.d.ts +18 -18
- package/lib/utils/FileUtils.js +135 -135
- package/lib/utils/SparseBitVector.d.ts +100 -100
- package/lib/utils/SparseBitVector.js +445 -445
- package/lib/utils/callGraphUtils.d.ts +30 -30
- package/lib/utils/callGraphUtils.js +205 -205
- package/lib/utils/crypto_utils.d.ts +5 -5
- package/lib/utils/crypto_utils.js +57 -57
- package/lib/utils/entryMethodUtils.d.ts +13 -13
- package/lib/utils/entryMethodUtils.js +110 -110
- package/lib/utils/getAllFiles.d.ts +9 -9
- package/lib/utils/getAllFiles.js +90 -90
- package/lib/utils/json5parser.d.ts +6 -6
- package/lib/utils/json5parser.js +146 -146
- package/lib/utils/logger.d.ts +18 -18
- package/lib/utils/logger.d.ts.map +1 -1
- package/lib/utils/logger.js +97 -90
- package/lib/utils/pathTransfer.d.ts +1 -1
- package/lib/utils/pathTransfer.js +25 -25
- package/node_modules/json5/lib/cli.js +0 -0
- package/node_modules/ohos-typescript/bin/tsc +0 -0
- package/node_modules/ohos-typescript/bin/tsserver +0 -0
- package/package.json +3 -3
package/lib/Scene.js
CHANGED
|
@@ -1,1316 +1,1316 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright (c) 2024-2025 Huawei Device Co., Ltd.
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
-
if (k2 === undefined) k2 = k;
|
|
18
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
-
}
|
|
22
|
-
Object.defineProperty(o, k2, desc);
|
|
23
|
-
}) : (function(o, m, k, k2) {
|
|
24
|
-
if (k2 === undefined) k2 = k;
|
|
25
|
-
o[k2] = m[k];
|
|
26
|
-
}));
|
|
27
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
-
}) : function(o, v) {
|
|
30
|
-
o["default"] = v;
|
|
31
|
-
});
|
|
32
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
33
|
-
if (mod && mod.__esModule) return mod;
|
|
34
|
-
var result = {};
|
|
35
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
36
|
-
__setModuleDefault(result, mod);
|
|
37
|
-
return result;
|
|
38
|
-
};
|
|
39
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
-
};
|
|
42
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
-
exports.ModuleScene = exports.Scene = void 0;
|
|
44
|
-
const fs_1 = __importDefault(require("fs"));
|
|
45
|
-
const path_1 = __importDefault(require("path"));
|
|
46
|
-
const ModelUtils_1 = require("./core/common/ModelUtils");
|
|
47
|
-
const TypeInference_1 = require("./core/common/TypeInference");
|
|
48
|
-
const VisibleValue_1 = require("./core/common/VisibleValue");
|
|
49
|
-
const ArkFile_1 = require("./core/model/ArkFile");
|
|
50
|
-
const ArkNamespace_1 = require("./core/model/ArkNamespace");
|
|
51
|
-
const ArkSignature_1 = require("./core/model/ArkSignature");
|
|
52
|
-
const logger_1 = __importStar(require("./utils/logger"));
|
|
53
|
-
const ArkFileBuilder_1 = require("./core/model/builder/ArkFileBuilder");
|
|
54
|
-
const json5parser_1 = require("./utils/json5parser");
|
|
55
|
-
const getAllFiles_1 = require("./utils/getAllFiles");
|
|
56
|
-
const FileUtils_1 = require("./utils/FileUtils");
|
|
57
|
-
const ArkExport_1 = require("./core/model/ArkExport");
|
|
58
|
-
const ArkMethodBuilder_1 = require("./core/model/builder/ArkMethodBuilder");
|
|
59
|
-
const Const_1 = require("./core/common/Const");
|
|
60
|
-
const CallGraph_1 = require("./callgraph/model/CallGraph");
|
|
61
|
-
const CallGraphBuilder_1 = require("./callgraph/model/builder/CallGraphBuilder");
|
|
62
|
-
const IRInference_1 = require("./core/common/IRInference");
|
|
63
|
-
const TSConst_1 = require("./core/common/TSConst");
|
|
64
|
-
const EtsConst_1 = require("./core/common/EtsConst");
|
|
65
|
-
const SdkUtils_1 = require("./core/common/SdkUtils");
|
|
66
|
-
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'Scene');
|
|
67
|
-
var SceneBuildStage;
|
|
68
|
-
(function (SceneBuildStage) {
|
|
69
|
-
SceneBuildStage[SceneBuildStage["BUILD_INIT"] = 0] = "BUILD_INIT";
|
|
70
|
-
SceneBuildStage[SceneBuildStage["CLASS_DONE"] = 1] = "CLASS_DONE";
|
|
71
|
-
SceneBuildStage[SceneBuildStage["METHOD_DONE"] = 2] = "METHOD_DONE";
|
|
72
|
-
SceneBuildStage[SceneBuildStage["CLASS_COLLECTED"] = 3] = "CLASS_COLLECTED";
|
|
73
|
-
SceneBuildStage[SceneBuildStage["METHOD_COLLECTED"] = 4] = "METHOD_COLLECTED";
|
|
74
|
-
SceneBuildStage[SceneBuildStage["SDK_INFERRED"] = 5] = "SDK_INFERRED";
|
|
75
|
-
SceneBuildStage[SceneBuildStage["TYPE_INFERRED"] = 6] = "TYPE_INFERRED";
|
|
76
|
-
})(SceneBuildStage || (SceneBuildStage = {}));
|
|
77
|
-
;
|
|
78
|
-
/**
|
|
79
|
-
* The Scene class includes everything in the analyzed project.
|
|
80
|
-
* We should be able to re-generate the project's code based on this class.
|
|
81
|
-
*/
|
|
82
|
-
class Scene {
|
|
83
|
-
constructor() {
|
|
84
|
-
this.projectName = '';
|
|
85
|
-
this.projectFiles = [];
|
|
86
|
-
this.realProjectDir = '';
|
|
87
|
-
this.moduleScenesMap = new Map();
|
|
88
|
-
this.modulePath2NameMap = new Map();
|
|
89
|
-
this.moduleSdkMap = new Map();
|
|
90
|
-
this.projectSdkMap = new Map();
|
|
91
|
-
// values that are visible in curr scope
|
|
92
|
-
this.visibleValue = new VisibleValue_1.VisibleValue();
|
|
93
|
-
// signature string to model
|
|
94
|
-
this.filesMap = new Map();
|
|
95
|
-
this.namespacesMap = new Map();
|
|
96
|
-
this.classesMap = new Map();
|
|
97
|
-
this.methodsMap = new Map();
|
|
98
|
-
// TODO: type of key should be signature object
|
|
99
|
-
this.sdkArkFilesMap = new Map();
|
|
100
|
-
this.sdkGlobalMap = new Map();
|
|
101
|
-
this.ohPkgContentMap = new Map();
|
|
102
|
-
this.ohPkgFilePath = '';
|
|
103
|
-
this.ohPkgContent = {};
|
|
104
|
-
this.overRides = new Map();
|
|
105
|
-
this.overRideDependencyMap = new Map();
|
|
106
|
-
this.buildStage = SceneBuildStage.BUILD_INIT;
|
|
107
|
-
this.indexPathArray = ['Index.ets', 'Index.ts', 'Index.d.ets', 'Index.d.ts', 'index.ets', 'index.ts', 'index.d.ets', 'index.d.ts'];
|
|
108
|
-
this.unhandledFilePaths = [];
|
|
109
|
-
this.unhandledSdkFilePaths = [];
|
|
110
|
-
}
|
|
111
|
-
getOptions() {
|
|
112
|
-
return this.options;
|
|
113
|
-
}
|
|
114
|
-
getOverRides() {
|
|
115
|
-
return this.overRides;
|
|
116
|
-
}
|
|
117
|
-
getOverRideDependencyMap() {
|
|
118
|
-
return this.overRideDependencyMap;
|
|
119
|
-
}
|
|
120
|
-
clear() {
|
|
121
|
-
this.projectFiles = [];
|
|
122
|
-
this.moduleScenesMap.clear();
|
|
123
|
-
this.modulePath2NameMap.clear();
|
|
124
|
-
this.moduleSdkMap.clear();
|
|
125
|
-
this.projectSdkMap.clear();
|
|
126
|
-
this.filesMap.clear();
|
|
127
|
-
this.namespacesMap.clear();
|
|
128
|
-
this.classesMap.clear();
|
|
129
|
-
this.methodsMap.clear();
|
|
130
|
-
this.sdkArkFilesMap.clear();
|
|
131
|
-
this.sdkGlobalMap.clear();
|
|
132
|
-
this.ohPkgContentMap.clear();
|
|
133
|
-
this.ohPkgContent = {};
|
|
134
|
-
}
|
|
135
|
-
getStage() {
|
|
136
|
-
return this.buildStage;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Build scene object according to the {@link SceneConfig}. This API implements 3 functions.
|
|
140
|
-
* First is to build scene object from {@link SceneConfig}, second is to generate {@link ArkFile}s,
|
|
141
|
-
* and the last is to collect project import infomation.
|
|
142
|
-
* @param sceneConfig - a sceneConfig object, which is usally defined by user or Json file.
|
|
143
|
-
* @example
|
|
144
|
-
* 1. Build Scene object from scene config
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
// build config
|
|
148
|
-
const projectDir = ... ...;
|
|
149
|
-
const sceneConfig = new SceneConfig();
|
|
150
|
-
sceneConfig.buildFromProjectDir(projectDir);
|
|
151
|
-
|
|
152
|
-
// build scene
|
|
153
|
-
const scene = new Scene();
|
|
154
|
-
scene.buildSceneFromProjectDir(sceneConfig);
|
|
155
|
-
```
|
|
156
|
-
*/
|
|
157
|
-
buildSceneFromProjectDir(sceneConfig) {
|
|
158
|
-
this.buildBasicInfo(sceneConfig);
|
|
159
|
-
this.genArkFiles();
|
|
160
|
-
}
|
|
161
|
-
buildSceneFromFiles(sceneConfig) {
|
|
162
|
-
this.buildBasicInfo(sceneConfig);
|
|
163
|
-
this.buildOhPkgContentMap();
|
|
164
|
-
(0, ModelUtils_1.initModulePathMap)(this.ohPkgContentMap);
|
|
165
|
-
this.getFilesOrderByDependency();
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Set the basic information of the scene using a config,
|
|
169
|
-
* such as the project's name, real path and files.
|
|
170
|
-
* @param sceneConfig - the config used to set the basic information of scene.
|
|
171
|
-
*/
|
|
172
|
-
buildBasicInfo(sceneConfig) {
|
|
173
|
-
var _a;
|
|
174
|
-
this.options = sceneConfig.getOptions();
|
|
175
|
-
this.projectName = sceneConfig.getTargetProjectName();
|
|
176
|
-
this.realProjectDir = fs_1.default.realpathSync(sceneConfig.getTargetProjectDirectory());
|
|
177
|
-
this.projectFiles = sceneConfig.getProjectFiles();
|
|
178
|
-
this.parseBuildProfile();
|
|
179
|
-
this.parseOhPackage();
|
|
180
|
-
let tsConfigFilePath;
|
|
181
|
-
if (this.options.tsconfig) {
|
|
182
|
-
tsConfigFilePath = path_1.default.join(sceneConfig.getTargetProjectDirectory(), this.options.tsconfig);
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
tsConfigFilePath = path_1.default.join(sceneConfig.getTargetProjectDirectory(), TSConst_1.TSCONFIG_JSON);
|
|
186
|
-
}
|
|
187
|
-
if (fs_1.default.existsSync(tsConfigFilePath)) {
|
|
188
|
-
const tsConfigObj = (0, json5parser_1.fetchDependenciesFromFile)(tsConfigFilePath);
|
|
189
|
-
this.findTsConfigInfoDeeply(tsConfigObj, tsConfigFilePath);
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
logger.warn('This project has no tsconfig.json!');
|
|
193
|
-
}
|
|
194
|
-
// handle sdks
|
|
195
|
-
(_a = sceneConfig.getSdksObj()) === null || _a === void 0 ? void 0 : _a.forEach((sdk) => {
|
|
196
|
-
if (!sdk.moduleName) {
|
|
197
|
-
this.buildSdk(sdk.name, sdk.path);
|
|
198
|
-
this.projectSdkMap.set(sdk.name, sdk);
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
let moduleSdks = this.moduleSdkMap.get(sdk.moduleName);
|
|
202
|
-
if (moduleSdks) {
|
|
203
|
-
moduleSdks.push(sdk);
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
this.moduleSdkMap.set(sdk.moduleName, [sdk]);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
parseBuildProfile() {
|
|
212
|
-
const buildProfile = path_1.default.join(this.realProjectDir, EtsConst_1.BUILD_PROFILE_JSON5);
|
|
213
|
-
if (fs_1.default.existsSync(buildProfile)) {
|
|
214
|
-
let configurationsText;
|
|
215
|
-
try {
|
|
216
|
-
configurationsText = fs_1.default.readFileSync(buildProfile, 'utf-8');
|
|
217
|
-
}
|
|
218
|
-
catch (error) {
|
|
219
|
-
logger.error(`Error reading file: ${error}`);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
const buildProfileJson = (0, json5parser_1.parseJsonText)(configurationsText);
|
|
223
|
-
const modules = buildProfileJson.modules;
|
|
224
|
-
if (modules instanceof Array) {
|
|
225
|
-
modules.forEach((module) => {
|
|
226
|
-
this.modulePath2NameMap.set(path_1.default.resolve(this.realProjectDir, path_1.default.join(module.srcPath)), module.name);
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
logger.warn('There is no build-profile.json5 for this project.');
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
parseOhPackage() {
|
|
235
|
-
const OhPkgFilePath = path_1.default.join(this.realProjectDir, EtsConst_1.OH_PACKAGE_JSON5);
|
|
236
|
-
if (fs_1.default.existsSync(OhPkgFilePath)) {
|
|
237
|
-
this.ohPkgFilePath = OhPkgFilePath;
|
|
238
|
-
this.ohPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(this.ohPkgFilePath);
|
|
239
|
-
this.ohPkgContentMap.set(OhPkgFilePath, this.ohPkgContent);
|
|
240
|
-
if (this.ohPkgContent.overrides) {
|
|
241
|
-
let overRides = this.ohPkgContent.overrides;
|
|
242
|
-
for (const [key, value] of Object.entries(overRides)) {
|
|
243
|
-
this.overRides.set(key, value);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
if (this.ohPkgContent.overrideDependencyMap) {
|
|
247
|
-
let globalOverRideDependencyMap = this.ohPkgContent.overrideDependencyMap;
|
|
248
|
-
for (const [key, value] of Object.entries(globalOverRideDependencyMap)) {
|
|
249
|
-
let globalDependency = (0, json5parser_1.fetchDependenciesFromFile)(value);
|
|
250
|
-
this.overRideDependencyMap.set(key, globalDependency);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
logger.warn('This project has no oh-package.json5!');
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
findTsConfigInfoDeeply(tsConfigObj, tsConfigFilePath) {
|
|
259
|
-
if (tsConfigObj.extends) {
|
|
260
|
-
const extTsConfigObj = (0, json5parser_1.fetchDependenciesFromFile)(path_1.default.join(path_1.default.dirname(tsConfigFilePath), tsConfigObj.extends));
|
|
261
|
-
this.findTsConfigInfoDeeply(extTsConfigObj, tsConfigFilePath);
|
|
262
|
-
if (!this.baseUrl && !this.globalModule2PathMapping) {
|
|
263
|
-
this.addTsConfigInfo(extTsConfigObj);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
if (!this.baseUrl && !this.globalModule2PathMapping) {
|
|
267
|
-
this.addTsConfigInfo(tsConfigObj);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
addTsConfigInfo(tsConfigObj) {
|
|
271
|
-
if (tsConfigObj.compilerOptions && tsConfigObj.compilerOptions.paths) {
|
|
272
|
-
const paths = tsConfigObj.compilerOptions.paths;
|
|
273
|
-
if (paths) {
|
|
274
|
-
this.globalModule2PathMapping = paths;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
if (tsConfigObj.compilerOptions && tsConfigObj.compilerOptions.baseUrl) {
|
|
278
|
-
this.baseUrl = tsConfigObj.compilerOptions.baseUrl;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
addDefaultConstructors() {
|
|
282
|
-
for (const file of this.getFiles()) {
|
|
283
|
-
for (const cls of ModelUtils_1.ModelUtils.getAllClassesInFile(file)) {
|
|
284
|
-
(0, ArkMethodBuilder_1.buildDefaultConstructor)(cls);
|
|
285
|
-
(0, ArkMethodBuilder_1.addInitInConstructor)(cls);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
buildAllMethodBody() {
|
|
290
|
-
this.buildStage = SceneBuildStage.CLASS_DONE;
|
|
291
|
-
for (const file of this.getFiles()) {
|
|
292
|
-
for (const cls of file.getClasses()) {
|
|
293
|
-
for (const method of cls.getMethods(true)) {
|
|
294
|
-
method.buildBody();
|
|
295
|
-
method.freeBodyBuilder();
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
for (const namespace of this.getNamespacesMap().values()) {
|
|
300
|
-
for (const cls of namespace.getClasses()) {
|
|
301
|
-
for (const method of cls.getMethods(true)) {
|
|
302
|
-
method.buildBody();
|
|
303
|
-
method.freeBodyBuilder();
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
this.buildStage = SceneBuildStage.METHOD_DONE;
|
|
308
|
-
}
|
|
309
|
-
genArkFiles() {
|
|
310
|
-
this.projectFiles.forEach((file) => {
|
|
311
|
-
logger.info('=== parse file:', file);
|
|
312
|
-
try {
|
|
313
|
-
const arkFile = new ArkFile_1.ArkFile();
|
|
314
|
-
arkFile.setScene(this);
|
|
315
|
-
(0, ArkFileBuilder_1.buildArkFileFromFile)(file, this.realProjectDir, arkFile, this.projectName);
|
|
316
|
-
this.filesMap.set(arkFile.getFileSignature().toMapKey(), arkFile);
|
|
317
|
-
}
|
|
318
|
-
catch (error) {
|
|
319
|
-
logger.error('Error parsing file:', file, error);
|
|
320
|
-
this.unhandledFilePaths.push(file);
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
this.buildAllMethodBody();
|
|
325
|
-
this.addDefaultConstructors();
|
|
326
|
-
}
|
|
327
|
-
getFilesOrderByDependency() {
|
|
328
|
-
for (const projectFile of this.projectFiles) {
|
|
329
|
-
this.getDependencyFilesDeeply(projectFile);
|
|
330
|
-
}
|
|
331
|
-
this.buildAllMethodBody();
|
|
332
|
-
this.addDefaultConstructors();
|
|
333
|
-
}
|
|
334
|
-
getDependencyFilesDeeply(projectFile) {
|
|
335
|
-
if (!this.options.supportFileExts.includes(path_1.default.extname(projectFile))) {
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
const fileSignature = new ArkSignature_1.FileSignature(this.getProjectName(), path_1.default.relative(this.getRealProjectDir(), projectFile));
|
|
339
|
-
if (this.filesMap.has(fileSignature.toMapKey()) || this.isRepeatBuildFile(projectFile)) {
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
try {
|
|
343
|
-
const arkFile = new ArkFile_1.ArkFile();
|
|
344
|
-
arkFile.setScene(this);
|
|
345
|
-
(0, ArkFileBuilder_1.buildArkFileFromFile)(projectFile, this.getRealProjectDir(), arkFile, this.getProjectName());
|
|
346
|
-
for (const [modulePath, moduleName] of this.modulePath2NameMap) {
|
|
347
|
-
if (arkFile.getFilePath().startsWith(modulePath)) {
|
|
348
|
-
this.addArkFile2ModuleScene(modulePath, moduleName, arkFile);
|
|
349
|
-
break;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
this.filesMap.set(arkFile.getFileSignature().toMapKey(), arkFile);
|
|
353
|
-
const importInfos = arkFile.getImportInfos();
|
|
354
|
-
const repeatFroms = [];
|
|
355
|
-
this.findDependencyFiles(importInfos, arkFile, repeatFroms);
|
|
356
|
-
const exportInfos = arkFile.getExportInfos();
|
|
357
|
-
this.findDependencyFiles(exportInfos, arkFile, repeatFroms);
|
|
358
|
-
}
|
|
359
|
-
catch (error) {
|
|
360
|
-
logger.error('Error parsing file:', projectFile, error);
|
|
361
|
-
this.unhandledFilePaths.push(projectFile);
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
isRepeatBuildFile(projectFile) {
|
|
366
|
-
for (const [key, file] of this.filesMap) {
|
|
367
|
-
if (key && file.getFilePath().toLowerCase() === projectFile.toLowerCase()) {
|
|
368
|
-
return true;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
return false;
|
|
372
|
-
}
|
|
373
|
-
addArkFile2ModuleScene(modulePath, moduleName, arkFile) {
|
|
374
|
-
if (this.moduleScenesMap.has(moduleName)) {
|
|
375
|
-
let curModuleScene = this.moduleScenesMap.get(moduleName);
|
|
376
|
-
if (curModuleScene) {
|
|
377
|
-
curModuleScene.addArkFile(arkFile);
|
|
378
|
-
arkFile.setModuleScene(curModuleScene);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
else {
|
|
382
|
-
let moduleScene = new ModuleScene(this);
|
|
383
|
-
moduleScene.ModuleScenePartiallyBuilder(moduleName, modulePath);
|
|
384
|
-
moduleScene.addArkFile(arkFile);
|
|
385
|
-
this.moduleScenesMap.set(moduleName, moduleScene);
|
|
386
|
-
arkFile.setModuleScene(moduleScene);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
findDependencyFiles(importOrExportInfos, arkFile, repeatFroms) {
|
|
390
|
-
for (const importOrExportInfo of importOrExportInfos) {
|
|
391
|
-
const from = importOrExportInfo.getFrom();
|
|
392
|
-
if (from && !repeatFroms.includes(from)) {
|
|
393
|
-
this.parseFrom(from, arkFile);
|
|
394
|
-
repeatFroms.push(from);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
parseFrom(from, arkFile) {
|
|
399
|
-
if (/^@[a-z|\-]+?\/?/.test(from)) {
|
|
400
|
-
for (const [ohPkgContentPath, ohPkgContent] of this.ohPkgContentMap) {
|
|
401
|
-
this.findDependenciesByOhPkg(ohPkgContentPath, ohPkgContent, from, arkFile);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
else if (/^([^@]*\/)([^\/]*)$/.test(from) || /^[\.\./|\.\.]+$/.test(from)) {
|
|
405
|
-
this.findRelativeDependenciesByOhPkg(from, arkFile);
|
|
406
|
-
}
|
|
407
|
-
else if (/^[@a-zA-Z0-9]+(\/[a-zA-Z0-9]+)*$/.test(from)) {
|
|
408
|
-
this.findDependenciesByTsConfig(from, arkFile);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
findDependenciesByTsConfig(from, arkFile) {
|
|
412
|
-
if (this.globalModule2PathMapping) {
|
|
413
|
-
const paths = this.globalModule2PathMapping;
|
|
414
|
-
Object.keys(paths).forEach((key) => this.parseTsConfigParms(paths, key, from, arkFile));
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
parseTsConfigParms(paths, key, from, arkFile) {
|
|
418
|
-
const module2pathMapping = paths[key];
|
|
419
|
-
if (key.includes(TSConst_1.ALL)) {
|
|
420
|
-
this.processFuzzyMapping(key, from, module2pathMapping, arkFile);
|
|
421
|
-
}
|
|
422
|
-
else if (from.startsWith(key)) {
|
|
423
|
-
let tail = from.substring(key.length, from.length);
|
|
424
|
-
module2pathMapping.forEach((pathMapping) => {
|
|
425
|
-
let originPath = path_1.default.join(this.getRealProjectDir(), pathMapping, tail);
|
|
426
|
-
if (this.baseUrl) {
|
|
427
|
-
originPath = path_1.default.resolve(this.baseUrl, originPath);
|
|
428
|
-
}
|
|
429
|
-
this.findDependenciesByRule(originPath, arkFile);
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
processFuzzyMapping(key, from, module2pathMapping, arkFile) {
|
|
434
|
-
key = key.substring(0, key.indexOf(TSConst_1.ALL) - 1);
|
|
435
|
-
if (from.substring(0, key.indexOf(TSConst_1.ALL) - 1) === key) {
|
|
436
|
-
let tail = from.substring(key.indexOf(TSConst_1.ALL) - 1, from.length);
|
|
437
|
-
module2pathMapping.forEach((pathMapping) => {
|
|
438
|
-
pathMapping = pathMapping.substring(0, pathMapping.indexOf(TSConst_1.ALL) - 1);
|
|
439
|
-
let originPath = path_1.default.join(this.getRealProjectDir(), pathMapping, tail);
|
|
440
|
-
if (this.baseUrl) {
|
|
441
|
-
originPath = path_1.default.join(this.baseUrl, originPath);
|
|
442
|
-
}
|
|
443
|
-
this.findDependenciesByRule(originPath, arkFile);
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
findDependenciesByRule(originPath, arkFile) {
|
|
448
|
-
const extNameArray = ['.ets', '.ts', '.d.ets', '.d.ts'];
|
|
449
|
-
if (!this.findFilesByPathArray(originPath, this.indexPathArray, arkFile) && !this.findFilesByExtNameArray(originPath, extNameArray, arkFile)) {
|
|
450
|
-
logger.info(originPath + 'module mapperInfo is not found!');
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
findFilesByPathArray(originPath, pathArray, arkFile) {
|
|
454
|
-
for (const pathInfo of pathArray) {
|
|
455
|
-
const curPath = path_1.default.join(originPath, pathInfo);
|
|
456
|
-
if (fs_1.default.existsSync(curPath) && !this.isRepeatBuildFile(curPath)) {
|
|
457
|
-
this.addFileNode2DependencyGrap(curPath, arkFile);
|
|
458
|
-
return true;
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
return false;
|
|
462
|
-
}
|
|
463
|
-
findFilesByExtNameArray(originPath, pathArray, arkFile) {
|
|
464
|
-
for (const pathInfo of pathArray) {
|
|
465
|
-
const curPath = originPath + pathInfo;
|
|
466
|
-
if (fs_1.default.existsSync(curPath) && !this.isRepeatBuildFile(curPath)) {
|
|
467
|
-
this.addFileNode2DependencyGrap(curPath, arkFile);
|
|
468
|
-
return true;
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
return false;
|
|
472
|
-
}
|
|
473
|
-
findRelativeDependenciesByOhPkg(from, arkFile) {
|
|
474
|
-
//relative path ../from ./from
|
|
475
|
-
//order
|
|
476
|
-
//1. ../from/oh-package.json5 -> [[name]] -> overRides/overRideDependencyMap? ->
|
|
477
|
-
//[[main]] -> file path ->dependencies(priority)+devDependencies? dynamicDependencies(not support) ->
|
|
478
|
-
//key overRides/overRideDependencyMap?
|
|
479
|
-
//2. ../from/index.ets(ts)
|
|
480
|
-
//3. ../from/index.d.ets(ts)
|
|
481
|
-
//4. ../from.ets(ts)
|
|
482
|
-
//5. ../from.d.ets(ts)
|
|
483
|
-
//2.3.4.5 random order
|
|
484
|
-
let originPath = this.getOriginPath(from, arkFile);
|
|
485
|
-
if (fs_1.default.existsSync(path_1.default.join(originPath, EtsConst_1.OH_PACKAGE_JSON5))) {
|
|
486
|
-
for (const [ohPkgContentPath, ohPkgContent] of this.ohPkgContentMap) {
|
|
487
|
-
this.findDependenciesByOhPkg(ohPkgContentPath, ohPkgContent, from, arkFile);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
this.findDependenciesByRule(originPath, arkFile);
|
|
491
|
-
}
|
|
492
|
-
findDependenciesByOhPkg(ohPkgContentPath, ohPkgContentInfo, from, arkFile) {
|
|
493
|
-
//module name @ohos/from
|
|
494
|
-
const ohPkgContent = ohPkgContentInfo;
|
|
495
|
-
//module main name is must be
|
|
496
|
-
if (ohPkgContent && ohPkgContent.name && from.startsWith(ohPkgContent.name.toString())) {
|
|
497
|
-
let originPath = ohPkgContentPath.toString().replace(EtsConst_1.OH_PACKAGE_JSON5, '');
|
|
498
|
-
if (ohPkgContent.main) {
|
|
499
|
-
originPath = path_1.default.join(ohPkgContentPath.toString().replace(EtsConst_1.OH_PACKAGE_JSON5, ''), ohPkgContent.main.toString());
|
|
500
|
-
if (ohPkgContent.dependencies) {
|
|
501
|
-
this.getDependenciesMapping(ohPkgContent.dependencies, ohPkgContentPath, from, arkFile);
|
|
502
|
-
}
|
|
503
|
-
else if (ohPkgContent.devDependencies) {
|
|
504
|
-
this.getDependenciesMapping(ohPkgContent.devDependencies, ohPkgContentPath, from, arkFile);
|
|
505
|
-
}
|
|
506
|
-
else if (ohPkgContent.dynamicDependencies) {
|
|
507
|
-
// dynamicDependencies not support
|
|
508
|
-
}
|
|
509
|
-
this.addFileNode2DependencyGrap(originPath, arkFile);
|
|
510
|
-
}
|
|
511
|
-
if (!this.findFilesByPathArray(originPath, this.indexPathArray, arkFile)) {
|
|
512
|
-
logger.info(originPath + 'module mapperInfo is not found!');
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
getDependenciesMapping(dependencies, ohPkgContentPath, from, arkFile) {
|
|
517
|
-
for (let [moduleName, modulePath] of Object.entries(dependencies)) {
|
|
518
|
-
logger.debug('dependencies:' + moduleName);
|
|
519
|
-
if (modulePath.startsWith('file:')) {
|
|
520
|
-
modulePath = modulePath.replace(/^file:/, '');
|
|
521
|
-
}
|
|
522
|
-
const innerOhpackagePath = path_1.default.join(ohPkgContentPath.replace(EtsConst_1.OH_PACKAGE_JSON5, ''), modulePath.toString(), EtsConst_1.OH_PACKAGE_JSON5);
|
|
523
|
-
if (!this.ohPkgContentMap.has(innerOhpackagePath)) {
|
|
524
|
-
const innerModuleOhPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(innerOhpackagePath);
|
|
525
|
-
this.findDependenciesByOhPkg(innerOhpackagePath, innerModuleOhPkgContent, from, arkFile);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
getOriginPath(from, arkFile) {
|
|
530
|
-
const parentPath = /^\.{1,2}\//.test(from) ? path_1.default.dirname(arkFile.getFilePath()) : arkFile.getProjectDir();
|
|
531
|
-
return path_1.default.resolve(parentPath, from);
|
|
532
|
-
}
|
|
533
|
-
addFileNode2DependencyGrap(filePath, arkFile) {
|
|
534
|
-
this.getDependencyFilesDeeply(filePath);
|
|
535
|
-
this.filesMap.set(arkFile.getFileSignature().toMapKey(), arkFile);
|
|
536
|
-
}
|
|
537
|
-
buildSdk(sdkName, sdkPath) {
|
|
538
|
-
const allFiles = (0, getAllFiles_1.getAllFiles)(sdkPath, this.options.supportFileExts, this.options.ignoreFileNames);
|
|
539
|
-
allFiles.forEach((file) => {
|
|
540
|
-
logger.info('=== parse sdk file:', file);
|
|
541
|
-
try {
|
|
542
|
-
const arkFile = new ArkFile_1.ArkFile();
|
|
543
|
-
arkFile.setScene(this);
|
|
544
|
-
(0, ArkFileBuilder_1.buildArkFileFromFile)(file, path_1.default.normalize(sdkPath), arkFile, sdkName);
|
|
545
|
-
ModelUtils_1.ModelUtils.getAllClassesInFile(arkFile).forEach(cls => {
|
|
546
|
-
var _a, _b;
|
|
547
|
-
(_a = cls.getDefaultArkMethod()) === null || _a === void 0 ? void 0 : _a.buildBody();
|
|
548
|
-
(_b = cls.getDefaultArkMethod()) === null || _b === void 0 ? void 0 : _b.freeBodyBuilder();
|
|
549
|
-
});
|
|
550
|
-
const fileSig = arkFile.getFileSignature().toMapKey();
|
|
551
|
-
this.sdkArkFilesMap.set(fileSig, arkFile);
|
|
552
|
-
SdkUtils_1.SdkUtils.buildGlobalMap(arkFile, this.sdkGlobalMap);
|
|
553
|
-
}
|
|
554
|
-
catch (error) {
|
|
555
|
-
logger.error('Error parsing file:', file, error);
|
|
556
|
-
this.unhandledSdkFilePaths.push(file);
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
/**
|
|
562
|
-
* Build the scene for harmony project. It resolves the file path of the project first, and then fetches
|
|
563
|
-
* dependencies from this file. Next, build a `ModuleScene` for this project to generate {@link ArkFile}. Finally,
|
|
564
|
-
* it build bodies of all methods, generate extended classes, and add DefaultConstructors.
|
|
565
|
-
*/
|
|
566
|
-
buildScene4HarmonyProject() {
|
|
567
|
-
this.buildOhPkgContentMap();
|
|
568
|
-
this.modulePath2NameMap.forEach((value, key) => {
|
|
569
|
-
let moduleScene = new ModuleScene(this);
|
|
570
|
-
moduleScene.ModuleSceneBuilder(value, key, this.options.supportFileExts);
|
|
571
|
-
this.moduleScenesMap.set(value, moduleScene);
|
|
572
|
-
});
|
|
573
|
-
(0, ModelUtils_1.initModulePathMap)(this.ohPkgContentMap);
|
|
574
|
-
this.buildAllMethodBody();
|
|
575
|
-
this.addDefaultConstructors();
|
|
576
|
-
}
|
|
577
|
-
buildOhPkgContentMap() {
|
|
578
|
-
this.modulePath2NameMap.forEach((value, key) => {
|
|
579
|
-
const moduleOhPkgFilePath = path_1.default.resolve(key, EtsConst_1.OH_PACKAGE_JSON5);
|
|
580
|
-
if (fs_1.default.existsSync(moduleOhPkgFilePath)) {
|
|
581
|
-
const moduleOhPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(moduleOhPkgFilePath);
|
|
582
|
-
this.ohPkgContentMap.set(moduleOhPkgFilePath, moduleOhPkgContent);
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
buildModuleScene(moduleName, modulePath, supportFileExts) {
|
|
587
|
-
if (this.moduleScenesMap.get(moduleName)) {
|
|
588
|
-
return;
|
|
589
|
-
}
|
|
590
|
-
// get oh-package.json5
|
|
591
|
-
const moduleOhPkgFilePath = path_1.default.resolve(this.realProjectDir, path_1.default.join(modulePath, EtsConst_1.OH_PACKAGE_JSON5));
|
|
592
|
-
if (fs_1.default.existsSync(moduleOhPkgFilePath)) {
|
|
593
|
-
const moduleOhPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(moduleOhPkgFilePath);
|
|
594
|
-
this.ohPkgContentMap.set(moduleOhPkgFilePath, moduleOhPkgContent);
|
|
595
|
-
}
|
|
596
|
-
else {
|
|
597
|
-
logger.warn('Module: ', moduleName, 'has no oh-package.json5.');
|
|
598
|
-
}
|
|
599
|
-
// parse moduleOhPkgContent, get dependencies and build dependent module
|
|
600
|
-
const moduleOhPkgContent = this.ohPkgContentMap.get(moduleOhPkgFilePath);
|
|
601
|
-
if (moduleOhPkgContent) {
|
|
602
|
-
if (moduleOhPkgContent.dependencies instanceof Object) {
|
|
603
|
-
this.processModuleOhPkgContent(moduleOhPkgContent.dependencies, moduleOhPkgFilePath, supportFileExts);
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
let moduleScene = new ModuleScene(this);
|
|
607
|
-
moduleScene.ModuleSceneBuilder(moduleName, modulePath, supportFileExts);
|
|
608
|
-
this.moduleScenesMap.set(moduleName, moduleScene);
|
|
609
|
-
this.buildAllMethodBody();
|
|
610
|
-
}
|
|
611
|
-
processModuleOhPkgContent(dependencies, moduleOhPkgFilePath, supportFileExts) {
|
|
612
|
-
Object.entries(dependencies).forEach(([k, v]) => {
|
|
613
|
-
const pattern = new RegExp('^(\\.\\.\\/\|\\.\\/)');
|
|
614
|
-
if (typeof (v) === 'string') {
|
|
615
|
-
let dependencyModulePath = '';
|
|
616
|
-
if (pattern.test(v)) {
|
|
617
|
-
dependencyModulePath = path_1.default.join(moduleOhPkgFilePath, v);
|
|
618
|
-
}
|
|
619
|
-
else if (v.startsWith('file:')) {
|
|
620
|
-
const dependencyFilePath = path_1.default.join(moduleOhPkgFilePath, v.replace(/^file:/, ''));
|
|
621
|
-
const dependencyOhPkgPath = (0, FileUtils_1.getFileRecursively)(path_1.default.dirname(dependencyFilePath), EtsConst_1.OH_PACKAGE_JSON5);
|
|
622
|
-
dependencyModulePath = path_1.default.dirname(dependencyOhPkgPath);
|
|
623
|
-
}
|
|
624
|
-
const dependencyModuleName = this.modulePath2NameMap.get(dependencyModulePath);
|
|
625
|
-
if (dependencyModuleName) {
|
|
626
|
-
this.buildModuleScene(dependencyModuleName, dependencyModulePath, supportFileExts);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
});
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Get the absolute path of current project.
|
|
633
|
-
* @returns The real project's directiory.
|
|
634
|
-
* @example
|
|
635
|
-
* 1. get real project directory, such as:
|
|
636
|
-
```typescript
|
|
637
|
-
let projectDir = projectScene.getRealProjectDir();
|
|
638
|
-
```
|
|
639
|
-
*/
|
|
640
|
-
getRealProjectDir() {
|
|
641
|
-
return this.realProjectDir;
|
|
642
|
-
}
|
|
643
|
-
/**
|
|
644
|
-
* Returns the **string** name of the project.
|
|
645
|
-
* @returns The name of the project.
|
|
646
|
-
*/
|
|
647
|
-
getProjectName() {
|
|
648
|
-
return this.projectName;
|
|
649
|
-
}
|
|
650
|
-
getProjectFiles() {
|
|
651
|
-
return this.projectFiles;
|
|
652
|
-
}
|
|
653
|
-
getSdkGlobal(globalName) {
|
|
654
|
-
return this.sdkGlobalMap.get(globalName) || null;
|
|
655
|
-
}
|
|
656
|
-
/**
|
|
657
|
-
* Returns the file based on its signature.
|
|
658
|
-
* If no file can be found according to the input signature, **null** will be returned.
|
|
659
|
-
* A typical {@link ArkFile} contains: file's name (i.e., its relative path), project's name,
|
|
660
|
-
* project's dir, file's signature etc.
|
|
661
|
-
* @param fileSignature - the signature of file.
|
|
662
|
-
* @returns a file defined by ArkAnalyzer. **null** will be returned if no file could be found.
|
|
663
|
-
* @example
|
|
664
|
-
* 1. get ArkFile based on file signature.
|
|
665
|
-
|
|
666
|
-
```typescript
|
|
667
|
-
if (...) {
|
|
668
|
-
const fromSignature = new FileSignature();
|
|
669
|
-
fromSignature.setProjectName(im.getDeclaringArkFile().getProjectName());
|
|
670
|
-
fromSignature.setFileName(fileName);
|
|
671
|
-
return scene.getFile(fromSignature);
|
|
672
|
-
}
|
|
673
|
-
```
|
|
674
|
-
*/
|
|
675
|
-
getFile(fileSignature) {
|
|
676
|
-
if (this.projectName === fileSignature.getProjectName()) {
|
|
677
|
-
return this.filesMap.get(fileSignature.toMapKey()) || null;
|
|
678
|
-
}
|
|
679
|
-
else {
|
|
680
|
-
return this.sdkArkFilesMap.get(fileSignature.toMapKey()) || null;
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
/*
|
|
684
|
-
* Returns the absolute file paths that cannot be handled currently.
|
|
685
|
-
*/
|
|
686
|
-
getUnhandledFilePaths() {
|
|
687
|
-
return this.unhandledFilePaths;
|
|
688
|
-
}
|
|
689
|
-
/*
|
|
690
|
-
* Returns the absolute sdk file paths that cannot be handled currently.
|
|
691
|
-
*/
|
|
692
|
-
getUnhandledSdkFilePaths() {
|
|
693
|
-
return this.unhandledSdkFilePaths;
|
|
694
|
-
}
|
|
695
|
-
setFile(file) {
|
|
696
|
-
this.filesMap.set(file.getFileSignature().toMapKey(), file);
|
|
697
|
-
}
|
|
698
|
-
hasSdkFile(fileSignature) {
|
|
699
|
-
return this.sdkArkFilesMap.has(fileSignature.toMapKey());
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* Get files of a {@link Scene}. Generally, a project includes several ets/ts files that define the different
|
|
703
|
-
* class. We need to generate {@link ArkFile} objects from these ets/ts files.
|
|
704
|
-
* @returns The array of {@link ArkFile} from `scene.filesMap.values()`.
|
|
705
|
-
* @example
|
|
706
|
-
* 1. In inferSimpleTypes() to check arkClass and arkMethod.
|
|
707
|
-
* ```typescript
|
|
708
|
-
* public inferSimpleTypes() {
|
|
709
|
-
* for (let arkFile of this.getFiles()) {
|
|
710
|
-
* for (let arkClass of arkFile.getClasses()) {
|
|
711
|
-
* for (let arkMethod of arkClass.getMethods()) {
|
|
712
|
-
* // ... ...;
|
|
713
|
-
* }
|
|
714
|
-
* }
|
|
715
|
-
* }
|
|
716
|
-
* }
|
|
717
|
-
* ```
|
|
718
|
-
* 2. To iterate each method
|
|
719
|
-
* ```typescript
|
|
720
|
-
* for (const file of this.getFiles()) {
|
|
721
|
-
* for (const cls of file.getClasses()) {
|
|
722
|
-
* for (const method of cls.getMethods()) {
|
|
723
|
-
* // ... ...
|
|
724
|
-
* }
|
|
725
|
-
* }
|
|
726
|
-
* }
|
|
727
|
-
*```
|
|
728
|
-
*/
|
|
729
|
-
getFiles() {
|
|
730
|
-
return Array.from(this.filesMap.values());
|
|
731
|
-
}
|
|
732
|
-
getSdkArkFiles() {
|
|
733
|
-
return Array.from(this.sdkArkFilesMap.values());
|
|
734
|
-
}
|
|
735
|
-
getModuleSdkMap() {
|
|
736
|
-
return this.moduleSdkMap;
|
|
737
|
-
}
|
|
738
|
-
getProjectSdkMap() {
|
|
739
|
-
return this.projectSdkMap;
|
|
740
|
-
}
|
|
741
|
-
getNamespace(namespaceSignature) {
|
|
742
|
-
const isProject = this.projectName === namespaceSignature.getDeclaringFileSignature().getProjectName();
|
|
743
|
-
let namespace;
|
|
744
|
-
if (isProject) {
|
|
745
|
-
namespace = this.namespacesMap.get(namespaceSignature.toMapKey());
|
|
746
|
-
}
|
|
747
|
-
if (namespace) {
|
|
748
|
-
return namespace;
|
|
749
|
-
}
|
|
750
|
-
namespace = this.getNamespaceBySignature(namespaceSignature);
|
|
751
|
-
if (isProject && namespace) {
|
|
752
|
-
this.namespacesMap.set(namespaceSignature.toMapKey(), namespace);
|
|
753
|
-
}
|
|
754
|
-
return namespace || null;
|
|
755
|
-
}
|
|
756
|
-
getNamespaceBySignature(signature) {
|
|
757
|
-
const parentSignature = signature.getDeclaringNamespaceSignature();
|
|
758
|
-
if (parentSignature) {
|
|
759
|
-
const parentNamespace = this.getNamespaceBySignature(parentSignature);
|
|
760
|
-
return (parentNamespace === null || parentNamespace === void 0 ? void 0 : parentNamespace.getNamespace(signature)) || null;
|
|
761
|
-
}
|
|
762
|
-
else {
|
|
763
|
-
const arkFile = this.getFile(signature.getDeclaringFileSignature());
|
|
764
|
-
return (arkFile === null || arkFile === void 0 ? void 0 : arkFile.getNamespace(signature)) || null;
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
getNamespacesMap() {
|
|
768
|
-
if (this.buildStage === SceneBuildStage.CLASS_DONE) {
|
|
769
|
-
for (const file of this.getFiles()) {
|
|
770
|
-
ModelUtils_1.ModelUtils.getAllNamespacesInFile(file).forEach((namespace) => {
|
|
771
|
-
this.namespacesMap.set(namespace.getNamespaceSignature().toMapKey(), namespace);
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
return this.namespacesMap;
|
|
776
|
-
}
|
|
777
|
-
getNamespaces() {
|
|
778
|
-
return Array.from(this.getNamespacesMap().values());
|
|
779
|
-
}
|
|
780
|
-
/**
|
|
781
|
-
* Returns the class according to the input class signature.
|
|
782
|
-
* @param classSignature - signature of the class to be obtained.
|
|
783
|
-
* @returns A class.
|
|
784
|
-
*/
|
|
785
|
-
getClass(classSignature) {
|
|
786
|
-
var _a;
|
|
787
|
-
const isProject = this.projectName === classSignature.getDeclaringFileSignature().getProjectName();
|
|
788
|
-
let arkClass;
|
|
789
|
-
if (isProject) {
|
|
790
|
-
arkClass = this.classesMap.get(classSignature.toMapKey());
|
|
791
|
-
}
|
|
792
|
-
if (arkClass) {
|
|
793
|
-
return arkClass;
|
|
794
|
-
}
|
|
795
|
-
const namespaceSignature = classSignature.getDeclaringNamespaceSignature();
|
|
796
|
-
if (namespaceSignature) {
|
|
797
|
-
arkClass = ((_a = this.getNamespaceBySignature(namespaceSignature)) === null || _a === void 0 ? void 0 : _a.getClass(classSignature)) || null;
|
|
798
|
-
}
|
|
799
|
-
else {
|
|
800
|
-
const arkFile = this.getFile(classSignature.getDeclaringFileSignature());
|
|
801
|
-
arkClass = arkFile === null || arkFile === void 0 ? void 0 : arkFile.getClass(classSignature);
|
|
802
|
-
}
|
|
803
|
-
if (isProject && arkClass) {
|
|
804
|
-
this.classesMap.set(classSignature.toMapKey(), arkClass);
|
|
805
|
-
}
|
|
806
|
-
return arkClass || null;
|
|
807
|
-
}
|
|
808
|
-
getClassesMap(refresh) {
|
|
809
|
-
if (refresh || this.buildStage === SceneBuildStage.METHOD_DONE) {
|
|
810
|
-
this.classesMap.clear();
|
|
811
|
-
for (const file of this.getFiles()) {
|
|
812
|
-
for (const cls of file.getClasses()) {
|
|
813
|
-
this.classesMap.set(cls.getSignature().toMapKey(), cls);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
for (const namespace of this.getNamespacesMap().values()) {
|
|
817
|
-
for (const cls of namespace.getClasses()) {
|
|
818
|
-
this.classesMap.set(cls.getSignature().toMapKey(), cls);
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
if (this.buildStage < SceneBuildStage.CLASS_COLLECTED) {
|
|
822
|
-
this.buildStage = SceneBuildStage.CLASS_COLLECTED;
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
return this.classesMap;
|
|
826
|
-
}
|
|
827
|
-
getClasses() {
|
|
828
|
-
return Array.from(this.getClassesMap().values());
|
|
829
|
-
}
|
|
830
|
-
getMethod(methodSignature, refresh) {
|
|
831
|
-
var _a;
|
|
832
|
-
const isProject = this.projectName === methodSignature.getDeclaringClassSignature().getDeclaringFileSignature().getProjectName();
|
|
833
|
-
let arkMethod;
|
|
834
|
-
if (isProject) {
|
|
835
|
-
arkMethod = this.methodsMap.get(methodSignature.toMapKey());
|
|
836
|
-
}
|
|
837
|
-
if (arkMethod) {
|
|
838
|
-
return arkMethod;
|
|
839
|
-
}
|
|
840
|
-
arkMethod = (_a = this.getClass(methodSignature.getDeclaringClassSignature())) === null || _a === void 0 ? void 0 : _a.getMethod(methodSignature);
|
|
841
|
-
if (isProject && arkMethod) {
|
|
842
|
-
this.methodsMap.set(methodSignature.toMapKey(), arkMethod);
|
|
843
|
-
}
|
|
844
|
-
return arkMethod || null;
|
|
845
|
-
}
|
|
846
|
-
getMethodsMap(refresh) {
|
|
847
|
-
if (refresh || (this.buildStage >= SceneBuildStage.METHOD_DONE && this.buildStage < SceneBuildStage.METHOD_COLLECTED)) {
|
|
848
|
-
this.methodsMap.clear();
|
|
849
|
-
for (const cls of this.getClassesMap(refresh).values()) {
|
|
850
|
-
for (const method of cls.getMethods(true)) {
|
|
851
|
-
this.methodsMap.set(method.getSignature().toMapKey(), method);
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
if (this.buildStage < SceneBuildStage.METHOD_COLLECTED) {
|
|
855
|
-
this.buildStage = SceneBuildStage.METHOD_COLLECTED;
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
return this.methodsMap;
|
|
859
|
-
}
|
|
860
|
-
/**
|
|
861
|
-
* Returns the method associated with the method signature.
|
|
862
|
-
* If no method is associated with this signature, **null** will be returned.
|
|
863
|
-
* An {@link ArkMethod} includes:
|
|
864
|
-
* - Name: the **string** name of method.
|
|
865
|
-
* - Code: the **string** code of the method.
|
|
866
|
-
* - Line: a **number** indicating the line location, initialized as -1.
|
|
867
|
-
* - Column: a **number** indicating the column location, initialized as -1.
|
|
868
|
-
* - Parameters & Types of parameters: the parameters of method and their types.
|
|
869
|
-
* - View tree: the view tree of the method.
|
|
870
|
-
* - ...
|
|
871
|
-
*
|
|
872
|
-
* @param methodSignature - the signature of method.
|
|
873
|
-
* @returns The method associated with the method signature.
|
|
874
|
-
* @example
|
|
875
|
-
* 1. get method from getMethod.
|
|
876
|
-
|
|
877
|
-
```typescript
|
|
878
|
-
const methodSignatures = this.CHA.resolveCall(xxx, yyy);
|
|
879
|
-
for (const methodSignature of methodSignatures) {
|
|
880
|
-
const method = this.scene.getMethod(methodSignature);
|
|
881
|
-
... ...
|
|
882
|
-
}
|
|
883
|
-
```
|
|
884
|
-
*/
|
|
885
|
-
getMethods() {
|
|
886
|
-
return Array.from(this.getMethodsMap().values());
|
|
887
|
-
}
|
|
888
|
-
addToMethodsMap(method) {
|
|
889
|
-
this.methodsMap.set(method.getSignature().toMapKey(), method);
|
|
890
|
-
}
|
|
891
|
-
removeMethod(method) {
|
|
892
|
-
return this.methodsMap.delete(method.getSignature().toMapKey());
|
|
893
|
-
}
|
|
894
|
-
removeClass(arkClass) {
|
|
895
|
-
return this.classesMap.delete(arkClass.getSignature().toMapKey());
|
|
896
|
-
}
|
|
897
|
-
removeNamespace(namespace) {
|
|
898
|
-
return this.namespacesMap.delete(namespace.getSignature().toMapKey());
|
|
899
|
-
}
|
|
900
|
-
removeFile(file) {
|
|
901
|
-
return this.filesMap.delete(file.getFileSignature().toMapKey());
|
|
902
|
-
}
|
|
903
|
-
hasMainMethod() {
|
|
904
|
-
return false;
|
|
905
|
-
}
|
|
906
|
-
//Get the set of entry points that are used to build the call graph.
|
|
907
|
-
getEntryPoints() {
|
|
908
|
-
return [];
|
|
909
|
-
}
|
|
910
|
-
/** get values that is visible in curr scope */
|
|
911
|
-
getVisibleValue() {
|
|
912
|
-
return this.visibleValue;
|
|
913
|
-
}
|
|
914
|
-
getOhPkgContent() {
|
|
915
|
-
return this.ohPkgContent;
|
|
916
|
-
}
|
|
917
|
-
getOhPkgContentMap() {
|
|
918
|
-
return this.ohPkgContentMap;
|
|
919
|
-
}
|
|
920
|
-
getOhPkgFilePath() {
|
|
921
|
-
return this.ohPkgFilePath;
|
|
922
|
-
}
|
|
923
|
-
makeCallGraphCHA(entryPoints) {
|
|
924
|
-
let callGraph = new CallGraph_1.CallGraph(this);
|
|
925
|
-
let callGraphBuilder = new CallGraphBuilder_1.CallGraphBuilder(callGraph, this);
|
|
926
|
-
callGraphBuilder.buildClassHierarchyCallGraph(entryPoints);
|
|
927
|
-
return callGraph;
|
|
928
|
-
}
|
|
929
|
-
makeCallGraphRTA(entryPoints) {
|
|
930
|
-
let callGraph = new CallGraph_1.CallGraph(this);
|
|
931
|
-
let callGraphBuilder = new CallGraphBuilder_1.CallGraphBuilder(callGraph, this);
|
|
932
|
-
callGraphBuilder.buildRapidTypeCallGraph(entryPoints);
|
|
933
|
-
return callGraph;
|
|
934
|
-
}
|
|
935
|
-
/**
|
|
936
|
-
* Infer type for each non-default method. It infers the type of each field/local/reference.
|
|
937
|
-
* For example, the statement `let b = 5;`, the type of local `b` is `NumberType`; and for the statement `let s =
|
|
938
|
-
* 'hello';`, the type of local `s` is `StringType`. The detailed types are defined in the Type.ts file.
|
|
939
|
-
* @example
|
|
940
|
-
* 1. Infer the type of each class field and method field.
|
|
941
|
-
```typescript
|
|
942
|
-
const scene = new Scene();
|
|
943
|
-
scene.buildSceneFromProjectDir(sceneConfig);
|
|
944
|
-
scene.inferTypes();
|
|
945
|
-
```
|
|
946
|
-
*/
|
|
947
|
-
inferTypes() {
|
|
948
|
-
if (this.buildStage < SceneBuildStage.SDK_INFERRED) {
|
|
949
|
-
this.sdkArkFilesMap.forEach(file => IRInference_1.IRInference.inferFile(file));
|
|
950
|
-
this.buildStage = SceneBuildStage.SDK_INFERRED;
|
|
951
|
-
}
|
|
952
|
-
this.filesMap.forEach(file => IRInference_1.IRInference.inferFile(file));
|
|
953
|
-
if (this.buildStage < SceneBuildStage.TYPE_INFERRED) {
|
|
954
|
-
this.getMethodsMap(true);
|
|
955
|
-
this.buildStage = SceneBuildStage.TYPE_INFERRED;
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
/**
|
|
959
|
-
* Iterate all assignment statements in methods,
|
|
960
|
-
* and set the type of left operand based on the type of right operand
|
|
961
|
-
* if the left operand is a local variable as well as an unknown.
|
|
962
|
-
* @Deprecated
|
|
963
|
-
* @example
|
|
964
|
-
* 1. Infer simple type when scene building.
|
|
965
|
-
|
|
966
|
-
```typescript
|
|
967
|
-
let scene = new Scene();
|
|
968
|
-
scene.buildSceneFromProjectDir(config);
|
|
969
|
-
scene.inferSimpleTypes();
|
|
970
|
-
```
|
|
971
|
-
*/
|
|
972
|
-
inferSimpleTypes() {
|
|
973
|
-
for (let arkFile of this.getFiles()) {
|
|
974
|
-
for (let arkClass of arkFile.getClasses()) {
|
|
975
|
-
for (let arkMethod of arkClass.getMethods()) {
|
|
976
|
-
TypeInference_1.TypeInference.inferSimpleTypeInMethod(arkMethod);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
getClassMap() {
|
|
982
|
-
var _a, _b, _c, _d;
|
|
983
|
-
const classMap = new Map();
|
|
984
|
-
for (const file of this.getFiles()) {
|
|
985
|
-
const fileClass = [];
|
|
986
|
-
const namespaceStack = [];
|
|
987
|
-
const parentMap = new Map();
|
|
988
|
-
const finalNamespaces = [];
|
|
989
|
-
for (const arkClass of file.getClasses()) {
|
|
990
|
-
fileClass.push(arkClass);
|
|
991
|
-
}
|
|
992
|
-
for (const ns of file.getNamespaces()) {
|
|
993
|
-
namespaceStack.push(ns);
|
|
994
|
-
parentMap.set(ns, file);
|
|
995
|
-
}
|
|
996
|
-
classMap.set(file.getFileSignature(), fileClass);
|
|
997
|
-
// 第一轮遍历,加上每个namespace自己的class
|
|
998
|
-
while (namespaceStack.length > 0) {
|
|
999
|
-
const ns = namespaceStack.shift();
|
|
1000
|
-
const nsClass = [];
|
|
1001
|
-
for (const arkClass of ns.getClasses()) {
|
|
1002
|
-
nsClass.push(arkClass);
|
|
1003
|
-
}
|
|
1004
|
-
classMap.set(ns.getNamespaceSignature(), nsClass);
|
|
1005
|
-
if (ns.getNamespaces().length === 0) {
|
|
1006
|
-
finalNamespaces.push(ns);
|
|
1007
|
-
}
|
|
1008
|
-
else {
|
|
1009
|
-
for (const nsns of ns.getNamespaces()) {
|
|
1010
|
-
namespaceStack.push(nsns);
|
|
1011
|
-
parentMap.set(nsns, ns);
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
// 第二轮遍历,父节点加上子节点的export的class
|
|
1016
|
-
while (finalNamespaces.length > 0) {
|
|
1017
|
-
const finalNS = finalNamespaces.shift();
|
|
1018
|
-
const exportClass = [];
|
|
1019
|
-
for (const arkClass of finalNS.getClasses()) {
|
|
1020
|
-
if (arkClass.isExported()) {
|
|
1021
|
-
exportClass.push(arkClass);
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
const parent = parentMap.get(finalNS);
|
|
1025
|
-
if (parent instanceof ArkNamespace_1.ArkNamespace) {
|
|
1026
|
-
(_a = classMap.get(parent.getNamespaceSignature())) === null || _a === void 0 ? void 0 : _a.push(...exportClass);
|
|
1027
|
-
}
|
|
1028
|
-
else if (parent instanceof ArkFile_1.ArkFile) {
|
|
1029
|
-
(_b = classMap.get(parent.getFileSignature())) === null || _b === void 0 ? void 0 : _b.push(...exportClass);
|
|
1030
|
-
}
|
|
1031
|
-
let p = finalNS;
|
|
1032
|
-
while (!(parentMap.get(p) instanceof ArkFile_1.ArkFile) && p.isExported()) {
|
|
1033
|
-
const grandParent = parentMap.get(parentMap.get(p));
|
|
1034
|
-
if (grandParent instanceof ArkNamespace_1.ArkNamespace) {
|
|
1035
|
-
(_c = classMap.get(grandParent.getNamespaceSignature())) === null || _c === void 0 ? void 0 : _c.push(...exportClass);
|
|
1036
|
-
p = parentMap.get(p);
|
|
1037
|
-
}
|
|
1038
|
-
else if (grandParent instanceof ArkFile_1.ArkFile) {
|
|
1039
|
-
(_d = classMap.get(grandParent.getFileSignature())) === null || _d === void 0 ? void 0 : _d.push(...exportClass);
|
|
1040
|
-
break;
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
if (parent instanceof ArkNamespace_1.ArkNamespace && !finalNamespaces.includes(parent)) {
|
|
1044
|
-
finalNamespaces.push(parent);
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
for (const file of this.getFiles()) {
|
|
1049
|
-
// 文件加上import的class,包括ns的
|
|
1050
|
-
const importClasses = [];
|
|
1051
|
-
const importNameSpaces = [];
|
|
1052
|
-
for (const importInfo of file.getImportInfos()) {
|
|
1053
|
-
const importClass = ModelUtils_1.ModelUtils.getClassInImportInfoWithName(importInfo.getImportClauseName(), file);
|
|
1054
|
-
if (importClass && !importClasses.includes(importClass)) {
|
|
1055
|
-
importClasses.push(importClass);
|
|
1056
|
-
continue;
|
|
1057
|
-
}
|
|
1058
|
-
const importNameSpace = ModelUtils_1.ModelUtils.getNamespaceInImportInfoWithName(importInfo.getImportClauseName(), file);
|
|
1059
|
-
if (importNameSpace && !importNameSpaces.includes(importNameSpace)) {
|
|
1060
|
-
try {
|
|
1061
|
-
// 遗留问题:只统计了项目文件的namespace,没统计sdk文件内部的引入
|
|
1062
|
-
const importNameSpaceClasses = classMap.get(importNameSpace.getNamespaceSignature());
|
|
1063
|
-
importClasses.push(...importNameSpaceClasses.filter(c => !importClasses.includes(c) && c.getName() !== Const_1.DEFAULT_ARK_CLASS_NAME));
|
|
1064
|
-
}
|
|
1065
|
-
catch (_e) {
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
const fileClasses = classMap.get(file.getFileSignature());
|
|
1070
|
-
fileClasses.push(...importClasses.filter(c => !fileClasses.includes(c)));
|
|
1071
|
-
// 子节点加上父节点的class
|
|
1072
|
-
const namespaceStack = [...file.getNamespaces()];
|
|
1073
|
-
for (const ns of namespaceStack) {
|
|
1074
|
-
const nsClasses = classMap.get(ns.getNamespaceSignature());
|
|
1075
|
-
nsClasses.push(...fileClasses.filter(c => !nsClasses.includes(c) && c.getName() !== Const_1.DEFAULT_ARK_CLASS_NAME));
|
|
1076
|
-
}
|
|
1077
|
-
while (namespaceStack.length > 0) {
|
|
1078
|
-
const ns = namespaceStack.shift();
|
|
1079
|
-
const nsClasses = classMap.get(ns.getNamespaceSignature());
|
|
1080
|
-
for (const nsns of ns.getNamespaces()) {
|
|
1081
|
-
const nsnsClasses = classMap.get(nsns.getNamespaceSignature());
|
|
1082
|
-
nsnsClasses.push(...nsClasses.filter(c => !nsnsClasses.includes(c) && c.getName() !== Const_1.DEFAULT_ARK_CLASS_NAME));
|
|
1083
|
-
namespaceStack.push(nsns);
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
return classMap;
|
|
1088
|
-
}
|
|
1089
|
-
getGlobalVariableMap() {
|
|
1090
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
1091
|
-
const globalVariableMap = new Map();
|
|
1092
|
-
for (const file of this.getFiles()) {
|
|
1093
|
-
const namespaceStack = [];
|
|
1094
|
-
const parentMap = new Map();
|
|
1095
|
-
const finalNamespaces = [];
|
|
1096
|
-
const globalLocals = [];
|
|
1097
|
-
(_b = (_a = file.getDefaultClass()) === null || _a === void 0 ? void 0 : _a.getDefaultArkMethod().getBody()) === null || _b === void 0 ? void 0 : _b.getLocals().forEach(local => {
|
|
1098
|
-
if (local.getDeclaringStmt() && local.getName() !== 'this' && local.getName()[0] !== '$') {
|
|
1099
|
-
globalLocals.push(local);
|
|
1100
|
-
}
|
|
1101
|
-
});
|
|
1102
|
-
globalVariableMap.set(file.getFileSignature(), globalLocals);
|
|
1103
|
-
for (const ns of file.getNamespaces()) {
|
|
1104
|
-
namespaceStack.push(ns);
|
|
1105
|
-
parentMap.set(ns, file);
|
|
1106
|
-
}
|
|
1107
|
-
// 第一轮遍历,加上每个namespace自己的local
|
|
1108
|
-
while (namespaceStack.length > 0) {
|
|
1109
|
-
const ns = namespaceStack.shift();
|
|
1110
|
-
const nsGlobalLocals = [];
|
|
1111
|
-
(_c = ns.getDefaultClass().getDefaultArkMethod().getBody()) === null || _c === void 0 ? void 0 : _c.getLocals().forEach(local => {
|
|
1112
|
-
if (local.getDeclaringStmt() && local.getName() !== 'this' && local.getName()[0] !== '$') {
|
|
1113
|
-
nsGlobalLocals.push(local);
|
|
1114
|
-
}
|
|
1115
|
-
});
|
|
1116
|
-
globalVariableMap.set(ns.getNamespaceSignature(), nsGlobalLocals);
|
|
1117
|
-
if (ns.getNamespaces().length === 0) {
|
|
1118
|
-
finalNamespaces.push(ns);
|
|
1119
|
-
}
|
|
1120
|
-
else {
|
|
1121
|
-
for (const nsns of ns.getNamespaces()) {
|
|
1122
|
-
namespaceStack.push(nsns);
|
|
1123
|
-
parentMap.set(nsns, ns);
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
// 第二轮遍历,父节点加上子节点的export的local
|
|
1128
|
-
while (finalNamespaces.length > 0) {
|
|
1129
|
-
const finalNS = finalNamespaces.shift();
|
|
1130
|
-
const exportLocal = [];
|
|
1131
|
-
for (const exportInfo of finalNS.getExportInfos()) {
|
|
1132
|
-
if (exportInfo.getExportClauseType() === ArkExport_1.ExportType.LOCAL && exportInfo.getArkExport()) {
|
|
1133
|
-
exportLocal.push(exportInfo.getArkExport());
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
const parent = parentMap.get(finalNS);
|
|
1137
|
-
if (parent instanceof ArkNamespace_1.ArkNamespace) {
|
|
1138
|
-
(_d = globalVariableMap.get(parent.getNamespaceSignature())) === null || _d === void 0 ? void 0 : _d.push(...exportLocal);
|
|
1139
|
-
}
|
|
1140
|
-
else if (parent instanceof ArkFile_1.ArkFile) {
|
|
1141
|
-
(_e = globalVariableMap.get(parent.getFileSignature())) === null || _e === void 0 ? void 0 : _e.push(...exportLocal);
|
|
1142
|
-
}
|
|
1143
|
-
let p = finalNS;
|
|
1144
|
-
while (!(parentMap.get(p) instanceof ArkFile_1.ArkFile) && p.isExported()) {
|
|
1145
|
-
const grandParent = parentMap.get(parentMap.get(p));
|
|
1146
|
-
if (grandParent instanceof ArkNamespace_1.ArkNamespace) {
|
|
1147
|
-
(_f = globalVariableMap.get(grandParent.getNamespaceSignature())) === null || _f === void 0 ? void 0 : _f.push(...exportLocal);
|
|
1148
|
-
p = parentMap.get(p);
|
|
1149
|
-
}
|
|
1150
|
-
else if (grandParent instanceof ArkFile_1.ArkFile) {
|
|
1151
|
-
(_g = globalVariableMap.get(grandParent.getFileSignature())) === null || _g === void 0 ? void 0 : _g.push(...exportLocal);
|
|
1152
|
-
break;
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
if (parent instanceof ArkNamespace_1.ArkNamespace && !finalNamespaces.includes(parent)) {
|
|
1156
|
-
finalNamespaces.push(parent);
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
for (const file of this.getFiles()) {
|
|
1161
|
-
// 文件加上import的local,包括ns的
|
|
1162
|
-
const importLocals = [];
|
|
1163
|
-
const importNameSpaces = [];
|
|
1164
|
-
for (const importInfo of file.getImportInfos()) {
|
|
1165
|
-
const importLocal = ModelUtils_1.ModelUtils.getLocalInImportInfoWithName(importInfo.getImportClauseName(), file);
|
|
1166
|
-
if (importLocal && !importLocals.includes(importLocal)) {
|
|
1167
|
-
importLocals.push(importLocal);
|
|
1168
|
-
}
|
|
1169
|
-
const importNameSpace = ModelUtils_1.ModelUtils.getNamespaceInImportInfoWithName(importInfo.getImportClauseName(), file);
|
|
1170
|
-
if (importNameSpace && !importNameSpaces.includes(importNameSpace)) {
|
|
1171
|
-
try {
|
|
1172
|
-
// 遗留问题:只统计了项目文件,没统计sdk文件内部的引入
|
|
1173
|
-
const importNameSpaceClasses = globalVariableMap.get(importNameSpace.getNamespaceSignature());
|
|
1174
|
-
importLocals.push(...importNameSpaceClasses.filter(c => !importLocals.includes(c) && c.getName() !== Const_1.DEFAULT_ARK_CLASS_NAME));
|
|
1175
|
-
}
|
|
1176
|
-
catch (_h) {
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
const fileLocals = globalVariableMap.get(file.getFileSignature());
|
|
1181
|
-
fileLocals.push(...importLocals.filter(c => !fileLocals.includes(c)));
|
|
1182
|
-
// 子节点加上父节点的local
|
|
1183
|
-
const namespaceStack = [...file.getNamespaces()];
|
|
1184
|
-
for (const ns of namespaceStack) {
|
|
1185
|
-
const nsLocals = globalVariableMap.get(ns.getNamespaceSignature());
|
|
1186
|
-
const nsLocalNameSet = new Set(nsLocals.map(item => item.getName()));
|
|
1187
|
-
for (const local of fileLocals) {
|
|
1188
|
-
if (!nsLocalNameSet.has(local.getName())) {
|
|
1189
|
-
nsLocals.push(local);
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
while (namespaceStack.length > 0) {
|
|
1194
|
-
const ns = namespaceStack.shift();
|
|
1195
|
-
const nsLocals = globalVariableMap.get(ns.getNamespaceSignature());
|
|
1196
|
-
for (const nsns of ns.getNamespaces()) {
|
|
1197
|
-
const nsnsLocals = globalVariableMap.get(nsns.getNamespaceSignature());
|
|
1198
|
-
const nsnsLocalNameSet = new Set(nsnsLocals.map(item => item.getName()));
|
|
1199
|
-
for (const local of nsLocals) {
|
|
1200
|
-
if (!nsnsLocalNameSet.has(local.getName())) {
|
|
1201
|
-
nsnsLocals.push(local);
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
namespaceStack.push(nsns);
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
return globalVariableMap;
|
|
1209
|
-
}
|
|
1210
|
-
getStaticInitMethods() {
|
|
1211
|
-
const staticInitMethods = [];
|
|
1212
|
-
for (const method of Array.from(this.getMethodsMap(true).values())) {
|
|
1213
|
-
if (method.getName() === Const_1.STATIC_INIT_METHOD_NAME) {
|
|
1214
|
-
staticInitMethods.push(method);
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
return staticInitMethods;
|
|
1218
|
-
}
|
|
1219
|
-
buildClassDone() {
|
|
1220
|
-
return this.buildStage >= SceneBuildStage.CLASS_DONE;
|
|
1221
|
-
}
|
|
1222
|
-
getModuleScene(moduleName) {
|
|
1223
|
-
return this.moduleScenesMap.get(moduleName);
|
|
1224
|
-
}
|
|
1225
|
-
getModuleSceneMap() {
|
|
1226
|
-
return this.moduleScenesMap;
|
|
1227
|
-
}
|
|
1228
|
-
getGlobalModule2PathMapping() {
|
|
1229
|
-
return this.globalModule2PathMapping;
|
|
1230
|
-
}
|
|
1231
|
-
getbaseUrl() {
|
|
1232
|
-
return this.baseUrl;
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
exports.Scene = Scene;
|
|
1236
|
-
class ModuleScene {
|
|
1237
|
-
constructor(projectScene) {
|
|
1238
|
-
this.moduleName = '';
|
|
1239
|
-
this.modulePath = '';
|
|
1240
|
-
this.moduleFileMap = new Map();
|
|
1241
|
-
this.moduleOhPkgFilePath = '';
|
|
1242
|
-
this.ohPkgContent = {};
|
|
1243
|
-
this.projectScene = projectScene;
|
|
1244
|
-
}
|
|
1245
|
-
ModuleSceneBuilder(moduleName, modulePath, supportFileExts, recursively = false) {
|
|
1246
|
-
this.moduleName = moduleName;
|
|
1247
|
-
this.modulePath = modulePath;
|
|
1248
|
-
this.getModuleOhPkgFilePath();
|
|
1249
|
-
if (this.moduleOhPkgFilePath) {
|
|
1250
|
-
this.ohPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(this.moduleOhPkgFilePath);
|
|
1251
|
-
}
|
|
1252
|
-
else {
|
|
1253
|
-
logger.warn('This module has no oh-package.json5!');
|
|
1254
|
-
}
|
|
1255
|
-
this.genArkFiles(supportFileExts);
|
|
1256
|
-
}
|
|
1257
|
-
ModuleScenePartiallyBuilder(moduleName, modulePath) {
|
|
1258
|
-
this.moduleName = moduleName;
|
|
1259
|
-
this.modulePath = modulePath;
|
|
1260
|
-
if (this.moduleOhPkgFilePath) {
|
|
1261
|
-
this.ohPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(this.moduleOhPkgFilePath);
|
|
1262
|
-
}
|
|
1263
|
-
else {
|
|
1264
|
-
logger.warn('This module has no oh-package.json5!');
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
/**
|
|
1268
|
-
* get oh-package.json5
|
|
1269
|
-
*/
|
|
1270
|
-
getModuleOhPkgFilePath() {
|
|
1271
|
-
const moduleOhPkgFilePath = path_1.default.resolve(this.projectScene.getRealProjectDir(), path_1.default.join(this.modulePath, EtsConst_1.OH_PACKAGE_JSON5));
|
|
1272
|
-
if (fs_1.default.existsSync(moduleOhPkgFilePath)) {
|
|
1273
|
-
this.moduleOhPkgFilePath = moduleOhPkgFilePath;
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
/**
|
|
1277
|
-
* get nodule name
|
|
1278
|
-
* @returns return module name
|
|
1279
|
-
*/
|
|
1280
|
-
getModuleName() {
|
|
1281
|
-
return this.moduleName;
|
|
1282
|
-
}
|
|
1283
|
-
getModulePath() {
|
|
1284
|
-
return this.modulePath;
|
|
1285
|
-
}
|
|
1286
|
-
getOhPkgFilePath() {
|
|
1287
|
-
return this.moduleOhPkgFilePath;
|
|
1288
|
-
}
|
|
1289
|
-
getOhPkgContent() {
|
|
1290
|
-
return this.ohPkgContent;
|
|
1291
|
-
}
|
|
1292
|
-
getModuleFilesMap() {
|
|
1293
|
-
return this.moduleFileMap;
|
|
1294
|
-
}
|
|
1295
|
-
addArkFile(arkFile) {
|
|
1296
|
-
this.moduleFileMap.set(arkFile.getFileSignature().toMapKey(), arkFile);
|
|
1297
|
-
}
|
|
1298
|
-
genArkFiles(supportFileExts) {
|
|
1299
|
-
(0, getAllFiles_1.getAllFiles)(this.modulePath, supportFileExts, this.projectScene.getOptions().ignoreFileNames).forEach((file) => {
|
|
1300
|
-
logger.info('=== parse file:', file);
|
|
1301
|
-
try {
|
|
1302
|
-
const arkFile = new ArkFile_1.ArkFile();
|
|
1303
|
-
arkFile.setScene(this.projectScene);
|
|
1304
|
-
arkFile.setModuleScene(this);
|
|
1305
|
-
(0, ArkFileBuilder_1.buildArkFileFromFile)(file, this.projectScene.getRealProjectDir(), arkFile, this.projectScene.getProjectName());
|
|
1306
|
-
this.projectScene.setFile(arkFile);
|
|
1307
|
-
}
|
|
1308
|
-
catch (error) {
|
|
1309
|
-
logger.error('Error parsing file:', file, error);
|
|
1310
|
-
this.projectScene.getUnhandledFilePaths().push(file);
|
|
1311
|
-
return;
|
|
1312
|
-
}
|
|
1313
|
-
});
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
exports.ModuleScene = ModuleScene;
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2024-2025 Huawei Device Co., Ltd.
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.ModuleScene = exports.Scene = void 0;
|
|
44
|
+
const fs_1 = __importDefault(require("fs"));
|
|
45
|
+
const path_1 = __importDefault(require("path"));
|
|
46
|
+
const ModelUtils_1 = require("./core/common/ModelUtils");
|
|
47
|
+
const TypeInference_1 = require("./core/common/TypeInference");
|
|
48
|
+
const VisibleValue_1 = require("./core/common/VisibleValue");
|
|
49
|
+
const ArkFile_1 = require("./core/model/ArkFile");
|
|
50
|
+
const ArkNamespace_1 = require("./core/model/ArkNamespace");
|
|
51
|
+
const ArkSignature_1 = require("./core/model/ArkSignature");
|
|
52
|
+
const logger_1 = __importStar(require("./utils/logger"));
|
|
53
|
+
const ArkFileBuilder_1 = require("./core/model/builder/ArkFileBuilder");
|
|
54
|
+
const json5parser_1 = require("./utils/json5parser");
|
|
55
|
+
const getAllFiles_1 = require("./utils/getAllFiles");
|
|
56
|
+
const FileUtils_1 = require("./utils/FileUtils");
|
|
57
|
+
const ArkExport_1 = require("./core/model/ArkExport");
|
|
58
|
+
const ArkMethodBuilder_1 = require("./core/model/builder/ArkMethodBuilder");
|
|
59
|
+
const Const_1 = require("./core/common/Const");
|
|
60
|
+
const CallGraph_1 = require("./callgraph/model/CallGraph");
|
|
61
|
+
const CallGraphBuilder_1 = require("./callgraph/model/builder/CallGraphBuilder");
|
|
62
|
+
const IRInference_1 = require("./core/common/IRInference");
|
|
63
|
+
const TSConst_1 = require("./core/common/TSConst");
|
|
64
|
+
const EtsConst_1 = require("./core/common/EtsConst");
|
|
65
|
+
const SdkUtils_1 = require("./core/common/SdkUtils");
|
|
66
|
+
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'Scene');
|
|
67
|
+
var SceneBuildStage;
|
|
68
|
+
(function (SceneBuildStage) {
|
|
69
|
+
SceneBuildStage[SceneBuildStage["BUILD_INIT"] = 0] = "BUILD_INIT";
|
|
70
|
+
SceneBuildStage[SceneBuildStage["CLASS_DONE"] = 1] = "CLASS_DONE";
|
|
71
|
+
SceneBuildStage[SceneBuildStage["METHOD_DONE"] = 2] = "METHOD_DONE";
|
|
72
|
+
SceneBuildStage[SceneBuildStage["CLASS_COLLECTED"] = 3] = "CLASS_COLLECTED";
|
|
73
|
+
SceneBuildStage[SceneBuildStage["METHOD_COLLECTED"] = 4] = "METHOD_COLLECTED";
|
|
74
|
+
SceneBuildStage[SceneBuildStage["SDK_INFERRED"] = 5] = "SDK_INFERRED";
|
|
75
|
+
SceneBuildStage[SceneBuildStage["TYPE_INFERRED"] = 6] = "TYPE_INFERRED";
|
|
76
|
+
})(SceneBuildStage || (SceneBuildStage = {}));
|
|
77
|
+
;
|
|
78
|
+
/**
|
|
79
|
+
* The Scene class includes everything in the analyzed project.
|
|
80
|
+
* We should be able to re-generate the project's code based on this class.
|
|
81
|
+
*/
|
|
82
|
+
class Scene {
|
|
83
|
+
constructor() {
|
|
84
|
+
this.projectName = '';
|
|
85
|
+
this.projectFiles = [];
|
|
86
|
+
this.realProjectDir = '';
|
|
87
|
+
this.moduleScenesMap = new Map();
|
|
88
|
+
this.modulePath2NameMap = new Map();
|
|
89
|
+
this.moduleSdkMap = new Map();
|
|
90
|
+
this.projectSdkMap = new Map();
|
|
91
|
+
// values that are visible in curr scope
|
|
92
|
+
this.visibleValue = new VisibleValue_1.VisibleValue();
|
|
93
|
+
// signature string to model
|
|
94
|
+
this.filesMap = new Map();
|
|
95
|
+
this.namespacesMap = new Map();
|
|
96
|
+
this.classesMap = new Map();
|
|
97
|
+
this.methodsMap = new Map();
|
|
98
|
+
// TODO: type of key should be signature object
|
|
99
|
+
this.sdkArkFilesMap = new Map();
|
|
100
|
+
this.sdkGlobalMap = new Map();
|
|
101
|
+
this.ohPkgContentMap = new Map();
|
|
102
|
+
this.ohPkgFilePath = '';
|
|
103
|
+
this.ohPkgContent = {};
|
|
104
|
+
this.overRides = new Map();
|
|
105
|
+
this.overRideDependencyMap = new Map();
|
|
106
|
+
this.buildStage = SceneBuildStage.BUILD_INIT;
|
|
107
|
+
this.indexPathArray = ['Index.ets', 'Index.ts', 'Index.d.ets', 'Index.d.ts', 'index.ets', 'index.ts', 'index.d.ets', 'index.d.ts'];
|
|
108
|
+
this.unhandledFilePaths = [];
|
|
109
|
+
this.unhandledSdkFilePaths = [];
|
|
110
|
+
}
|
|
111
|
+
getOptions() {
|
|
112
|
+
return this.options;
|
|
113
|
+
}
|
|
114
|
+
getOverRides() {
|
|
115
|
+
return this.overRides;
|
|
116
|
+
}
|
|
117
|
+
getOverRideDependencyMap() {
|
|
118
|
+
return this.overRideDependencyMap;
|
|
119
|
+
}
|
|
120
|
+
clear() {
|
|
121
|
+
this.projectFiles = [];
|
|
122
|
+
this.moduleScenesMap.clear();
|
|
123
|
+
this.modulePath2NameMap.clear();
|
|
124
|
+
this.moduleSdkMap.clear();
|
|
125
|
+
this.projectSdkMap.clear();
|
|
126
|
+
this.filesMap.clear();
|
|
127
|
+
this.namespacesMap.clear();
|
|
128
|
+
this.classesMap.clear();
|
|
129
|
+
this.methodsMap.clear();
|
|
130
|
+
this.sdkArkFilesMap.clear();
|
|
131
|
+
this.sdkGlobalMap.clear();
|
|
132
|
+
this.ohPkgContentMap.clear();
|
|
133
|
+
this.ohPkgContent = {};
|
|
134
|
+
}
|
|
135
|
+
getStage() {
|
|
136
|
+
return this.buildStage;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Build scene object according to the {@link SceneConfig}. This API implements 3 functions.
|
|
140
|
+
* First is to build scene object from {@link SceneConfig}, second is to generate {@link ArkFile}s,
|
|
141
|
+
* and the last is to collect project import infomation.
|
|
142
|
+
* @param sceneConfig - a sceneConfig object, which is usally defined by user or Json file.
|
|
143
|
+
* @example
|
|
144
|
+
* 1. Build Scene object from scene config
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
// build config
|
|
148
|
+
const projectDir = ... ...;
|
|
149
|
+
const sceneConfig = new SceneConfig();
|
|
150
|
+
sceneConfig.buildFromProjectDir(projectDir);
|
|
151
|
+
|
|
152
|
+
// build scene
|
|
153
|
+
const scene = new Scene();
|
|
154
|
+
scene.buildSceneFromProjectDir(sceneConfig);
|
|
155
|
+
```
|
|
156
|
+
*/
|
|
157
|
+
buildSceneFromProjectDir(sceneConfig) {
|
|
158
|
+
this.buildBasicInfo(sceneConfig);
|
|
159
|
+
this.genArkFiles();
|
|
160
|
+
}
|
|
161
|
+
buildSceneFromFiles(sceneConfig) {
|
|
162
|
+
this.buildBasicInfo(sceneConfig);
|
|
163
|
+
this.buildOhPkgContentMap();
|
|
164
|
+
(0, ModelUtils_1.initModulePathMap)(this.ohPkgContentMap);
|
|
165
|
+
this.getFilesOrderByDependency();
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Set the basic information of the scene using a config,
|
|
169
|
+
* such as the project's name, real path and files.
|
|
170
|
+
* @param sceneConfig - the config used to set the basic information of scene.
|
|
171
|
+
*/
|
|
172
|
+
buildBasicInfo(sceneConfig) {
|
|
173
|
+
var _a;
|
|
174
|
+
this.options = sceneConfig.getOptions();
|
|
175
|
+
this.projectName = sceneConfig.getTargetProjectName();
|
|
176
|
+
this.realProjectDir = fs_1.default.realpathSync(sceneConfig.getTargetProjectDirectory());
|
|
177
|
+
this.projectFiles = sceneConfig.getProjectFiles();
|
|
178
|
+
this.parseBuildProfile();
|
|
179
|
+
this.parseOhPackage();
|
|
180
|
+
let tsConfigFilePath;
|
|
181
|
+
if (this.options.tsconfig) {
|
|
182
|
+
tsConfigFilePath = path_1.default.join(sceneConfig.getTargetProjectDirectory(), this.options.tsconfig);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
tsConfigFilePath = path_1.default.join(sceneConfig.getTargetProjectDirectory(), TSConst_1.TSCONFIG_JSON);
|
|
186
|
+
}
|
|
187
|
+
if (fs_1.default.existsSync(tsConfigFilePath)) {
|
|
188
|
+
const tsConfigObj = (0, json5parser_1.fetchDependenciesFromFile)(tsConfigFilePath);
|
|
189
|
+
this.findTsConfigInfoDeeply(tsConfigObj, tsConfigFilePath);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
logger.warn('This project has no tsconfig.json!');
|
|
193
|
+
}
|
|
194
|
+
// handle sdks
|
|
195
|
+
(_a = sceneConfig.getSdksObj()) === null || _a === void 0 ? void 0 : _a.forEach((sdk) => {
|
|
196
|
+
if (!sdk.moduleName) {
|
|
197
|
+
this.buildSdk(sdk.name, sdk.path);
|
|
198
|
+
this.projectSdkMap.set(sdk.name, sdk);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
let moduleSdks = this.moduleSdkMap.get(sdk.moduleName);
|
|
202
|
+
if (moduleSdks) {
|
|
203
|
+
moduleSdks.push(sdk);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
this.moduleSdkMap.set(sdk.moduleName, [sdk]);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
parseBuildProfile() {
|
|
212
|
+
const buildProfile = path_1.default.join(this.realProjectDir, EtsConst_1.BUILD_PROFILE_JSON5);
|
|
213
|
+
if (fs_1.default.existsSync(buildProfile)) {
|
|
214
|
+
let configurationsText;
|
|
215
|
+
try {
|
|
216
|
+
configurationsText = fs_1.default.readFileSync(buildProfile, 'utf-8');
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
logger.error(`Error reading file: ${error}`);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const buildProfileJson = (0, json5parser_1.parseJsonText)(configurationsText);
|
|
223
|
+
const modules = buildProfileJson.modules;
|
|
224
|
+
if (modules instanceof Array) {
|
|
225
|
+
modules.forEach((module) => {
|
|
226
|
+
this.modulePath2NameMap.set(path_1.default.resolve(this.realProjectDir, path_1.default.join(module.srcPath)), module.name);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
logger.warn('There is no build-profile.json5 for this project.');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
parseOhPackage() {
|
|
235
|
+
const OhPkgFilePath = path_1.default.join(this.realProjectDir, EtsConst_1.OH_PACKAGE_JSON5);
|
|
236
|
+
if (fs_1.default.existsSync(OhPkgFilePath)) {
|
|
237
|
+
this.ohPkgFilePath = OhPkgFilePath;
|
|
238
|
+
this.ohPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(this.ohPkgFilePath);
|
|
239
|
+
this.ohPkgContentMap.set(OhPkgFilePath, this.ohPkgContent);
|
|
240
|
+
if (this.ohPkgContent.overrides) {
|
|
241
|
+
let overRides = this.ohPkgContent.overrides;
|
|
242
|
+
for (const [key, value] of Object.entries(overRides)) {
|
|
243
|
+
this.overRides.set(key, value);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (this.ohPkgContent.overrideDependencyMap) {
|
|
247
|
+
let globalOverRideDependencyMap = this.ohPkgContent.overrideDependencyMap;
|
|
248
|
+
for (const [key, value] of Object.entries(globalOverRideDependencyMap)) {
|
|
249
|
+
let globalDependency = (0, json5parser_1.fetchDependenciesFromFile)(value);
|
|
250
|
+
this.overRideDependencyMap.set(key, globalDependency);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
logger.warn('This project has no oh-package.json5!');
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
findTsConfigInfoDeeply(tsConfigObj, tsConfigFilePath) {
|
|
259
|
+
if (tsConfigObj.extends) {
|
|
260
|
+
const extTsConfigObj = (0, json5parser_1.fetchDependenciesFromFile)(path_1.default.join(path_1.default.dirname(tsConfigFilePath), tsConfigObj.extends));
|
|
261
|
+
this.findTsConfigInfoDeeply(extTsConfigObj, tsConfigFilePath);
|
|
262
|
+
if (!this.baseUrl && !this.globalModule2PathMapping) {
|
|
263
|
+
this.addTsConfigInfo(extTsConfigObj);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (!this.baseUrl && !this.globalModule2PathMapping) {
|
|
267
|
+
this.addTsConfigInfo(tsConfigObj);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
addTsConfigInfo(tsConfigObj) {
|
|
271
|
+
if (tsConfigObj.compilerOptions && tsConfigObj.compilerOptions.paths) {
|
|
272
|
+
const paths = tsConfigObj.compilerOptions.paths;
|
|
273
|
+
if (paths) {
|
|
274
|
+
this.globalModule2PathMapping = paths;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (tsConfigObj.compilerOptions && tsConfigObj.compilerOptions.baseUrl) {
|
|
278
|
+
this.baseUrl = tsConfigObj.compilerOptions.baseUrl;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
addDefaultConstructors() {
|
|
282
|
+
for (const file of this.getFiles()) {
|
|
283
|
+
for (const cls of ModelUtils_1.ModelUtils.getAllClassesInFile(file)) {
|
|
284
|
+
(0, ArkMethodBuilder_1.buildDefaultConstructor)(cls);
|
|
285
|
+
(0, ArkMethodBuilder_1.addInitInConstructor)(cls);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
buildAllMethodBody() {
|
|
290
|
+
this.buildStage = SceneBuildStage.CLASS_DONE;
|
|
291
|
+
for (const file of this.getFiles()) {
|
|
292
|
+
for (const cls of file.getClasses()) {
|
|
293
|
+
for (const method of cls.getMethods(true)) {
|
|
294
|
+
method.buildBody();
|
|
295
|
+
method.freeBodyBuilder();
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
for (const namespace of this.getNamespacesMap().values()) {
|
|
300
|
+
for (const cls of namespace.getClasses()) {
|
|
301
|
+
for (const method of cls.getMethods(true)) {
|
|
302
|
+
method.buildBody();
|
|
303
|
+
method.freeBodyBuilder();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
this.buildStage = SceneBuildStage.METHOD_DONE;
|
|
308
|
+
}
|
|
309
|
+
genArkFiles() {
|
|
310
|
+
this.projectFiles.forEach((file) => {
|
|
311
|
+
logger.info('=== parse file:', file);
|
|
312
|
+
try {
|
|
313
|
+
const arkFile = new ArkFile_1.ArkFile();
|
|
314
|
+
arkFile.setScene(this);
|
|
315
|
+
(0, ArkFileBuilder_1.buildArkFileFromFile)(file, this.realProjectDir, arkFile, this.projectName);
|
|
316
|
+
this.filesMap.set(arkFile.getFileSignature().toMapKey(), arkFile);
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
logger.error('Error parsing file:', file, error);
|
|
320
|
+
this.unhandledFilePaths.push(file);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
this.buildAllMethodBody();
|
|
325
|
+
this.addDefaultConstructors();
|
|
326
|
+
}
|
|
327
|
+
getFilesOrderByDependency() {
|
|
328
|
+
for (const projectFile of this.projectFiles) {
|
|
329
|
+
this.getDependencyFilesDeeply(projectFile);
|
|
330
|
+
}
|
|
331
|
+
this.buildAllMethodBody();
|
|
332
|
+
this.addDefaultConstructors();
|
|
333
|
+
}
|
|
334
|
+
getDependencyFilesDeeply(projectFile) {
|
|
335
|
+
if (!this.options.supportFileExts.includes(path_1.default.extname(projectFile))) {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
const fileSignature = new ArkSignature_1.FileSignature(this.getProjectName(), path_1.default.relative(this.getRealProjectDir(), projectFile));
|
|
339
|
+
if (this.filesMap.has(fileSignature.toMapKey()) || this.isRepeatBuildFile(projectFile)) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
const arkFile = new ArkFile_1.ArkFile();
|
|
344
|
+
arkFile.setScene(this);
|
|
345
|
+
(0, ArkFileBuilder_1.buildArkFileFromFile)(projectFile, this.getRealProjectDir(), arkFile, this.getProjectName());
|
|
346
|
+
for (const [modulePath, moduleName] of this.modulePath2NameMap) {
|
|
347
|
+
if (arkFile.getFilePath().startsWith(modulePath)) {
|
|
348
|
+
this.addArkFile2ModuleScene(modulePath, moduleName, arkFile);
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
this.filesMap.set(arkFile.getFileSignature().toMapKey(), arkFile);
|
|
353
|
+
const importInfos = arkFile.getImportInfos();
|
|
354
|
+
const repeatFroms = [];
|
|
355
|
+
this.findDependencyFiles(importInfos, arkFile, repeatFroms);
|
|
356
|
+
const exportInfos = arkFile.getExportInfos();
|
|
357
|
+
this.findDependencyFiles(exportInfos, arkFile, repeatFroms);
|
|
358
|
+
}
|
|
359
|
+
catch (error) {
|
|
360
|
+
logger.error('Error parsing file:', projectFile, error);
|
|
361
|
+
this.unhandledFilePaths.push(projectFile);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
isRepeatBuildFile(projectFile) {
|
|
366
|
+
for (const [key, file] of this.filesMap) {
|
|
367
|
+
if (key && file.getFilePath().toLowerCase() === projectFile.toLowerCase()) {
|
|
368
|
+
return true;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
addArkFile2ModuleScene(modulePath, moduleName, arkFile) {
|
|
374
|
+
if (this.moduleScenesMap.has(moduleName)) {
|
|
375
|
+
let curModuleScene = this.moduleScenesMap.get(moduleName);
|
|
376
|
+
if (curModuleScene) {
|
|
377
|
+
curModuleScene.addArkFile(arkFile);
|
|
378
|
+
arkFile.setModuleScene(curModuleScene);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
let moduleScene = new ModuleScene(this);
|
|
383
|
+
moduleScene.ModuleScenePartiallyBuilder(moduleName, modulePath);
|
|
384
|
+
moduleScene.addArkFile(arkFile);
|
|
385
|
+
this.moduleScenesMap.set(moduleName, moduleScene);
|
|
386
|
+
arkFile.setModuleScene(moduleScene);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
findDependencyFiles(importOrExportInfos, arkFile, repeatFroms) {
|
|
390
|
+
for (const importOrExportInfo of importOrExportInfos) {
|
|
391
|
+
const from = importOrExportInfo.getFrom();
|
|
392
|
+
if (from && !repeatFroms.includes(from)) {
|
|
393
|
+
this.parseFrom(from, arkFile);
|
|
394
|
+
repeatFroms.push(from);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
parseFrom(from, arkFile) {
|
|
399
|
+
if (/^@[a-z|\-]+?\/?/.test(from)) {
|
|
400
|
+
for (const [ohPkgContentPath, ohPkgContent] of this.ohPkgContentMap) {
|
|
401
|
+
this.findDependenciesByOhPkg(ohPkgContentPath, ohPkgContent, from, arkFile);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
else if (/^([^@]*\/)([^\/]*)$/.test(from) || /^[\.\./|\.\.]+$/.test(from)) {
|
|
405
|
+
this.findRelativeDependenciesByOhPkg(from, arkFile);
|
|
406
|
+
}
|
|
407
|
+
else if (/^[@a-zA-Z0-9]+(\/[a-zA-Z0-9]+)*$/.test(from)) {
|
|
408
|
+
this.findDependenciesByTsConfig(from, arkFile);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
findDependenciesByTsConfig(from, arkFile) {
|
|
412
|
+
if (this.globalModule2PathMapping) {
|
|
413
|
+
const paths = this.globalModule2PathMapping;
|
|
414
|
+
Object.keys(paths).forEach((key) => this.parseTsConfigParms(paths, key, from, arkFile));
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
parseTsConfigParms(paths, key, from, arkFile) {
|
|
418
|
+
const module2pathMapping = paths[key];
|
|
419
|
+
if (key.includes(TSConst_1.ALL)) {
|
|
420
|
+
this.processFuzzyMapping(key, from, module2pathMapping, arkFile);
|
|
421
|
+
}
|
|
422
|
+
else if (from.startsWith(key)) {
|
|
423
|
+
let tail = from.substring(key.length, from.length);
|
|
424
|
+
module2pathMapping.forEach((pathMapping) => {
|
|
425
|
+
let originPath = path_1.default.join(this.getRealProjectDir(), pathMapping, tail);
|
|
426
|
+
if (this.baseUrl) {
|
|
427
|
+
originPath = path_1.default.resolve(this.baseUrl, originPath);
|
|
428
|
+
}
|
|
429
|
+
this.findDependenciesByRule(originPath, arkFile);
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
processFuzzyMapping(key, from, module2pathMapping, arkFile) {
|
|
434
|
+
key = key.substring(0, key.indexOf(TSConst_1.ALL) - 1);
|
|
435
|
+
if (from.substring(0, key.indexOf(TSConst_1.ALL) - 1) === key) {
|
|
436
|
+
let tail = from.substring(key.indexOf(TSConst_1.ALL) - 1, from.length);
|
|
437
|
+
module2pathMapping.forEach((pathMapping) => {
|
|
438
|
+
pathMapping = pathMapping.substring(0, pathMapping.indexOf(TSConst_1.ALL) - 1);
|
|
439
|
+
let originPath = path_1.default.join(this.getRealProjectDir(), pathMapping, tail);
|
|
440
|
+
if (this.baseUrl) {
|
|
441
|
+
originPath = path_1.default.join(this.baseUrl, originPath);
|
|
442
|
+
}
|
|
443
|
+
this.findDependenciesByRule(originPath, arkFile);
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
findDependenciesByRule(originPath, arkFile) {
|
|
448
|
+
const extNameArray = ['.ets', '.ts', '.d.ets', '.d.ts'];
|
|
449
|
+
if (!this.findFilesByPathArray(originPath, this.indexPathArray, arkFile) && !this.findFilesByExtNameArray(originPath, extNameArray, arkFile)) {
|
|
450
|
+
logger.info(originPath + 'module mapperInfo is not found!');
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
findFilesByPathArray(originPath, pathArray, arkFile) {
|
|
454
|
+
for (const pathInfo of pathArray) {
|
|
455
|
+
const curPath = path_1.default.join(originPath, pathInfo);
|
|
456
|
+
if (fs_1.default.existsSync(curPath) && !this.isRepeatBuildFile(curPath)) {
|
|
457
|
+
this.addFileNode2DependencyGrap(curPath, arkFile);
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
findFilesByExtNameArray(originPath, pathArray, arkFile) {
|
|
464
|
+
for (const pathInfo of pathArray) {
|
|
465
|
+
const curPath = originPath + pathInfo;
|
|
466
|
+
if (fs_1.default.existsSync(curPath) && !this.isRepeatBuildFile(curPath)) {
|
|
467
|
+
this.addFileNode2DependencyGrap(curPath, arkFile);
|
|
468
|
+
return true;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
findRelativeDependenciesByOhPkg(from, arkFile) {
|
|
474
|
+
//relative path ../from ./from
|
|
475
|
+
//order
|
|
476
|
+
//1. ../from/oh-package.json5 -> [[name]] -> overRides/overRideDependencyMap? ->
|
|
477
|
+
//[[main]] -> file path ->dependencies(priority)+devDependencies? dynamicDependencies(not support) ->
|
|
478
|
+
//key overRides/overRideDependencyMap?
|
|
479
|
+
//2. ../from/index.ets(ts)
|
|
480
|
+
//3. ../from/index.d.ets(ts)
|
|
481
|
+
//4. ../from.ets(ts)
|
|
482
|
+
//5. ../from.d.ets(ts)
|
|
483
|
+
//2.3.4.5 random order
|
|
484
|
+
let originPath = this.getOriginPath(from, arkFile);
|
|
485
|
+
if (fs_1.default.existsSync(path_1.default.join(originPath, EtsConst_1.OH_PACKAGE_JSON5))) {
|
|
486
|
+
for (const [ohPkgContentPath, ohPkgContent] of this.ohPkgContentMap) {
|
|
487
|
+
this.findDependenciesByOhPkg(ohPkgContentPath, ohPkgContent, from, arkFile);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
this.findDependenciesByRule(originPath, arkFile);
|
|
491
|
+
}
|
|
492
|
+
findDependenciesByOhPkg(ohPkgContentPath, ohPkgContentInfo, from, arkFile) {
|
|
493
|
+
//module name @ohos/from
|
|
494
|
+
const ohPkgContent = ohPkgContentInfo;
|
|
495
|
+
//module main name is must be
|
|
496
|
+
if (ohPkgContent && ohPkgContent.name && from.startsWith(ohPkgContent.name.toString())) {
|
|
497
|
+
let originPath = ohPkgContentPath.toString().replace(EtsConst_1.OH_PACKAGE_JSON5, '');
|
|
498
|
+
if (ohPkgContent.main) {
|
|
499
|
+
originPath = path_1.default.join(ohPkgContentPath.toString().replace(EtsConst_1.OH_PACKAGE_JSON5, ''), ohPkgContent.main.toString());
|
|
500
|
+
if (ohPkgContent.dependencies) {
|
|
501
|
+
this.getDependenciesMapping(ohPkgContent.dependencies, ohPkgContentPath, from, arkFile);
|
|
502
|
+
}
|
|
503
|
+
else if (ohPkgContent.devDependencies) {
|
|
504
|
+
this.getDependenciesMapping(ohPkgContent.devDependencies, ohPkgContentPath, from, arkFile);
|
|
505
|
+
}
|
|
506
|
+
else if (ohPkgContent.dynamicDependencies) {
|
|
507
|
+
// dynamicDependencies not support
|
|
508
|
+
}
|
|
509
|
+
this.addFileNode2DependencyGrap(originPath, arkFile);
|
|
510
|
+
}
|
|
511
|
+
if (!this.findFilesByPathArray(originPath, this.indexPathArray, arkFile)) {
|
|
512
|
+
logger.info(originPath + 'module mapperInfo is not found!');
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
getDependenciesMapping(dependencies, ohPkgContentPath, from, arkFile) {
|
|
517
|
+
for (let [moduleName, modulePath] of Object.entries(dependencies)) {
|
|
518
|
+
logger.debug('dependencies:' + moduleName);
|
|
519
|
+
if (modulePath.startsWith('file:')) {
|
|
520
|
+
modulePath = modulePath.replace(/^file:/, '');
|
|
521
|
+
}
|
|
522
|
+
const innerOhpackagePath = path_1.default.join(ohPkgContentPath.replace(EtsConst_1.OH_PACKAGE_JSON5, ''), modulePath.toString(), EtsConst_1.OH_PACKAGE_JSON5);
|
|
523
|
+
if (!this.ohPkgContentMap.has(innerOhpackagePath)) {
|
|
524
|
+
const innerModuleOhPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(innerOhpackagePath);
|
|
525
|
+
this.findDependenciesByOhPkg(innerOhpackagePath, innerModuleOhPkgContent, from, arkFile);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
getOriginPath(from, arkFile) {
|
|
530
|
+
const parentPath = /^\.{1,2}\//.test(from) ? path_1.default.dirname(arkFile.getFilePath()) : arkFile.getProjectDir();
|
|
531
|
+
return path_1.default.resolve(parentPath, from);
|
|
532
|
+
}
|
|
533
|
+
addFileNode2DependencyGrap(filePath, arkFile) {
|
|
534
|
+
this.getDependencyFilesDeeply(filePath);
|
|
535
|
+
this.filesMap.set(arkFile.getFileSignature().toMapKey(), arkFile);
|
|
536
|
+
}
|
|
537
|
+
buildSdk(sdkName, sdkPath) {
|
|
538
|
+
const allFiles = (0, getAllFiles_1.getAllFiles)(sdkPath, this.options.supportFileExts, this.options.ignoreFileNames);
|
|
539
|
+
allFiles.forEach((file) => {
|
|
540
|
+
logger.info('=== parse sdk file:', file);
|
|
541
|
+
try {
|
|
542
|
+
const arkFile = new ArkFile_1.ArkFile();
|
|
543
|
+
arkFile.setScene(this);
|
|
544
|
+
(0, ArkFileBuilder_1.buildArkFileFromFile)(file, path_1.default.normalize(sdkPath), arkFile, sdkName);
|
|
545
|
+
ModelUtils_1.ModelUtils.getAllClassesInFile(arkFile).forEach(cls => {
|
|
546
|
+
var _a, _b;
|
|
547
|
+
(_a = cls.getDefaultArkMethod()) === null || _a === void 0 ? void 0 : _a.buildBody();
|
|
548
|
+
(_b = cls.getDefaultArkMethod()) === null || _b === void 0 ? void 0 : _b.freeBodyBuilder();
|
|
549
|
+
});
|
|
550
|
+
const fileSig = arkFile.getFileSignature().toMapKey();
|
|
551
|
+
this.sdkArkFilesMap.set(fileSig, arkFile);
|
|
552
|
+
SdkUtils_1.SdkUtils.buildGlobalMap(arkFile, this.sdkGlobalMap);
|
|
553
|
+
}
|
|
554
|
+
catch (error) {
|
|
555
|
+
logger.error('Error parsing file:', file, error);
|
|
556
|
+
this.unhandledSdkFilePaths.push(file);
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Build the scene for harmony project. It resolves the file path of the project first, and then fetches
|
|
563
|
+
* dependencies from this file. Next, build a `ModuleScene` for this project to generate {@link ArkFile}. Finally,
|
|
564
|
+
* it build bodies of all methods, generate extended classes, and add DefaultConstructors.
|
|
565
|
+
*/
|
|
566
|
+
buildScene4HarmonyProject() {
|
|
567
|
+
this.buildOhPkgContentMap();
|
|
568
|
+
this.modulePath2NameMap.forEach((value, key) => {
|
|
569
|
+
let moduleScene = new ModuleScene(this);
|
|
570
|
+
moduleScene.ModuleSceneBuilder(value, key, this.options.supportFileExts);
|
|
571
|
+
this.moduleScenesMap.set(value, moduleScene);
|
|
572
|
+
});
|
|
573
|
+
(0, ModelUtils_1.initModulePathMap)(this.ohPkgContentMap);
|
|
574
|
+
this.buildAllMethodBody();
|
|
575
|
+
this.addDefaultConstructors();
|
|
576
|
+
}
|
|
577
|
+
buildOhPkgContentMap() {
|
|
578
|
+
this.modulePath2NameMap.forEach((value, key) => {
|
|
579
|
+
const moduleOhPkgFilePath = path_1.default.resolve(key, EtsConst_1.OH_PACKAGE_JSON5);
|
|
580
|
+
if (fs_1.default.existsSync(moduleOhPkgFilePath)) {
|
|
581
|
+
const moduleOhPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(moduleOhPkgFilePath);
|
|
582
|
+
this.ohPkgContentMap.set(moduleOhPkgFilePath, moduleOhPkgContent);
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
buildModuleScene(moduleName, modulePath, supportFileExts) {
|
|
587
|
+
if (this.moduleScenesMap.get(moduleName)) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
// get oh-package.json5
|
|
591
|
+
const moduleOhPkgFilePath = path_1.default.resolve(this.realProjectDir, path_1.default.join(modulePath, EtsConst_1.OH_PACKAGE_JSON5));
|
|
592
|
+
if (fs_1.default.existsSync(moduleOhPkgFilePath)) {
|
|
593
|
+
const moduleOhPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(moduleOhPkgFilePath);
|
|
594
|
+
this.ohPkgContentMap.set(moduleOhPkgFilePath, moduleOhPkgContent);
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
logger.warn('Module: ', moduleName, 'has no oh-package.json5.');
|
|
598
|
+
}
|
|
599
|
+
// parse moduleOhPkgContent, get dependencies and build dependent module
|
|
600
|
+
const moduleOhPkgContent = this.ohPkgContentMap.get(moduleOhPkgFilePath);
|
|
601
|
+
if (moduleOhPkgContent) {
|
|
602
|
+
if (moduleOhPkgContent.dependencies instanceof Object) {
|
|
603
|
+
this.processModuleOhPkgContent(moduleOhPkgContent.dependencies, moduleOhPkgFilePath, supportFileExts);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
let moduleScene = new ModuleScene(this);
|
|
607
|
+
moduleScene.ModuleSceneBuilder(moduleName, modulePath, supportFileExts);
|
|
608
|
+
this.moduleScenesMap.set(moduleName, moduleScene);
|
|
609
|
+
this.buildAllMethodBody();
|
|
610
|
+
}
|
|
611
|
+
processModuleOhPkgContent(dependencies, moduleOhPkgFilePath, supportFileExts) {
|
|
612
|
+
Object.entries(dependencies).forEach(([k, v]) => {
|
|
613
|
+
const pattern = new RegExp('^(\\.\\.\\/\|\\.\\/)');
|
|
614
|
+
if (typeof (v) === 'string') {
|
|
615
|
+
let dependencyModulePath = '';
|
|
616
|
+
if (pattern.test(v)) {
|
|
617
|
+
dependencyModulePath = path_1.default.join(moduleOhPkgFilePath, v);
|
|
618
|
+
}
|
|
619
|
+
else if (v.startsWith('file:')) {
|
|
620
|
+
const dependencyFilePath = path_1.default.join(moduleOhPkgFilePath, v.replace(/^file:/, ''));
|
|
621
|
+
const dependencyOhPkgPath = (0, FileUtils_1.getFileRecursively)(path_1.default.dirname(dependencyFilePath), EtsConst_1.OH_PACKAGE_JSON5);
|
|
622
|
+
dependencyModulePath = path_1.default.dirname(dependencyOhPkgPath);
|
|
623
|
+
}
|
|
624
|
+
const dependencyModuleName = this.modulePath2NameMap.get(dependencyModulePath);
|
|
625
|
+
if (dependencyModuleName) {
|
|
626
|
+
this.buildModuleScene(dependencyModuleName, dependencyModulePath, supportFileExts);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Get the absolute path of current project.
|
|
633
|
+
* @returns The real project's directiory.
|
|
634
|
+
* @example
|
|
635
|
+
* 1. get real project directory, such as:
|
|
636
|
+
```typescript
|
|
637
|
+
let projectDir = projectScene.getRealProjectDir();
|
|
638
|
+
```
|
|
639
|
+
*/
|
|
640
|
+
getRealProjectDir() {
|
|
641
|
+
return this.realProjectDir;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Returns the **string** name of the project.
|
|
645
|
+
* @returns The name of the project.
|
|
646
|
+
*/
|
|
647
|
+
getProjectName() {
|
|
648
|
+
return this.projectName;
|
|
649
|
+
}
|
|
650
|
+
getProjectFiles() {
|
|
651
|
+
return this.projectFiles;
|
|
652
|
+
}
|
|
653
|
+
getSdkGlobal(globalName) {
|
|
654
|
+
return this.sdkGlobalMap.get(globalName) || null;
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Returns the file based on its signature.
|
|
658
|
+
* If no file can be found according to the input signature, **null** will be returned.
|
|
659
|
+
* A typical {@link ArkFile} contains: file's name (i.e., its relative path), project's name,
|
|
660
|
+
* project's dir, file's signature etc.
|
|
661
|
+
* @param fileSignature - the signature of file.
|
|
662
|
+
* @returns a file defined by ArkAnalyzer. **null** will be returned if no file could be found.
|
|
663
|
+
* @example
|
|
664
|
+
* 1. get ArkFile based on file signature.
|
|
665
|
+
|
|
666
|
+
```typescript
|
|
667
|
+
if (...) {
|
|
668
|
+
const fromSignature = new FileSignature();
|
|
669
|
+
fromSignature.setProjectName(im.getDeclaringArkFile().getProjectName());
|
|
670
|
+
fromSignature.setFileName(fileName);
|
|
671
|
+
return scene.getFile(fromSignature);
|
|
672
|
+
}
|
|
673
|
+
```
|
|
674
|
+
*/
|
|
675
|
+
getFile(fileSignature) {
|
|
676
|
+
if (this.projectName === fileSignature.getProjectName()) {
|
|
677
|
+
return this.filesMap.get(fileSignature.toMapKey()) || null;
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
return this.sdkArkFilesMap.get(fileSignature.toMapKey()) || null;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
/*
|
|
684
|
+
* Returns the absolute file paths that cannot be handled currently.
|
|
685
|
+
*/
|
|
686
|
+
getUnhandledFilePaths() {
|
|
687
|
+
return this.unhandledFilePaths;
|
|
688
|
+
}
|
|
689
|
+
/*
|
|
690
|
+
* Returns the absolute sdk file paths that cannot be handled currently.
|
|
691
|
+
*/
|
|
692
|
+
getUnhandledSdkFilePaths() {
|
|
693
|
+
return this.unhandledSdkFilePaths;
|
|
694
|
+
}
|
|
695
|
+
setFile(file) {
|
|
696
|
+
this.filesMap.set(file.getFileSignature().toMapKey(), file);
|
|
697
|
+
}
|
|
698
|
+
hasSdkFile(fileSignature) {
|
|
699
|
+
return this.sdkArkFilesMap.has(fileSignature.toMapKey());
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Get files of a {@link Scene}. Generally, a project includes several ets/ts files that define the different
|
|
703
|
+
* class. We need to generate {@link ArkFile} objects from these ets/ts files.
|
|
704
|
+
* @returns The array of {@link ArkFile} from `scene.filesMap.values()`.
|
|
705
|
+
* @example
|
|
706
|
+
* 1. In inferSimpleTypes() to check arkClass and arkMethod.
|
|
707
|
+
* ```typescript
|
|
708
|
+
* public inferSimpleTypes() {
|
|
709
|
+
* for (let arkFile of this.getFiles()) {
|
|
710
|
+
* for (let arkClass of arkFile.getClasses()) {
|
|
711
|
+
* for (let arkMethod of arkClass.getMethods()) {
|
|
712
|
+
* // ... ...;
|
|
713
|
+
* }
|
|
714
|
+
* }
|
|
715
|
+
* }
|
|
716
|
+
* }
|
|
717
|
+
* ```
|
|
718
|
+
* 2. To iterate each method
|
|
719
|
+
* ```typescript
|
|
720
|
+
* for (const file of this.getFiles()) {
|
|
721
|
+
* for (const cls of file.getClasses()) {
|
|
722
|
+
* for (const method of cls.getMethods()) {
|
|
723
|
+
* // ... ...
|
|
724
|
+
* }
|
|
725
|
+
* }
|
|
726
|
+
* }
|
|
727
|
+
*```
|
|
728
|
+
*/
|
|
729
|
+
getFiles() {
|
|
730
|
+
return Array.from(this.filesMap.values());
|
|
731
|
+
}
|
|
732
|
+
getSdkArkFiles() {
|
|
733
|
+
return Array.from(this.sdkArkFilesMap.values());
|
|
734
|
+
}
|
|
735
|
+
getModuleSdkMap() {
|
|
736
|
+
return this.moduleSdkMap;
|
|
737
|
+
}
|
|
738
|
+
getProjectSdkMap() {
|
|
739
|
+
return this.projectSdkMap;
|
|
740
|
+
}
|
|
741
|
+
getNamespace(namespaceSignature) {
|
|
742
|
+
const isProject = this.projectName === namespaceSignature.getDeclaringFileSignature().getProjectName();
|
|
743
|
+
let namespace;
|
|
744
|
+
if (isProject) {
|
|
745
|
+
namespace = this.namespacesMap.get(namespaceSignature.toMapKey());
|
|
746
|
+
}
|
|
747
|
+
if (namespace) {
|
|
748
|
+
return namespace;
|
|
749
|
+
}
|
|
750
|
+
namespace = this.getNamespaceBySignature(namespaceSignature);
|
|
751
|
+
if (isProject && namespace) {
|
|
752
|
+
this.namespacesMap.set(namespaceSignature.toMapKey(), namespace);
|
|
753
|
+
}
|
|
754
|
+
return namespace || null;
|
|
755
|
+
}
|
|
756
|
+
getNamespaceBySignature(signature) {
|
|
757
|
+
const parentSignature = signature.getDeclaringNamespaceSignature();
|
|
758
|
+
if (parentSignature) {
|
|
759
|
+
const parentNamespace = this.getNamespaceBySignature(parentSignature);
|
|
760
|
+
return (parentNamespace === null || parentNamespace === void 0 ? void 0 : parentNamespace.getNamespace(signature)) || null;
|
|
761
|
+
}
|
|
762
|
+
else {
|
|
763
|
+
const arkFile = this.getFile(signature.getDeclaringFileSignature());
|
|
764
|
+
return (arkFile === null || arkFile === void 0 ? void 0 : arkFile.getNamespace(signature)) || null;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
getNamespacesMap() {
|
|
768
|
+
if (this.buildStage === SceneBuildStage.CLASS_DONE) {
|
|
769
|
+
for (const file of this.getFiles()) {
|
|
770
|
+
ModelUtils_1.ModelUtils.getAllNamespacesInFile(file).forEach((namespace) => {
|
|
771
|
+
this.namespacesMap.set(namespace.getNamespaceSignature().toMapKey(), namespace);
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
return this.namespacesMap;
|
|
776
|
+
}
|
|
777
|
+
getNamespaces() {
|
|
778
|
+
return Array.from(this.getNamespacesMap().values());
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Returns the class according to the input class signature.
|
|
782
|
+
* @param classSignature - signature of the class to be obtained.
|
|
783
|
+
* @returns A class.
|
|
784
|
+
*/
|
|
785
|
+
getClass(classSignature) {
|
|
786
|
+
var _a;
|
|
787
|
+
const isProject = this.projectName === classSignature.getDeclaringFileSignature().getProjectName();
|
|
788
|
+
let arkClass;
|
|
789
|
+
if (isProject) {
|
|
790
|
+
arkClass = this.classesMap.get(classSignature.toMapKey());
|
|
791
|
+
}
|
|
792
|
+
if (arkClass) {
|
|
793
|
+
return arkClass;
|
|
794
|
+
}
|
|
795
|
+
const namespaceSignature = classSignature.getDeclaringNamespaceSignature();
|
|
796
|
+
if (namespaceSignature) {
|
|
797
|
+
arkClass = ((_a = this.getNamespaceBySignature(namespaceSignature)) === null || _a === void 0 ? void 0 : _a.getClass(classSignature)) || null;
|
|
798
|
+
}
|
|
799
|
+
else {
|
|
800
|
+
const arkFile = this.getFile(classSignature.getDeclaringFileSignature());
|
|
801
|
+
arkClass = arkFile === null || arkFile === void 0 ? void 0 : arkFile.getClass(classSignature);
|
|
802
|
+
}
|
|
803
|
+
if (isProject && arkClass) {
|
|
804
|
+
this.classesMap.set(classSignature.toMapKey(), arkClass);
|
|
805
|
+
}
|
|
806
|
+
return arkClass || null;
|
|
807
|
+
}
|
|
808
|
+
getClassesMap(refresh) {
|
|
809
|
+
if (refresh || this.buildStage === SceneBuildStage.METHOD_DONE) {
|
|
810
|
+
this.classesMap.clear();
|
|
811
|
+
for (const file of this.getFiles()) {
|
|
812
|
+
for (const cls of file.getClasses()) {
|
|
813
|
+
this.classesMap.set(cls.getSignature().toMapKey(), cls);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
for (const namespace of this.getNamespacesMap().values()) {
|
|
817
|
+
for (const cls of namespace.getClasses()) {
|
|
818
|
+
this.classesMap.set(cls.getSignature().toMapKey(), cls);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
if (this.buildStage < SceneBuildStage.CLASS_COLLECTED) {
|
|
822
|
+
this.buildStage = SceneBuildStage.CLASS_COLLECTED;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
return this.classesMap;
|
|
826
|
+
}
|
|
827
|
+
getClasses() {
|
|
828
|
+
return Array.from(this.getClassesMap().values());
|
|
829
|
+
}
|
|
830
|
+
getMethod(methodSignature, refresh) {
|
|
831
|
+
var _a;
|
|
832
|
+
const isProject = this.projectName === methodSignature.getDeclaringClassSignature().getDeclaringFileSignature().getProjectName();
|
|
833
|
+
let arkMethod;
|
|
834
|
+
if (isProject) {
|
|
835
|
+
arkMethod = this.methodsMap.get(methodSignature.toMapKey());
|
|
836
|
+
}
|
|
837
|
+
if (arkMethod) {
|
|
838
|
+
return arkMethod;
|
|
839
|
+
}
|
|
840
|
+
arkMethod = (_a = this.getClass(methodSignature.getDeclaringClassSignature())) === null || _a === void 0 ? void 0 : _a.getMethod(methodSignature);
|
|
841
|
+
if (isProject && arkMethod) {
|
|
842
|
+
this.methodsMap.set(methodSignature.toMapKey(), arkMethod);
|
|
843
|
+
}
|
|
844
|
+
return arkMethod || null;
|
|
845
|
+
}
|
|
846
|
+
getMethodsMap(refresh) {
|
|
847
|
+
if (refresh || (this.buildStage >= SceneBuildStage.METHOD_DONE && this.buildStage < SceneBuildStage.METHOD_COLLECTED)) {
|
|
848
|
+
this.methodsMap.clear();
|
|
849
|
+
for (const cls of this.getClassesMap(refresh).values()) {
|
|
850
|
+
for (const method of cls.getMethods(true)) {
|
|
851
|
+
this.methodsMap.set(method.getSignature().toMapKey(), method);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
if (this.buildStage < SceneBuildStage.METHOD_COLLECTED) {
|
|
855
|
+
this.buildStage = SceneBuildStage.METHOD_COLLECTED;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
return this.methodsMap;
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Returns the method associated with the method signature.
|
|
862
|
+
* If no method is associated with this signature, **null** will be returned.
|
|
863
|
+
* An {@link ArkMethod} includes:
|
|
864
|
+
* - Name: the **string** name of method.
|
|
865
|
+
* - Code: the **string** code of the method.
|
|
866
|
+
* - Line: a **number** indicating the line location, initialized as -1.
|
|
867
|
+
* - Column: a **number** indicating the column location, initialized as -1.
|
|
868
|
+
* - Parameters & Types of parameters: the parameters of method and their types.
|
|
869
|
+
* - View tree: the view tree of the method.
|
|
870
|
+
* - ...
|
|
871
|
+
*
|
|
872
|
+
* @param methodSignature - the signature of method.
|
|
873
|
+
* @returns The method associated with the method signature.
|
|
874
|
+
* @example
|
|
875
|
+
* 1. get method from getMethod.
|
|
876
|
+
|
|
877
|
+
```typescript
|
|
878
|
+
const methodSignatures = this.CHA.resolveCall(xxx, yyy);
|
|
879
|
+
for (const methodSignature of methodSignatures) {
|
|
880
|
+
const method = this.scene.getMethod(methodSignature);
|
|
881
|
+
... ...
|
|
882
|
+
}
|
|
883
|
+
```
|
|
884
|
+
*/
|
|
885
|
+
getMethods() {
|
|
886
|
+
return Array.from(this.getMethodsMap().values());
|
|
887
|
+
}
|
|
888
|
+
addToMethodsMap(method) {
|
|
889
|
+
this.methodsMap.set(method.getSignature().toMapKey(), method);
|
|
890
|
+
}
|
|
891
|
+
removeMethod(method) {
|
|
892
|
+
return this.methodsMap.delete(method.getSignature().toMapKey());
|
|
893
|
+
}
|
|
894
|
+
removeClass(arkClass) {
|
|
895
|
+
return this.classesMap.delete(arkClass.getSignature().toMapKey());
|
|
896
|
+
}
|
|
897
|
+
removeNamespace(namespace) {
|
|
898
|
+
return this.namespacesMap.delete(namespace.getSignature().toMapKey());
|
|
899
|
+
}
|
|
900
|
+
removeFile(file) {
|
|
901
|
+
return this.filesMap.delete(file.getFileSignature().toMapKey());
|
|
902
|
+
}
|
|
903
|
+
hasMainMethod() {
|
|
904
|
+
return false;
|
|
905
|
+
}
|
|
906
|
+
//Get the set of entry points that are used to build the call graph.
|
|
907
|
+
getEntryPoints() {
|
|
908
|
+
return [];
|
|
909
|
+
}
|
|
910
|
+
/** get values that is visible in curr scope */
|
|
911
|
+
getVisibleValue() {
|
|
912
|
+
return this.visibleValue;
|
|
913
|
+
}
|
|
914
|
+
getOhPkgContent() {
|
|
915
|
+
return this.ohPkgContent;
|
|
916
|
+
}
|
|
917
|
+
getOhPkgContentMap() {
|
|
918
|
+
return this.ohPkgContentMap;
|
|
919
|
+
}
|
|
920
|
+
getOhPkgFilePath() {
|
|
921
|
+
return this.ohPkgFilePath;
|
|
922
|
+
}
|
|
923
|
+
makeCallGraphCHA(entryPoints) {
|
|
924
|
+
let callGraph = new CallGraph_1.CallGraph(this);
|
|
925
|
+
let callGraphBuilder = new CallGraphBuilder_1.CallGraphBuilder(callGraph, this);
|
|
926
|
+
callGraphBuilder.buildClassHierarchyCallGraph(entryPoints);
|
|
927
|
+
return callGraph;
|
|
928
|
+
}
|
|
929
|
+
makeCallGraphRTA(entryPoints) {
|
|
930
|
+
let callGraph = new CallGraph_1.CallGraph(this);
|
|
931
|
+
let callGraphBuilder = new CallGraphBuilder_1.CallGraphBuilder(callGraph, this);
|
|
932
|
+
callGraphBuilder.buildRapidTypeCallGraph(entryPoints);
|
|
933
|
+
return callGraph;
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* Infer type for each non-default method. It infers the type of each field/local/reference.
|
|
937
|
+
* For example, the statement `let b = 5;`, the type of local `b` is `NumberType`; and for the statement `let s =
|
|
938
|
+
* 'hello';`, the type of local `s` is `StringType`. The detailed types are defined in the Type.ts file.
|
|
939
|
+
* @example
|
|
940
|
+
* 1. Infer the type of each class field and method field.
|
|
941
|
+
```typescript
|
|
942
|
+
const scene = new Scene();
|
|
943
|
+
scene.buildSceneFromProjectDir(sceneConfig);
|
|
944
|
+
scene.inferTypes();
|
|
945
|
+
```
|
|
946
|
+
*/
|
|
947
|
+
inferTypes() {
|
|
948
|
+
if (this.buildStage < SceneBuildStage.SDK_INFERRED) {
|
|
949
|
+
this.sdkArkFilesMap.forEach(file => IRInference_1.IRInference.inferFile(file));
|
|
950
|
+
this.buildStage = SceneBuildStage.SDK_INFERRED;
|
|
951
|
+
}
|
|
952
|
+
this.filesMap.forEach(file => IRInference_1.IRInference.inferFile(file));
|
|
953
|
+
if (this.buildStage < SceneBuildStage.TYPE_INFERRED) {
|
|
954
|
+
this.getMethodsMap(true);
|
|
955
|
+
this.buildStage = SceneBuildStage.TYPE_INFERRED;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Iterate all assignment statements in methods,
|
|
960
|
+
* and set the type of left operand based on the type of right operand
|
|
961
|
+
* if the left operand is a local variable as well as an unknown.
|
|
962
|
+
* @Deprecated
|
|
963
|
+
* @example
|
|
964
|
+
* 1. Infer simple type when scene building.
|
|
965
|
+
|
|
966
|
+
```typescript
|
|
967
|
+
let scene = new Scene();
|
|
968
|
+
scene.buildSceneFromProjectDir(config);
|
|
969
|
+
scene.inferSimpleTypes();
|
|
970
|
+
```
|
|
971
|
+
*/
|
|
972
|
+
inferSimpleTypes() {
|
|
973
|
+
for (let arkFile of this.getFiles()) {
|
|
974
|
+
for (let arkClass of arkFile.getClasses()) {
|
|
975
|
+
for (let arkMethod of arkClass.getMethods()) {
|
|
976
|
+
TypeInference_1.TypeInference.inferSimpleTypeInMethod(arkMethod);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
getClassMap() {
|
|
982
|
+
var _a, _b, _c, _d;
|
|
983
|
+
const classMap = new Map();
|
|
984
|
+
for (const file of this.getFiles()) {
|
|
985
|
+
const fileClass = [];
|
|
986
|
+
const namespaceStack = [];
|
|
987
|
+
const parentMap = new Map();
|
|
988
|
+
const finalNamespaces = [];
|
|
989
|
+
for (const arkClass of file.getClasses()) {
|
|
990
|
+
fileClass.push(arkClass);
|
|
991
|
+
}
|
|
992
|
+
for (const ns of file.getNamespaces()) {
|
|
993
|
+
namespaceStack.push(ns);
|
|
994
|
+
parentMap.set(ns, file);
|
|
995
|
+
}
|
|
996
|
+
classMap.set(file.getFileSignature(), fileClass);
|
|
997
|
+
// 第一轮遍历,加上每个namespace自己的class
|
|
998
|
+
while (namespaceStack.length > 0) {
|
|
999
|
+
const ns = namespaceStack.shift();
|
|
1000
|
+
const nsClass = [];
|
|
1001
|
+
for (const arkClass of ns.getClasses()) {
|
|
1002
|
+
nsClass.push(arkClass);
|
|
1003
|
+
}
|
|
1004
|
+
classMap.set(ns.getNamespaceSignature(), nsClass);
|
|
1005
|
+
if (ns.getNamespaces().length === 0) {
|
|
1006
|
+
finalNamespaces.push(ns);
|
|
1007
|
+
}
|
|
1008
|
+
else {
|
|
1009
|
+
for (const nsns of ns.getNamespaces()) {
|
|
1010
|
+
namespaceStack.push(nsns);
|
|
1011
|
+
parentMap.set(nsns, ns);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
// 第二轮遍历,父节点加上子节点的export的class
|
|
1016
|
+
while (finalNamespaces.length > 0) {
|
|
1017
|
+
const finalNS = finalNamespaces.shift();
|
|
1018
|
+
const exportClass = [];
|
|
1019
|
+
for (const arkClass of finalNS.getClasses()) {
|
|
1020
|
+
if (arkClass.isExported()) {
|
|
1021
|
+
exportClass.push(arkClass);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
const parent = parentMap.get(finalNS);
|
|
1025
|
+
if (parent instanceof ArkNamespace_1.ArkNamespace) {
|
|
1026
|
+
(_a = classMap.get(parent.getNamespaceSignature())) === null || _a === void 0 ? void 0 : _a.push(...exportClass);
|
|
1027
|
+
}
|
|
1028
|
+
else if (parent instanceof ArkFile_1.ArkFile) {
|
|
1029
|
+
(_b = classMap.get(parent.getFileSignature())) === null || _b === void 0 ? void 0 : _b.push(...exportClass);
|
|
1030
|
+
}
|
|
1031
|
+
let p = finalNS;
|
|
1032
|
+
while (!(parentMap.get(p) instanceof ArkFile_1.ArkFile) && p.isExported()) {
|
|
1033
|
+
const grandParent = parentMap.get(parentMap.get(p));
|
|
1034
|
+
if (grandParent instanceof ArkNamespace_1.ArkNamespace) {
|
|
1035
|
+
(_c = classMap.get(grandParent.getNamespaceSignature())) === null || _c === void 0 ? void 0 : _c.push(...exportClass);
|
|
1036
|
+
p = parentMap.get(p);
|
|
1037
|
+
}
|
|
1038
|
+
else if (grandParent instanceof ArkFile_1.ArkFile) {
|
|
1039
|
+
(_d = classMap.get(grandParent.getFileSignature())) === null || _d === void 0 ? void 0 : _d.push(...exportClass);
|
|
1040
|
+
break;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
if (parent instanceof ArkNamespace_1.ArkNamespace && !finalNamespaces.includes(parent)) {
|
|
1044
|
+
finalNamespaces.push(parent);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
for (const file of this.getFiles()) {
|
|
1049
|
+
// 文件加上import的class,包括ns的
|
|
1050
|
+
const importClasses = [];
|
|
1051
|
+
const importNameSpaces = [];
|
|
1052
|
+
for (const importInfo of file.getImportInfos()) {
|
|
1053
|
+
const importClass = ModelUtils_1.ModelUtils.getClassInImportInfoWithName(importInfo.getImportClauseName(), file);
|
|
1054
|
+
if (importClass && !importClasses.includes(importClass)) {
|
|
1055
|
+
importClasses.push(importClass);
|
|
1056
|
+
continue;
|
|
1057
|
+
}
|
|
1058
|
+
const importNameSpace = ModelUtils_1.ModelUtils.getNamespaceInImportInfoWithName(importInfo.getImportClauseName(), file);
|
|
1059
|
+
if (importNameSpace && !importNameSpaces.includes(importNameSpace)) {
|
|
1060
|
+
try {
|
|
1061
|
+
// 遗留问题:只统计了项目文件的namespace,没统计sdk文件内部的引入
|
|
1062
|
+
const importNameSpaceClasses = classMap.get(importNameSpace.getNamespaceSignature());
|
|
1063
|
+
importClasses.push(...importNameSpaceClasses.filter(c => !importClasses.includes(c) && c.getName() !== Const_1.DEFAULT_ARK_CLASS_NAME));
|
|
1064
|
+
}
|
|
1065
|
+
catch (_e) {
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
const fileClasses = classMap.get(file.getFileSignature());
|
|
1070
|
+
fileClasses.push(...importClasses.filter(c => !fileClasses.includes(c)));
|
|
1071
|
+
// 子节点加上父节点的class
|
|
1072
|
+
const namespaceStack = [...file.getNamespaces()];
|
|
1073
|
+
for (const ns of namespaceStack) {
|
|
1074
|
+
const nsClasses = classMap.get(ns.getNamespaceSignature());
|
|
1075
|
+
nsClasses.push(...fileClasses.filter(c => !nsClasses.includes(c) && c.getName() !== Const_1.DEFAULT_ARK_CLASS_NAME));
|
|
1076
|
+
}
|
|
1077
|
+
while (namespaceStack.length > 0) {
|
|
1078
|
+
const ns = namespaceStack.shift();
|
|
1079
|
+
const nsClasses = classMap.get(ns.getNamespaceSignature());
|
|
1080
|
+
for (const nsns of ns.getNamespaces()) {
|
|
1081
|
+
const nsnsClasses = classMap.get(nsns.getNamespaceSignature());
|
|
1082
|
+
nsnsClasses.push(...nsClasses.filter(c => !nsnsClasses.includes(c) && c.getName() !== Const_1.DEFAULT_ARK_CLASS_NAME));
|
|
1083
|
+
namespaceStack.push(nsns);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
return classMap;
|
|
1088
|
+
}
|
|
1089
|
+
getGlobalVariableMap() {
|
|
1090
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1091
|
+
const globalVariableMap = new Map();
|
|
1092
|
+
for (const file of this.getFiles()) {
|
|
1093
|
+
const namespaceStack = [];
|
|
1094
|
+
const parentMap = new Map();
|
|
1095
|
+
const finalNamespaces = [];
|
|
1096
|
+
const globalLocals = [];
|
|
1097
|
+
(_b = (_a = file.getDefaultClass()) === null || _a === void 0 ? void 0 : _a.getDefaultArkMethod().getBody()) === null || _b === void 0 ? void 0 : _b.getLocals().forEach(local => {
|
|
1098
|
+
if (local.getDeclaringStmt() && local.getName() !== 'this' && local.getName()[0] !== '$') {
|
|
1099
|
+
globalLocals.push(local);
|
|
1100
|
+
}
|
|
1101
|
+
});
|
|
1102
|
+
globalVariableMap.set(file.getFileSignature(), globalLocals);
|
|
1103
|
+
for (const ns of file.getNamespaces()) {
|
|
1104
|
+
namespaceStack.push(ns);
|
|
1105
|
+
parentMap.set(ns, file);
|
|
1106
|
+
}
|
|
1107
|
+
// 第一轮遍历,加上每个namespace自己的local
|
|
1108
|
+
while (namespaceStack.length > 0) {
|
|
1109
|
+
const ns = namespaceStack.shift();
|
|
1110
|
+
const nsGlobalLocals = [];
|
|
1111
|
+
(_c = ns.getDefaultClass().getDefaultArkMethod().getBody()) === null || _c === void 0 ? void 0 : _c.getLocals().forEach(local => {
|
|
1112
|
+
if (local.getDeclaringStmt() && local.getName() !== 'this' && local.getName()[0] !== '$') {
|
|
1113
|
+
nsGlobalLocals.push(local);
|
|
1114
|
+
}
|
|
1115
|
+
});
|
|
1116
|
+
globalVariableMap.set(ns.getNamespaceSignature(), nsGlobalLocals);
|
|
1117
|
+
if (ns.getNamespaces().length === 0) {
|
|
1118
|
+
finalNamespaces.push(ns);
|
|
1119
|
+
}
|
|
1120
|
+
else {
|
|
1121
|
+
for (const nsns of ns.getNamespaces()) {
|
|
1122
|
+
namespaceStack.push(nsns);
|
|
1123
|
+
parentMap.set(nsns, ns);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
// 第二轮遍历,父节点加上子节点的export的local
|
|
1128
|
+
while (finalNamespaces.length > 0) {
|
|
1129
|
+
const finalNS = finalNamespaces.shift();
|
|
1130
|
+
const exportLocal = [];
|
|
1131
|
+
for (const exportInfo of finalNS.getExportInfos()) {
|
|
1132
|
+
if (exportInfo.getExportClauseType() === ArkExport_1.ExportType.LOCAL && exportInfo.getArkExport()) {
|
|
1133
|
+
exportLocal.push(exportInfo.getArkExport());
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
const parent = parentMap.get(finalNS);
|
|
1137
|
+
if (parent instanceof ArkNamespace_1.ArkNamespace) {
|
|
1138
|
+
(_d = globalVariableMap.get(parent.getNamespaceSignature())) === null || _d === void 0 ? void 0 : _d.push(...exportLocal);
|
|
1139
|
+
}
|
|
1140
|
+
else if (parent instanceof ArkFile_1.ArkFile) {
|
|
1141
|
+
(_e = globalVariableMap.get(parent.getFileSignature())) === null || _e === void 0 ? void 0 : _e.push(...exportLocal);
|
|
1142
|
+
}
|
|
1143
|
+
let p = finalNS;
|
|
1144
|
+
while (!(parentMap.get(p) instanceof ArkFile_1.ArkFile) && p.isExported()) {
|
|
1145
|
+
const grandParent = parentMap.get(parentMap.get(p));
|
|
1146
|
+
if (grandParent instanceof ArkNamespace_1.ArkNamespace) {
|
|
1147
|
+
(_f = globalVariableMap.get(grandParent.getNamespaceSignature())) === null || _f === void 0 ? void 0 : _f.push(...exportLocal);
|
|
1148
|
+
p = parentMap.get(p);
|
|
1149
|
+
}
|
|
1150
|
+
else if (grandParent instanceof ArkFile_1.ArkFile) {
|
|
1151
|
+
(_g = globalVariableMap.get(grandParent.getFileSignature())) === null || _g === void 0 ? void 0 : _g.push(...exportLocal);
|
|
1152
|
+
break;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
if (parent instanceof ArkNamespace_1.ArkNamespace && !finalNamespaces.includes(parent)) {
|
|
1156
|
+
finalNamespaces.push(parent);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
for (const file of this.getFiles()) {
|
|
1161
|
+
// 文件加上import的local,包括ns的
|
|
1162
|
+
const importLocals = [];
|
|
1163
|
+
const importNameSpaces = [];
|
|
1164
|
+
for (const importInfo of file.getImportInfos()) {
|
|
1165
|
+
const importLocal = ModelUtils_1.ModelUtils.getLocalInImportInfoWithName(importInfo.getImportClauseName(), file);
|
|
1166
|
+
if (importLocal && !importLocals.includes(importLocal)) {
|
|
1167
|
+
importLocals.push(importLocal);
|
|
1168
|
+
}
|
|
1169
|
+
const importNameSpace = ModelUtils_1.ModelUtils.getNamespaceInImportInfoWithName(importInfo.getImportClauseName(), file);
|
|
1170
|
+
if (importNameSpace && !importNameSpaces.includes(importNameSpace)) {
|
|
1171
|
+
try {
|
|
1172
|
+
// 遗留问题:只统计了项目文件,没统计sdk文件内部的引入
|
|
1173
|
+
const importNameSpaceClasses = globalVariableMap.get(importNameSpace.getNamespaceSignature());
|
|
1174
|
+
importLocals.push(...importNameSpaceClasses.filter(c => !importLocals.includes(c) && c.getName() !== Const_1.DEFAULT_ARK_CLASS_NAME));
|
|
1175
|
+
}
|
|
1176
|
+
catch (_h) {
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
const fileLocals = globalVariableMap.get(file.getFileSignature());
|
|
1181
|
+
fileLocals.push(...importLocals.filter(c => !fileLocals.includes(c)));
|
|
1182
|
+
// 子节点加上父节点的local
|
|
1183
|
+
const namespaceStack = [...file.getNamespaces()];
|
|
1184
|
+
for (const ns of namespaceStack) {
|
|
1185
|
+
const nsLocals = globalVariableMap.get(ns.getNamespaceSignature());
|
|
1186
|
+
const nsLocalNameSet = new Set(nsLocals.map(item => item.getName()));
|
|
1187
|
+
for (const local of fileLocals) {
|
|
1188
|
+
if (!nsLocalNameSet.has(local.getName())) {
|
|
1189
|
+
nsLocals.push(local);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
while (namespaceStack.length > 0) {
|
|
1194
|
+
const ns = namespaceStack.shift();
|
|
1195
|
+
const nsLocals = globalVariableMap.get(ns.getNamespaceSignature());
|
|
1196
|
+
for (const nsns of ns.getNamespaces()) {
|
|
1197
|
+
const nsnsLocals = globalVariableMap.get(nsns.getNamespaceSignature());
|
|
1198
|
+
const nsnsLocalNameSet = new Set(nsnsLocals.map(item => item.getName()));
|
|
1199
|
+
for (const local of nsLocals) {
|
|
1200
|
+
if (!nsnsLocalNameSet.has(local.getName())) {
|
|
1201
|
+
nsnsLocals.push(local);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
namespaceStack.push(nsns);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
return globalVariableMap;
|
|
1209
|
+
}
|
|
1210
|
+
getStaticInitMethods() {
|
|
1211
|
+
const staticInitMethods = [];
|
|
1212
|
+
for (const method of Array.from(this.getMethodsMap(true).values())) {
|
|
1213
|
+
if (method.getName() === Const_1.STATIC_INIT_METHOD_NAME) {
|
|
1214
|
+
staticInitMethods.push(method);
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
return staticInitMethods;
|
|
1218
|
+
}
|
|
1219
|
+
buildClassDone() {
|
|
1220
|
+
return this.buildStage >= SceneBuildStage.CLASS_DONE;
|
|
1221
|
+
}
|
|
1222
|
+
getModuleScene(moduleName) {
|
|
1223
|
+
return this.moduleScenesMap.get(moduleName);
|
|
1224
|
+
}
|
|
1225
|
+
getModuleSceneMap() {
|
|
1226
|
+
return this.moduleScenesMap;
|
|
1227
|
+
}
|
|
1228
|
+
getGlobalModule2PathMapping() {
|
|
1229
|
+
return this.globalModule2PathMapping;
|
|
1230
|
+
}
|
|
1231
|
+
getbaseUrl() {
|
|
1232
|
+
return this.baseUrl;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
exports.Scene = Scene;
|
|
1236
|
+
class ModuleScene {
|
|
1237
|
+
constructor(projectScene) {
|
|
1238
|
+
this.moduleName = '';
|
|
1239
|
+
this.modulePath = '';
|
|
1240
|
+
this.moduleFileMap = new Map();
|
|
1241
|
+
this.moduleOhPkgFilePath = '';
|
|
1242
|
+
this.ohPkgContent = {};
|
|
1243
|
+
this.projectScene = projectScene;
|
|
1244
|
+
}
|
|
1245
|
+
ModuleSceneBuilder(moduleName, modulePath, supportFileExts, recursively = false) {
|
|
1246
|
+
this.moduleName = moduleName;
|
|
1247
|
+
this.modulePath = modulePath;
|
|
1248
|
+
this.getModuleOhPkgFilePath();
|
|
1249
|
+
if (this.moduleOhPkgFilePath) {
|
|
1250
|
+
this.ohPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(this.moduleOhPkgFilePath);
|
|
1251
|
+
}
|
|
1252
|
+
else {
|
|
1253
|
+
logger.warn('This module has no oh-package.json5!');
|
|
1254
|
+
}
|
|
1255
|
+
this.genArkFiles(supportFileExts);
|
|
1256
|
+
}
|
|
1257
|
+
ModuleScenePartiallyBuilder(moduleName, modulePath) {
|
|
1258
|
+
this.moduleName = moduleName;
|
|
1259
|
+
this.modulePath = modulePath;
|
|
1260
|
+
if (this.moduleOhPkgFilePath) {
|
|
1261
|
+
this.ohPkgContent = (0, json5parser_1.fetchDependenciesFromFile)(this.moduleOhPkgFilePath);
|
|
1262
|
+
}
|
|
1263
|
+
else {
|
|
1264
|
+
logger.warn('This module has no oh-package.json5!');
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* get oh-package.json5
|
|
1269
|
+
*/
|
|
1270
|
+
getModuleOhPkgFilePath() {
|
|
1271
|
+
const moduleOhPkgFilePath = path_1.default.resolve(this.projectScene.getRealProjectDir(), path_1.default.join(this.modulePath, EtsConst_1.OH_PACKAGE_JSON5));
|
|
1272
|
+
if (fs_1.default.existsSync(moduleOhPkgFilePath)) {
|
|
1273
|
+
this.moduleOhPkgFilePath = moduleOhPkgFilePath;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* get nodule name
|
|
1278
|
+
* @returns return module name
|
|
1279
|
+
*/
|
|
1280
|
+
getModuleName() {
|
|
1281
|
+
return this.moduleName;
|
|
1282
|
+
}
|
|
1283
|
+
getModulePath() {
|
|
1284
|
+
return this.modulePath;
|
|
1285
|
+
}
|
|
1286
|
+
getOhPkgFilePath() {
|
|
1287
|
+
return this.moduleOhPkgFilePath;
|
|
1288
|
+
}
|
|
1289
|
+
getOhPkgContent() {
|
|
1290
|
+
return this.ohPkgContent;
|
|
1291
|
+
}
|
|
1292
|
+
getModuleFilesMap() {
|
|
1293
|
+
return this.moduleFileMap;
|
|
1294
|
+
}
|
|
1295
|
+
addArkFile(arkFile) {
|
|
1296
|
+
this.moduleFileMap.set(arkFile.getFileSignature().toMapKey(), arkFile);
|
|
1297
|
+
}
|
|
1298
|
+
genArkFiles(supportFileExts) {
|
|
1299
|
+
(0, getAllFiles_1.getAllFiles)(this.modulePath, supportFileExts, this.projectScene.getOptions().ignoreFileNames).forEach((file) => {
|
|
1300
|
+
logger.info('=== parse file:', file);
|
|
1301
|
+
try {
|
|
1302
|
+
const arkFile = new ArkFile_1.ArkFile();
|
|
1303
|
+
arkFile.setScene(this.projectScene);
|
|
1304
|
+
arkFile.setModuleScene(this);
|
|
1305
|
+
(0, ArkFileBuilder_1.buildArkFileFromFile)(file, this.projectScene.getRealProjectDir(), arkFile, this.projectScene.getProjectName());
|
|
1306
|
+
this.projectScene.setFile(arkFile);
|
|
1307
|
+
}
|
|
1308
|
+
catch (error) {
|
|
1309
|
+
logger.error('Error parsing file:', file, error);
|
|
1310
|
+
this.projectScene.getUnhandledFilePaths().push(file);
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
exports.ModuleScene = ModuleScene;
|