@hadss/hmrouter-plugin 1.2.3-rc.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,7 +23,7 @@ HMRouter编译插件是一个基于hvigor的编译插件,用于:
23
23
  ```json5
24
24
  {
25
25
  "dependencies": {
26
- "@hadss/hmrouter-plugin": "^1.2.3-rc.2" // 使用最新版本
26
+ "@hadss/hmrouter-plugin": "^1.2.3" // 使用最新版本
27
27
  },
28
28
  // ...其余配置
29
29
  }
@@ -514,11 +514,12 @@ hvigor 5.7.3及以上
514
514
  > [HMRouterPlugin] Your DevEco Studio version less than 5.0.3.800, may cause remote hsp dependencies get failed
515
515
  > ```
516
516
 
517
- ## 更新日志
518
- ### 1.2.3-rc.2 (2026.02.06)
517
+ ## 更新记录
519
518
 
520
- - [新增增量编译配置开关](#增量编译规则)
521
- - [修复插件解析路由常量是通过`export *`导出,生成路由表格式不正确问题](https://gitcode.com/openharmony-sig/ohrouter/issues/278)
519
+ ### 1.2.3 (2026.04.30)
520
+
521
+ - [优化使用插件编译速度](https://gitcode.com/openharmony-sig/ohrouter/issues/298)
522
+ - [修复插件编译报错问题](https://gitcode.com/openharmony-sig/ohrouter/issues/303)
522
523
 
523
524
  ### 1.2.3-rc.1 (2026.01.15)
524
525
 
@@ -6,8 +6,8 @@ export declare class HMRouterPluginManager {
6
6
  private moduleNodes;
7
7
  private nodeIgnored;
8
8
  private constructor();
9
+ private handleNodesEvaluated;
9
10
  static getInstance(): HMRouterPluginManager;
10
11
  registerPlugin(node: HvigorNode, pluginId: string, options: PluginParam): void;
11
12
  addModuleNode(node: HvigorNode, isIgnored: boolean): void;
12
- private initializeArkAnalyzer;
13
13
  }
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HMRouterPluginManager = void 0;
4
4
  const hvigor_1 = require("@ohos/hvigor");
5
- const hvigor_ohos_plugin_1 = require("@ohos/hvigor-ohos-plugin");
6
5
  const PluginError_1 = require("./hmrouter_extension/error/PluginError");
7
6
  const HMRouterExtension_1 = require("./hmrouter_extension/HMRouterExtension");
8
7
  const framework_1 = require("./framework");
@@ -13,25 +12,11 @@ class HMRouterPluginManager {
13
12
  this.nodeIgnored = new Set();
14
13
  framework_1.Logger.info('', 'HMRouterPlugin starting...');
15
14
  (0, framework_1.registerPluginExtension)(new HMRouterExtension_1.HMRouterDefaultExtension());
16
- hvigor_1.hvigor.nodesEvaluated(() => {
17
- this.initializeArkAnalyzer();
18
- this.moduleNodes.forEach((node) => {
19
- if (this.controllerMap.has(node.getNodeName())) {
20
- return;
21
- }
22
- node.getAllPluginIds().forEach((pluginId) => {
23
- this.registerPlugin(node, pluginId, {});
24
- });
25
- });
26
- for (const [_key, controller] of this.controllerMap) {
27
- controller.start();
28
- }
29
- });
15
+ hvigor_1.hvigor.nodesEvaluated(() => this.handleNodesEvaluated());
30
16
  hvigor_1.hvigor.buildFinished(() => {
31
17
  this.controllerMap.forEach((controller) => {
32
18
  controller.complete();
33
19
  });
34
- framework_1.ArkAnalyzerUtil.clear();
35
20
  HMRouterPluginManager.instance = null;
36
21
  framework_1.PluginStore.destroy();
37
22
  framework_1.ExtensionManager.destroy();
@@ -39,6 +24,22 @@ class HMRouterPluginManager {
39
24
  framework_1.TsAstUtil.clearProject();
40
25
  });
41
26
  }
27
+ handleNodesEvaluated() {
28
+ this.moduleNodes.forEach((node) => {
29
+ const nodeName = node.getNodeName();
30
+ if (this.controllerMap.has(nodeName)) {
31
+ return;
32
+ }
33
+ node.getAllPluginIds().forEach((pluginId) => {
34
+ if ((0, framework_1.isModule)(pluginId)) {
35
+ this.registerPlugin(node, pluginId, {});
36
+ }
37
+ });
38
+ });
39
+ for (const controller of this.controllerMap.values()) {
40
+ controller.start();
41
+ }
42
+ }
42
43
  static getInstance() {
43
44
  if (!HMRouterPluginManager.instance) {
44
45
  HMRouterPluginManager.instance = new HMRouterPluginManager();
@@ -76,18 +77,6 @@ class HMRouterPluginManager {
76
77
  this.nodeIgnored.add(node.getNodeName());
77
78
  }
78
79
  }
79
- initializeArkAnalyzer() {
80
- if (this.moduleNodes.length === 0) {
81
- return;
82
- }
83
- const firstNode = this.moduleNodes[0];
84
- const appContext = firstNode.getParentNode()?.getContext(hvigor_ohos_plugin_1.OhosPluginId.OHOS_APP_PLUGIN);
85
- if (appContext) {
86
- const projectPath = appContext.getProjectPath();
87
- framework_1.Logger.info('', `Initializing ArkAnalyzer for project: ${projectPath}`);
88
- framework_1.ArkAnalyzerUtil.initialize(projectPath);
89
- }
90
- }
91
80
  }
92
81
  exports.HMRouterPluginManager = HMRouterPluginManager;
93
82
  HMRouterPluginManager.instance = null;
package/dist/Index.js CHANGED
@@ -18,6 +18,7 @@ exports.appPlugin = exports.modulePlugin = exports.harPlugin = exports.hspPlugin
18
18
  const hvigor_ohos_plugin_1 = require("@ohos/hvigor-ohos-plugin");
19
19
  const constants_1 = require("./hmrouter_extension/constants");
20
20
  const HMRouterPluginManager_1 = require("./HMRouterPluginManager");
21
+ const framework_1 = require("./framework");
21
22
  __exportStar(require("./framework/utils"), exports);
22
23
  __exportStar(require("./framework/extension"), exports);
23
24
  function hapPlugin(options = {}) {
@@ -52,7 +53,9 @@ function modulePlugin(options = {}) {
52
53
  pluginId: constants_1.PluginConstants.PLUGIN_ID,
53
54
  apply(node) {
54
55
  node.getAllPluginIds().forEach((pluginId) => {
55
- HMRouterPluginManager_1.HMRouterPluginManager.getInstance().registerPlugin(node, pluginId, options);
56
+ if ((0, framework_1.isModule)(pluginId)) {
57
+ HMRouterPluginManager_1.HMRouterPluginManager.getInstance().registerPlugin(node, pluginId, options);
58
+ }
56
59
  });
57
60
  },
58
61
  };
@@ -2,3 +2,4 @@ import { HvigorNode } from '@ohos/hvigor';
2
2
  export declare function isHapModule(node: HvigorNode): boolean;
3
3
  export declare function isHarModule(node: HvigorNode): boolean;
4
4
  export declare function isHspModule(node: HvigorNode): boolean;
5
+ export declare function isModule(pluginId: string): boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isHspModule = exports.isHarModule = exports.isHapModule = void 0;
3
+ exports.isModule = exports.isHspModule = exports.isHarModule = exports.isHapModule = void 0;
4
4
  const hvigor_ohos_plugin_1 = require("@ohos/hvigor-ohos-plugin");
5
5
  function isHapModule(node) {
6
6
  return node.getAllPluginIds().includes(hvigor_ohos_plugin_1.OhosPluginId.OHOS_HAP_PLUGIN);
@@ -14,3 +14,12 @@ function isHspModule(node) {
14
14
  return node.getAllPluginIds().includes(hvigor_ohos_plugin_1.OhosPluginId.OHOS_HSP_PLUGIN);
15
15
  }
16
16
  exports.isHspModule = isHspModule;
17
+ function isModule(pluginId) {
18
+ return [
19
+ hvigor_ohos_plugin_1.OhosPluginId.OHOS_HSP_PLUGIN,
20
+ hvigor_ohos_plugin_1.OhosPluginId.OHOS_HAR_PLUGIN,
21
+ hvigor_ohos_plugin_1.OhosPluginId.OHOS_HAP_PLUGIN,
22
+ hvigor_ohos_plugin_1.OhosPluginId.OHOS_APP_PLUGIN
23
+ ].includes(pluginId);
24
+ }
25
+ exports.isModule = isModule;
@@ -5,4 +5,3 @@ export * from './ModuleTypeUtil';
5
5
  export * from './StringUtil';
6
6
  export * from './ObjectUtils';
7
7
  export * from './Logger';
8
- export * from './ArkAnalyzerUtil';
@@ -21,4 +21,3 @@ __exportStar(require("./ModuleTypeUtil"), exports);
21
21
  __exportStar(require("./StringUtil"), exports);
22
22
  __exportStar(require("./ObjectUtils"), exports);
23
23
  __exportStar(require("./Logger"), exports);
24
- __exportStar(require("./ArkAnalyzerUtil"), exports);
@@ -14,6 +14,7 @@ class RouterAnalyzer extends AbstractAnnotationAnalyzer_1.AbstractAnnotationAnal
14
14
  }
15
15
  analyze(sourceFile, filePath, context) {
16
16
  framework_1.Logger.debug('', `Start to analyze source file: ${filePath}`);
17
+ this.constantResolver.setContext(context);
17
18
  sourceFile.getChildrenOfKind(ts_morph_1.SyntaxKind.MissingDeclaration).forEach((node) => {
18
19
  const componentName = this.extractComponentNameFromNode(node);
19
20
  node.getChildrenOfKind(ts_morph_1.SyntaxKind.Decorator).forEach((decorator) => {
@@ -1,5 +1,7 @@
1
1
  import { Expression, SourceFile } from 'ts-morph';
2
+ import { HMRouterExtensionContext } from '../../HMRouterExtensionContext';
2
3
  export interface IConstantResolver {
4
+ setContext(context: HMRouterExtensionContext): void;
3
5
  resolveConstant(value: any, sourceFile: SourceFile, filePath: string): any;
4
6
  resolvePropertyValue(value: Expression, sourceFile: SourceFile, filePath: string): any;
5
7
  getVariableFilePath(variableName: string, sourceFile: SourceFile, filePath: string): string;
@@ -1,11 +1,22 @@
1
1
  import { Expression, SourceFile } from 'ts-morph';
2
2
  import { IConstantResolver } from '../interface/IConstantResolver';
3
+ import { HMRouterExtensionContext } from '../../HMRouterExtensionContext';
3
4
  export declare class ConstantResolver implements IConstantResolver {
4
5
  private importMapCache;
6
+ private importMapCacheFilePath;
7
+ private context?;
8
+ setContext(context: HMRouterExtensionContext): void;
5
9
  resolveConstant(value: any, sourceFile: SourceFile, filePath: string): any;
6
10
  resolvePropertyValue(value: Expression, sourceFile: SourceFile, filePath: string): any;
7
11
  getVariableFilePath(variableName: string, sourceFile: SourceFile, filePath: string): string;
8
12
  getOtherModuleVariableFilePath(moduleName: string, variableName: string): string;
13
+ private findExportInFile;
14
+ private isFileExists;
15
+ private findLocalDefinition;
16
+ private findReExportedDeclaration;
17
+ private findReExport;
18
+ private shouldCheckReExport;
19
+ private findNamedExport;
9
20
  private parsePrimitiveValue;
10
21
  private parseConstantValue;
11
22
  }
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.ConstantResolver = void 0;
4
7
  const ts_morph_1 = require("ts-morph");
@@ -6,9 +9,14 @@ const framework_1 = require("../../../framework");
6
9
  const constants_1 = require("../../constants");
7
10
  const ImportAnalyzer_1 = require("./ImportAnalyzer");
8
11
  const PluginError_1 = require("../../error/PluginError");
12
+ const path_1 = __importDefault(require("path"));
9
13
  class ConstantResolver {
10
14
  constructor() {
11
15
  this.importMapCache = new Map();
16
+ this.importMapCacheFilePath = [];
17
+ }
18
+ setContext(context) {
19
+ this.context = context;
12
20
  }
13
21
  resolveConstant(value, sourceFile, filePath) {
14
22
  if (value.type === 'constant') {
@@ -94,14 +102,141 @@ class ConstantResolver {
94
102
  return resultPath;
95
103
  }
96
104
  getOtherModuleVariableFilePath(moduleName, variableName) {
97
- if (framework_1.ArkAnalyzerUtil.isReady()) {
98
- const filePath = framework_1.ArkAnalyzerUtil.findVariableFilePath(moduleName, variableName);
99
- if (filePath) {
100
- return filePath;
105
+ const dependencies = this.context?.moduleContext.getOhpmDependencyInfo() || {};
106
+ for (const [dependencyName, dependencyInfo] of Object.entries(dependencies)) {
107
+ if (moduleName.indexOf(dependencyName) === 0) {
108
+ const cacheImport = this.importMapCacheFilePath.find((f) => f.dependencyName === dependencyName &&
109
+ f.importConstantName === variableName && f.importPath === moduleName);
110
+ if (cacheImport) {
111
+ return cacheImport.importFullPath;
112
+ }
113
+ const isFullPathImport = dependencyName !== moduleName;
114
+ let dependencyFilePath = '';
115
+ if (isFullPathImport) {
116
+ dependencyFilePath = dependencyInfo.packagePath + moduleName.replace(dependencyName, '') + constants_1.FilePathConstants.ETS_SUFFIX;
117
+ }
118
+ else {
119
+ const dependPackageFileName = framework_1.PluginFileUtil.readJson5(framework_1.PluginFileUtil.pathResolve(dependencyInfo.packagePath, constants_1.FilePathConstants.OH_PACKAGE_FILE_NAME));
120
+ dependencyFilePath = framework_1.PluginFileUtil.pathResolve(dependencyInfo.packagePath, dependPackageFileName.main || 'Index.ets');
121
+ }
122
+ const path = this.findExportInFile(dependencyFilePath, variableName);
123
+ if (path) {
124
+ this.importMapCacheFilePath.push({
125
+ dependencyName: dependencyName,
126
+ importPath: moduleName,
127
+ importConstantName: variableName,
128
+ importFullPath: path
129
+ });
130
+ return path;
131
+ }
101
132
  }
102
133
  }
103
134
  throw PluginError_1.PluginError.create(PluginError_1.ErrorCode.UNKNOWN_VARIABLE, '', variableName);
104
135
  }
136
+ findExportInFile(filePath, variableName) {
137
+ if (!this.isFileExists(filePath)) {
138
+ return undefined;
139
+ }
140
+ const sourceFile = framework_1.TsAstUtil.getSourceFile(filePath);
141
+ const localDefinitionPath = this.findLocalDefinition(sourceFile, filePath, variableName);
142
+ if (localDefinitionPath) {
143
+ return localDefinitionPath;
144
+ }
145
+ const reExportedPath = this.findReExportedDeclaration(sourceFile, filePath, variableName);
146
+ if (reExportedPath) {
147
+ return reExportedPath;
148
+ }
149
+ const namedExportPath = this.findNamedExport(sourceFile, filePath, variableName);
150
+ if (namedExportPath) {
151
+ return namedExportPath;
152
+ }
153
+ return undefined;
154
+ }
155
+ isFileExists(filePath) {
156
+ if (!framework_1.PluginFileUtil.exist(filePath)) {
157
+ const alternativePath = filePath.replace(constants_1.FilePathConstants.ETS_SUFFIX, constants_1.FilePathConstants.D_ETS_SUFFIX);
158
+ return framework_1.PluginFileUtil.exist(alternativePath);
159
+ }
160
+ return true;
161
+ }
162
+ findLocalDefinition(sourceFile, filePath, variableName) {
163
+ const localDefinitions = [
164
+ ...sourceFile.getVariableDeclarations(),
165
+ ...sourceFile.getClasses(),
166
+ ...sourceFile.getInterfaces(),
167
+ ].filter(node => node.getName() === variableName);
168
+ if (localDefinitions.length > 0) {
169
+ framework_1.Logger.debug('', `Object "${variableName}" is defined locally in file: ${filePath}`);
170
+ return filePath;
171
+ }
172
+ return undefined;
173
+ }
174
+ findReExportedDeclaration(sourceFile, filePath, variableName) {
175
+ const exportDeclarations = sourceFile.getExportDeclarations();
176
+ for (const exportDecl of exportDeclarations) {
177
+ const moduleSpecifier = exportDecl.getModuleSpecifierValue();
178
+ if (!moduleSpecifier) {
179
+ continue;
180
+ }
181
+ if (!this.shouldCheckReExport(exportDecl, variableName)) {
182
+ continue;
183
+ }
184
+ const originalDefinitionPath = this.findReExport(moduleSpecifier, filePath, variableName);
185
+ if (originalDefinitionPath) {
186
+ return originalDefinitionPath;
187
+ }
188
+ }
189
+ for (const exportDecl of exportDeclarations) {
190
+ const moduleSpecifier = exportDecl.getModuleSpecifierValue();
191
+ if (!moduleSpecifier) {
192
+ continue;
193
+ }
194
+ if (!exportDecl.isNamespaceExport()) {
195
+ continue;
196
+ }
197
+ const originalDefinitionPath = this.findReExport(moduleSpecifier, filePath, variableName);
198
+ if (originalDefinitionPath) {
199
+ return originalDefinitionPath;
200
+ }
201
+ }
202
+ return undefined;
203
+ }
204
+ findReExport(moduleSpecifier, filePath, variableName) {
205
+ const resolvedPath = framework_1.PluginFileUtil.pathResolve(path_1.default.dirname(filePath), moduleSpecifier + constants_1.FilePathConstants.ETS_SUFFIX);
206
+ const originalDefinitionPath = this.findExportInFile(resolvedPath, variableName);
207
+ if (originalDefinitionPath) {
208
+ framework_1.Logger.debug('', `Object "${variableName}" is re-exported from: ${resolvedPath}`);
209
+ return originalDefinitionPath;
210
+ }
211
+ return undefined;
212
+ }
213
+ shouldCheckReExport(exportDecl, variableName) {
214
+ const namedExports = exportDecl.getNamedExports();
215
+ if (namedExports.some(specifier => specifier.getAliasNode()?.getText() === variableName || specifier.getName() === variableName)) {
216
+ return true;
217
+ }
218
+ return false;
219
+ }
220
+ findNamedExport(sourceFile, filePath, variableName) {
221
+ const exportSpecifiers = sourceFile.getExportedDeclarations().get(variableName);
222
+ if (!exportSpecifiers || exportSpecifiers.length === 0) {
223
+ return undefined;
224
+ }
225
+ const exportSpecifier = exportSpecifiers[0];
226
+ const symbol = exportSpecifier.getSymbol();
227
+ if (!symbol) {
228
+ return undefined;
229
+ }
230
+ const definitions = symbol.getDeclarations();
231
+ for (const definition of definitions) {
232
+ const definitionFilePath = definition.getSourceFile().getFilePath();
233
+ if (definitionFilePath !== filePath) {
234
+ framework_1.Logger.debug('', `Object "${variableName}" is exported from: ${definitionFilePath}`);
235
+ return definitionFilePath;
236
+ }
237
+ }
238
+ return undefined;
239
+ }
105
240
  parsePrimitiveValue(value) {
106
241
  let propertyValue;
107
242
  switch (value.getKind()) {
@@ -6,6 +6,7 @@ export default class FilePathConstants {
6
6
  static readonly TEMP_ROUTER_MAP_PATH = "../../intermediates/router_map";
7
7
  static readonly RAWFILE_DIR = "src/main/resources/rawfile/hm_router_map.json";
8
8
  static readonly ETS_SUFFIX = ".ets";
9
+ static readonly D_ETS_SUFFIX = ".d.ets";
9
10
  static readonly JSON_SUFFIX = ".json";
10
11
  static readonly CONFIG_FILE_NAME = "hmrouter_config.json";
11
12
  static readonly PARENT_DELIMITER = "../";
@@ -14,6 +14,7 @@ FilePathConstants.DELIMITER = '/';
14
14
  FilePathConstants.TEMP_ROUTER_MAP_PATH = '../../intermediates/router_map';
15
15
  FilePathConstants.RAWFILE_DIR = 'src/main/resources/rawfile/hm_router_map.json';
16
16
  FilePathConstants.ETS_SUFFIX = '.ets';
17
+ FilePathConstants.D_ETS_SUFFIX = '.d.ets';
17
18
  FilePathConstants.JSON_SUFFIX = '.json';
18
19
  FilePathConstants.CONFIG_FILE_NAME = 'hmrouter_config.json';
19
20
  FilePathConstants.PARENT_DELIMITER = '../';
@@ -18,7 +18,6 @@ class RouterMapBuildingProcessor {
18
18
  }
19
19
  generateRouterMapFile() {
20
20
  let set = new Set();
21
- framework_1.Logger.info(this.context.node.getNodeName(), `Start to build router map...${JSON.stringify(this.context.routerMap)}`);
22
21
  this.context.routerMap.forEach((item) => {
23
22
  if (set.has(item.name)) {
24
23
  throw PluginError_1.PluginError.create(PluginError_1.ErrorCode.DUPLICATE_NAME, this.context.config.moduleName, item.name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hadss/hmrouter-plugin",
3
- "version": "1.2.3-rc.2",
3
+ "version": "1.2.3",
4
4
  "description": "HMRouter Compiler Plugin",
5
5
  "main": "dist/Index.js",
6
6
  "scripts": {
@@ -21,8 +21,7 @@
21
21
  "dependencies": {
22
22
  "ejs": "^3.1.10",
23
23
  "micromatch": "^4.0.8",
24
- "ts-morph": "^23.0.0",
25
- "arkanalyzer": "^1.0.79"
24
+ "ts-morph": "^23.0.0"
26
25
  },
27
26
  "devDependencies": {
28
27
  "@ohos/hvigor": "^5.8.9",
@@ -1,24 +0,0 @@
1
- export declare class ArkAnalyzerUtil {
2
- private static instance;
3
- private scene;
4
- private isInitialized;
5
- private constructor();
6
- static getInstance(): ArkAnalyzerUtil;
7
- init(projectRoot: string): boolean;
8
- isReady(): boolean;
9
- findVariableFilePath(moduleName: string, variableName: string): string | undefined;
10
- private findInAllFiles;
11
- private isModuleMatch;
12
- private findExportInFile;
13
- private traceToDefinition;
14
- private findFileByPath;
15
- private normalizeModuleName;
16
- private isAbsolutePathImport;
17
- private extractBaseModuleName;
18
- private isAbsolutePathMatch;
19
- clear(): void;
20
- static isReady(): boolean;
21
- static findVariableFilePath(moduleName: string, variableName: string): string | undefined;
22
- static initialize(projectRoot: string): void;
23
- static clear(): void;
24
- }
@@ -1,198 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ArkAnalyzerUtil = void 0;
7
- const arkanalyzer_1 = require("arkanalyzer");
8
- const Logger_1 = require("./Logger");
9
- const path_1 = __importDefault(require("path"));
10
- class ArkAnalyzerUtil {
11
- constructor() {
12
- this.scene = null;
13
- this.isInitialized = false;
14
- }
15
- static getInstance() {
16
- if (!ArkAnalyzerUtil.instance) {
17
- ArkAnalyzerUtil.instance = new ArkAnalyzerUtil();
18
- }
19
- return ArkAnalyzerUtil.instance;
20
- }
21
- init(projectRoot) {
22
- if (this.isInitialized) {
23
- return true;
24
- }
25
- try {
26
- this.scene = new arkanalyzer_1.Scene();
27
- const options = {
28
- supportFileExts: ['.ets', '.d.ets'],
29
- projectName: 'HMRouterProject'
30
- };
31
- const config = new arkanalyzer_1.SceneConfig(options);
32
- config.buildFromProjectDir(projectRoot);
33
- this.scene.buildSceneFromProjectDir(config);
34
- this.scene.buildScene4HarmonyProject();
35
- this.scene.inferTypes();
36
- this.isInitialized = true;
37
- Logger_1.Logger.info('ArkAnalyzerUtil', 'Initialized successfully');
38
- return true;
39
- }
40
- catch (e) {
41
- Logger_1.Logger.error('ArkAnalyzerUtil', `Failed to initialize: ${e}`);
42
- return false;
43
- }
44
- }
45
- isReady() {
46
- return this.isInitialized && this.scene !== null;
47
- }
48
- findVariableFilePath(moduleName, variableName) {
49
- if (!this.scene) {
50
- throw new Error('ArkAnalyzer scene not initialized');
51
- }
52
- return this.findInAllFiles(moduleName, variableName);
53
- }
54
- findInAllFiles(moduleName, variableName) {
55
- const normalizedModuleName = this.normalizeModuleName(moduleName);
56
- const files = this.scene.getFiles();
57
- const isAbsolutePathImport = this.isAbsolutePathImport(moduleName);
58
- const baseModuleName = isAbsolutePathImport ? this.extractBaseModuleName(moduleName) : moduleName;
59
- for (const arkFile of files) {
60
- if (isAbsolutePathImport) {
61
- if (!this.isAbsolutePathMatch(arkFile, moduleName, baseModuleName)) {
62
- continue;
63
- }
64
- }
65
- else {
66
- if (!this.isModuleMatch(arkFile, moduleName, normalizedModuleName)) {
67
- continue;
68
- }
69
- }
70
- const result = this.findExportInFile(arkFile, variableName, isAbsolutePathImport);
71
- if (result) {
72
- return result;
73
- }
74
- }
75
- return undefined;
76
- }
77
- isModuleMatch(arkFile, moduleName, normalizedModuleName) {
78
- const fileModuleName = arkFile.getModuleName() || arkFile.getModuleScene()?.getModuleName() || '';
79
- const normalizedFileModule = this.normalizeModuleName(fileModuleName);
80
- if (fileModuleName === moduleName) {
81
- return true;
82
- }
83
- if (fileModuleName.toLowerCase() === moduleName.toLowerCase()) {
84
- return true;
85
- }
86
- if (normalizedFileModule.toLowerCase() === normalizedModuleName.toLowerCase()) {
87
- return true;
88
- }
89
- return false;
90
- }
91
- findExportInFile(arkFile, variableName, isAbsolutePathImport = false) {
92
- const exportInfos = arkFile.getExportInfos();
93
- for (const exportInfo of exportInfos) {
94
- if (exportInfo.getExportClauseName() === variableName) {
95
- return this.traceToDefinition(exportInfo, arkFile);
96
- }
97
- }
98
- if (isAbsolutePathImport) {
99
- for (const exportInfo of exportInfos) {
100
- if (exportInfo.isDefault()) {
101
- return this.traceToDefinition(exportInfo, arkFile);
102
- }
103
- }
104
- }
105
- return undefined;
106
- }
107
- traceToDefinition(exportInfo, currentFile) {
108
- const fromPath = exportInfo.getFrom();
109
- if (!fromPath) {
110
- return exportInfo.getDeclaringArkFile().getFilePath();
111
- }
112
- const currentDir = path_1.default.dirname(currentFile.getFilePath());
113
- let targetPath = path_1.default.resolve(currentDir, fromPath);
114
- if (!targetPath.endsWith('.ets') && !targetPath.endsWith('.d.ets')) {
115
- targetPath += '.ets';
116
- }
117
- const targetFile = this.findFileByPath(targetPath);
118
- if (!targetFile) {
119
- return currentFile.getFilePath();
120
- }
121
- const variableName = exportInfo.getNameBeforeAs() || exportInfo.getExportClauseName();
122
- const targetExports = targetFile.getExportInfos();
123
- for (const targetExport of targetExports) {
124
- if (targetExport.getExportClauseName() === variableName) {
125
- return this.traceToDefinition(targetExport, targetFile);
126
- }
127
- }
128
- return targetFile.getFilePath();
129
- }
130
- findFileByPath(filePath) {
131
- const files = this.scene.getFiles();
132
- for (const arkFile of files) {
133
- if (arkFile.getFilePath() === filePath) {
134
- return arkFile;
135
- }
136
- }
137
- return undefined;
138
- }
139
- normalizeModuleName(moduleName) {
140
- if (moduleName.startsWith('@')) {
141
- const parts = moduleName.split('/');
142
- return parts.length >= 2 ? parts[1] : moduleName;
143
- }
144
- return moduleName;
145
- }
146
- isAbsolutePathImport(moduleName) {
147
- return moduleName.includes('/src/') || moduleName.includes('/ets/');
148
- }
149
- extractBaseModuleName(moduleName) {
150
- const normalized = this.normalizeModuleName(moduleName);
151
- const srcIndex = normalized.indexOf('/src/');
152
- const etsIndex = normalized.indexOf('/ets/');
153
- let splitIndex = -1;
154
- if (srcIndex !== -1 && etsIndex !== -1) {
155
- splitIndex = Math.min(srcIndex, etsIndex);
156
- }
157
- else if (srcIndex !== -1) {
158
- splitIndex = srcIndex;
159
- }
160
- else if (etsIndex !== -1) {
161
- splitIndex = etsIndex;
162
- }
163
- if (splitIndex !== -1) {
164
- return normalized.substring(0, splitIndex);
165
- }
166
- return normalized;
167
- }
168
- isAbsolutePathMatch(arkFile, fullModuleName, baseModuleName) {
169
- const fileModuleName = arkFile.getModuleName() || arkFile.getModuleScene()?.getModuleName() || '';
170
- if (fileModuleName !== baseModuleName &&
171
- fileModuleName.toLowerCase() !== baseModuleName.toLowerCase()) {
172
- return false;
173
- }
174
- const filePath = arkFile.getFilePath().replaceAll('\\', '/');
175
- const subPath = fullModuleName.substring(baseModuleName.length);
176
- return filePath.includes(subPath) || filePath.includes(subPath + '.ets');
177
- }
178
- clear() {
179
- if (this.scene) {
180
- this.scene.dispose();
181
- this.scene = null;
182
- }
183
- this.isInitialized = false;
184
- }
185
- static isReady() {
186
- return ArkAnalyzerUtil.getInstance().isReady();
187
- }
188
- static findVariableFilePath(moduleName, variableName) {
189
- return ArkAnalyzerUtil.getInstance().findVariableFilePath(moduleName, variableName);
190
- }
191
- static initialize(projectRoot) {
192
- ArkAnalyzerUtil.getInstance().init(projectRoot);
193
- }
194
- static clear() {
195
- ArkAnalyzerUtil.getInstance().clear();
196
- }
197
- }
198
- exports.ArkAnalyzerUtil = ArkAnalyzerUtil;