@hadss/hmrouter-plugin 1.0.0-rc.5 → 1.0.0-rc.6

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/.mocharc.js ADDED
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Copyright (c) 2024 Huawei Device Co., Ltd.
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+
16
+ 'use strict';
17
+
18
+ module.exports = {
19
+ extension: ['ts'],
20
+ require: 'ts-node/register',
21
+ spec: process.env.TEST_ENV === 'unit' ? 'tests/**/Unit.test.ts' : 'tests/**/*.test.ts',
22
+ recursive: true
23
+ }
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  ```json5
5
5
  {
6
6
  "dependencies": {
7
- "@hadss/hmrouter-plugin": "^1.0.0-rc.4" // 使用npm仓版本号
7
+ "@hadss/hmrouter-plugin": "^1.0.0-rc.6" // 使用npm仓版本号
8
8
  },
9
9
  // ...其他配置
10
10
  }
@@ -28,13 +28,24 @@ export default {
28
28
  {
29
29
  // 如果不配置则扫描src/main/ets目录,对代码进行全量扫描,如果配置则数组不能为空,建议配置指定目录可缩短编译耗时
30
30
  "scanDir": ["src/main/ets/components","src/main/ets/interceptors"],
31
- "saveGeneratedFile": false, // 默认为false,调试排除错误时可以改成true,不删除编译产物
31
+ "saveGeneratedFile": false, // 默认为false,调试排除错误时可以改成true,不删除编译产物,
32
+ "autoObfuscation": true // 默认为false,不自动配置混淆规则,只会生成hmrouter_obfuscation_rules.txt文件帮助开发者配置混淆规则;如果设置为true,会自动配置混淆规则,并在编译完成后删除hmrouter_obfuscation_rules.txt文件
32
33
  }
33
34
  ```
34
35
 
36
+ ### hmrouter_config.json配置
37
+
38
+ `hmrouter_config.json`文件用于配置编译插件`@hadss/hmrouter-plugin`在编译期的行为
39
+
35
40
  > 配置文件读取规则为 模块 > 工程 > 默认
36
41
  > 优先使用本模块内的配置,如果没有配置,则找模块目录的上级目录(最多找三层目录,找到则停止),若找不到则使用默认配置
37
42
 
43
+ | 配置项 | 类型 | 是否必填 | 说明 |
44
+ |-------------------|---------|------|--------------------------------------------------------------------------------------------------------------------------------------|
45
+ | scanDir | array | 否 | 扫描当前模块使用HMRouter装饰器的路径,缺省值为`"src/main/ets"` |
46
+ | saveGeneratedFile | boolean | 否 | 默认为false,不保留插件自动生成的代码,如果需要保留,需要设置为true |
47
+ | autoObfuscation | boolean | 否 | 默认为false,不自动配置混淆规则,只会生成`hmrouter_obfuscation_rules.txt`文件帮助开发者配置混淆规则;如果设置为true,会自动配置混淆规则,并在编译完成后删除`hmrouter_obfuscation_rules.txt`文件 |
48
+
38
49
  ## HMRouter使用
39
50
 
40
51
  详见[@hadss/hmrouter](https://ohpm.openharmony.cn/#/cn/detail/@hadss%2Fhmrouter)
@@ -1,40 +1,8 @@
1
1
  import { HMRouterPluginConfig } from './HMRouterPluginConfig';
2
2
  import { AnalyzerResultLike } from './common/PluginModel';
3
- export declare class Analyzer {
4
- analyzeResultSet: Set<AnalyzerResultLike>;
5
- private readonly sourcePath;
6
- private readonly pluginConfig;
3
+ export declare class AnalyzerController {
7
4
  private analyzeResult;
8
- private classMethodAnalyzeResult;
9
- private keywordPos;
10
- private importMap;
11
- constructor(sourcePath: string, pluginConfig: HMRouterPluginConfig);
12
- start(): void;
13
- private resolveNode;
14
- private resolveImportDeclaration;
15
- private resolveMissingDeclaration;
16
- private isDecoratedClass;
17
- private resolveClass;
18
- private resolveClassMethod;
19
- private resolveDecorator;
20
- private switchIdentifier;
21
- private resolveCallExpression;
22
- private resolveExpression;
23
- private resolveBlock;
24
- private parseAnnotation;
25
- private parseConfig;
26
- private resolvePropertyAccess;
27
- private resolveIdentifier;
28
- private resolveArrayLiteral;
29
- private resolveNumericLiteral;
30
- private resolveStringLiteral;
31
- private resolveTrueKeyword;
32
- private resolveFalseKeyword;
33
- private getSourceFile;
34
- private findConstantValueInSourceFile;
35
- private findObjectValueInSourceFile;
36
- private resolveConstantValue;
37
- private resolveObjectValue;
38
- private resolvePath;
39
- private parseVariableDeclaration;
5
+ analyzeFile(sourceFilePath: string, config: HMRouterPluginConfig): void;
6
+ parsePageUrl(): void;
7
+ getAnalyzeResultSet(): Set<AnalyzerResultLike>;
40
8
  }
@@ -3,334 +3,242 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Analyzer = void 0;
7
- const typescript_1 = __importDefault(require("typescript"));
8
- const hvigor_1 = require("@ohos/hvigor");
6
+ exports.AnalyzerController = void 0;
7
+ const ts_morph_1 = require("ts-morph");
9
8
  const Logger_1 = require("./common/Logger");
10
- const Constant_1 = require("./common/Constant");
11
- class NodeInfo {
12
- }
13
- class Analyzer {
14
- constructor(sourcePath, pluginConfig) {
15
- this.analyzeResultSet = new Set();
16
- this.analyzeResult = {};
17
- this.classMethodAnalyzeResult = new Set();
18
- this.keywordPos = 0;
19
- this.importMap = new Map();
20
- this.sourcePath = sourcePath;
21
- this.pluginConfig = pluginConfig;
9
+ const TsAstUtil_1 = require("./utils/TsAstUtil");
10
+ const CommonConstants_1 = __importDefault(require("./constants/CommonConstants"));
11
+ const FileUtil_1 = __importDefault(require("./utils/FileUtil"));
12
+ class AnalyzerController {
13
+ constructor() {
14
+ this.analyzeResult = new Set();
15
+ }
16
+ analyzeFile(sourceFilePath, config) {
17
+ let analyzerService = new AnalyzerService(sourceFilePath, config);
18
+ analyzerService.start();
19
+ analyzerService.getResult().forEach(item => {
20
+ item.pageSourceFile = sourceFilePath;
21
+ this.analyzeResult.add(item);
22
+ });
23
+ this.parsePageUrl();
22
24
  }
23
- start() {
24
- const sourceCode = hvigor_1.FileUtil.readFileSync(this.sourcePath).toString();
25
- const sourceFile = typescript_1.default.createSourceFile(this.sourcePath, sourceCode, typescript_1.default.ScriptTarget.ES2021, false);
26
- typescript_1.default.forEachChild(sourceFile, node => {
27
- this.resolveNode(node);
28
- if (this.analyzeResult.annotation) {
29
- this.analyzeResultSet.add(this.analyzeResult);
25
+ parsePageUrl() {
26
+ this.analyzeResult.forEach((item) => {
27
+ if (item.annotation !== 'HMRouter') {
28
+ return;
30
29
  }
31
- if (this.classMethodAnalyzeResult.size > 0) {
32
- this.analyzeResultSet = new Set([...this.analyzeResultSet, ...this.classMethodAnalyzeResult]);
30
+ let pageUrl = item.pageUrl;
31
+ if (pageUrl.type === 'constant') {
32
+ pageUrl =
33
+ TsAstUtil_1.TsAstUtil.parseConstantValue(TsAstUtil_1.project.addSourceFileAtPath(pageUrl.variableFilePath), pageUrl.variableName);
33
34
  }
34
- });
35
- this.analyzeResultSet.forEach(value => {
36
- if (value.annotation === 'HMRouter') {
37
- let hmRouterResult = value;
38
- if (hmRouterResult.pageUrl.type === 'constant') {
39
- hmRouterResult.pageUrl = this.resolveConstantValue(hmRouterResult.pageUrl.value);
40
- }
41
- else if (hmRouterResult.pageUrl.type === 'object') {
42
- hmRouterResult.pageUrl =
43
- this.resolveObjectValue(hmRouterResult.pageUrl.className, hmRouterResult.pageUrl.propertyName);
44
- }
35
+ else if (pageUrl.type === 'object') {
36
+ pageUrl = TsAstUtil_1.TsAstUtil.parseConstantValue(TsAstUtil_1.project.addSourceFileAtPath(pageUrl.variableFilePath), pageUrl.variableName, pageUrl.propertyName);
45
37
  }
46
- });
47
- }
48
- resolveNode(node) {
49
- if (typescript_1.default.isImportDeclaration(node)) {
50
- this.resolveImportDeclaration(node);
51
- }
52
- else if (typescript_1.default.isMissingDeclaration(node)) {
53
- this.resolveMissingDeclaration(node);
54
- }
55
- else if (typescript_1.default.isClassDeclaration(node)) {
56
- this.isDecoratedClass(node) ? this.resolveClass(node) : this.resolveClassMethod(node);
57
- }
58
- else if (typescript_1.default.isDecorator(node)) {
59
- this.resolveDecorator(node);
60
- }
61
- else if (typescript_1.default.isCallExpression(node)) {
62
- this.resolveCallExpression(node);
63
- }
64
- else if (typescript_1.default.isExpressionStatement(node)) {
65
- this.resolveExpression(node);
66
- }
67
- else if (typescript_1.default.isBlock(node)) {
68
- this.resolveBlock(node);
69
- }
70
- else if (typescript_1.default.isPropertyAssignment(node)) {
71
- return this.resolvePropertyAccess(node);
72
- }
73
- else if (typescript_1.default.isIdentifier(node)) {
74
- return this.resolveIdentifier(node);
75
- }
76
- else if (typescript_1.default.isStringLiteral(node)) {
77
- return this.resolveStringLiteral(node);
78
- }
79
- else if (typescript_1.default.isNumericLiteral(node)) {
80
- return this.resolveNumericLiteral(node);
81
- }
82
- else if (typescript_1.default.isArrayLiteralExpression(node)) {
83
- return this.resolveArrayLiteral(node);
84
- }
85
- else if (node.kind === typescript_1.default.SyntaxKind.TrueKeyword) {
86
- return this.resolveTrueKeyword();
87
- }
88
- else if (node.kind === typescript_1.default.SyntaxKind.FalseKeyword) {
89
- return this.resolveFalseKeyword();
90
- }
91
- }
92
- resolveImportDeclaration(node) {
93
- let variableArr = [];
94
- node.importClause?.namedBindings?.forEachChild(child => {
95
- if (typescript_1.default.isImportSpecifier(child)) {
96
- variableArr.push(child.name.escapedText);
38
+ if (pageUrl === '') {
39
+ Logger_1.Logger.error(Logger_1.PluginError.ERR_NOT_EMPTY_STRING);
40
+ throw new Error('constant value cannot be an empty string');
97
41
  }
42
+ item.pageUrl = pageUrl;
98
43
  });
99
- variableArr.push(node.importClause?.name?.text);
100
- let key = node.moduleSpecifier;
101
- if (typescript_1.default.isModuleName(key)) {
102
- this.importMap.set(key.text, variableArr);
103
- }
104
44
  }
105
- resolveMissingDeclaration(node) {
106
- this.analyzeResult = {};
107
- node.forEachChild(child => this.resolveNode(child));
45
+ getAnalyzeResultSet() {
46
+ return this.analyzeResult;
108
47
  }
109
- isDecoratedClass(node) {
110
- return node.modifiers?.some((item) => Constant_1.HMRouterPluginConstant.CLASS_ANNOTATION_ARR.includes(item.expression?.expression?.text));
48
+ }
49
+ exports.AnalyzerController = AnalyzerController;
50
+ class AnalyzerService {
51
+ constructor(sourceFilePath, config) {
52
+ this.analyzerResultSet = new Set();
53
+ this.importMap = new Map();
54
+ this.sourceFilePath = sourceFilePath;
55
+ this.sourceFile = TsAstUtil_1.TsAstUtil.getSourceFile(sourceFilePath);
56
+ this.config = config;
111
57
  }
112
- resolveClass(node) {
113
- this.analyzeResult = {};
114
- node.modifiers?.forEach(modifier => {
115
- this.resolveNode(modifier);
58
+ start() {
59
+ this.analyzeImport();
60
+ this.analyzeRouter();
61
+ this.analyzeComponent();
62
+ this.parseFileByLineOrder();
63
+ }
64
+ getResult() {
65
+ let HMRouterNum = 0;
66
+ this.analyzerResultSet.forEach((analyzerResult) => {
67
+ if (analyzerResult.annotation === CommonConstants_1.default.ROUTER_ANNOTATION) {
68
+ HMRouterNum++;
69
+ }
116
70
  });
117
- if (this.analyzeResult.annotation) {
118
- this.analyzeResult.name = node.name?.text;
119
- }
120
- }
121
- resolveClassMethod(node) {
122
- this.classMethodAnalyzeResult = new Set([]);
123
- node.members?.forEach((member) => {
124
- this.analyzeResult = {};
125
- if (typescript_1.default.isMethodDeclaration(member) && member.modifiers) {
126
- member.modifiers?.forEach((modifier) => {
127
- this.resolveNode(modifier);
71
+ if (HMRouterNum > 1) {
72
+ Logger_1.Logger.error(Logger_1.PluginError.ERR_REPEAT_ANNOTATION, this.sourceFilePath);
73
+ throw new Error(`文件${this.sourceFilePath}中存在多个HMRouter注解`);
74
+ }
75
+ return this.analyzerResultSet;
76
+ }
77
+ analyzeImport() {
78
+ this.sourceFile.getImportDeclarations().forEach(importDeclaration => {
79
+ const moduleSpecifier = importDeclaration.getModuleSpecifierValue();
80
+ const namedImports = importDeclaration.getNamedImports().map(namedImport => namedImport.getName());
81
+ const defaultImport = importDeclaration.getDefaultImport()?.getText();
82
+ const namespaceImport = importDeclaration.getNamespaceImport()?.getText();
83
+ const importNames = [];
84
+ if (namedImports.length > 0) {
85
+ importNames.push(...namedImports);
86
+ }
87
+ if (defaultImport) {
88
+ importNames.push(defaultImport);
89
+ }
90
+ if (namespaceImport) {
91
+ importNames.push(namespaceImport);
92
+ }
93
+ if (importNames.length > 0) {
94
+ let variableFilePath = FileUtil_1.default.pathResolve(this.config.modulePath, moduleSpecifier);
95
+ importNames.forEach((item) => {
96
+ if (FileUtil_1.default.exist(variableFilePath)) {
97
+ TsAstUtil_1.importVariableCache.set(variableFilePath + CommonConstants_1.default.VARIABLE_SEPARATOR + item, '');
98
+ }
128
99
  });
129
- this.analyzeResult.functionName = member.name?.text;
130
- this.analyzeResult.name = node.name?.text;
131
- if (this.analyzeResult.annotation) {
132
- this.classMethodAnalyzeResult.add(this.analyzeResult);
133
- }
134
- this.analyzeResult = {};
100
+ this.importMap.set(moduleSpecifier, importNames);
135
101
  }
136
102
  });
137
103
  }
138
- resolveDecorator(node) {
139
- if (typescript_1.default.isCallExpression(node.expression)) {
140
- const callExpression = node.expression;
141
- if (typescript_1.default.isIdentifier(callExpression.expression)) {
142
- this.switchIdentifier(callExpression);
143
- }
144
- }
145
- }
146
- switchIdentifier(callExpression) {
147
- const identifier = callExpression.expression;
148
- if (this.pluginConfig.annotation.some(item => item === identifier.text)) {
149
- this.analyzeResult.annotation = identifier.text;
150
- this.resolveNode(callExpression);
151
- }
152
- }
153
- resolveCallExpression(node) {
154
- let identifier = this.resolveNode(node.expression);
155
- this.parseAnnotation(node.arguments, identifier);
156
- }
157
- resolveExpression(node) {
158
- let identifier = this.resolveNode(node.expression);
159
- if (identifier?.value === 'struct') {
160
- this.keywordPos = node.end;
161
- }
162
- if (this.analyzeResult.annotation === 'HMRouter' && this.keywordPos === node.pos) {
163
- this.analyzeResult.name = identifier?.value;
164
- }
165
- }
166
- resolveBlock(node) {
167
- node.statements.forEach(statement => {
168
- this.resolveNode(statement);
104
+ analyzeRouter() {
105
+ let viewNameArr = this.sourceFile.getChildrenOfKind(ts_morph_1.SyntaxKind.ExpressionStatement).map((node) => {
106
+ return node.getText();
107
+ }).filter((text) => {
108
+ return text != 'struct';
169
109
  });
170
- }
171
- parseAnnotation(args, nodeInfo) {
172
- if (this.pluginConfig.annotation.some(item => nodeInfo?.value === item)) {
173
- args
174
- .flatMap((e) => e.properties)
175
- .forEach((e) => {
176
- this.parseConfig(e, this.analyzeResult);
110
+ this.sourceFile.getChildrenOfKind(ts_morph_1.SyntaxKind.MissingDeclaration).forEach((node, index) => {
111
+ node.getChildrenOfKind(ts_morph_1.SyntaxKind.Decorator).forEach((decorator) => {
112
+ this.addToResultSet(decorator, viewNameArr[index]);
177
113
  });
178
- }
179
- }
180
- parseConfig(node, result) {
181
- let info = this.resolveNode(node);
182
- Reflect.set(result, info?.value['key'], info?.value['value']);
114
+ });
183
115
  }
184
- resolvePropertyAccess(node) {
185
- let propertyName = this.resolveNode(node.name)?.value;
186
- let propertyValue;
187
- if (propertyName === 'pageUrl') {
188
- if (node.initializer.kind === typescript_1.default.SyntaxKind.Identifier) {
189
- propertyValue = {
190
- type: 'constant',
191
- value: this.resolveNode(node.initializer)?.value
192
- };
116
+ parseFileByLineOrder() {
117
+ const statements = this.sourceFile.getStatements();
118
+ const sortedStatements = statements.sort((a, b) => a.getStart() - b.getStart());
119
+ let HMRouterExists = false;
120
+ sortedStatements.forEach(statement => {
121
+ if (statement.getKind() === ts_morph_1.SyntaxKind.MissingDeclaration && statement.getText().includes('HMRouter')) {
122
+ HMRouterExists = true;
193
123
  }
194
- else if (node.initializer.kind === typescript_1.default.SyntaxKind.PropertyAccessExpression) {
195
- propertyValue = {
196
- type: 'object',
197
- className: this.resolveNode(node.initializer.expression)?.value,
198
- propertyName: this.resolveNode(node.initializer.name)?.value
199
- };
200
- }
201
- else {
202
- propertyValue = this.resolveNode(node.initializer)?.value;
124
+ if (statement.getKind() === ts_morph_1.SyntaxKind.Block && HMRouterExists) {
125
+ HMRouterExists = false;
126
+ statement.getDescendantsOfKind(ts_morph_1.SyntaxKind.Identifier).forEach((node) => {
127
+ if (node.getText() === 'NavDestination') {
128
+ Logger_1.Logger.error(Logger_1.PluginError.ERR_WRONG_DECORATION);
129
+ throw new Error('NavDestination is not allowed in HMRouter, filePath:' + this.sourceFilePath);
130
+ }
131
+ });
203
132
  }
204
- }
205
- else {
206
- propertyValue = this.resolveNode(node.initializer)?.value;
207
- }
208
- let info = new NodeInfo();
209
- info.value = { key: propertyName, value: propertyValue };
210
- return info;
211
- }
212
- resolveIdentifier(node) {
213
- if (node.escapedText === 'NavDestination' && this.analyzeResult.annotation === 'HMRouter') {
214
- Logger_1.Logger.error(Logger_1.PluginError.ERR_WRONG_DECORATION);
215
- throw new Error('NavDestination is not allowed in HMRouter' + this.sourcePath);
216
- }
217
- let info = new NodeInfo();
218
- info.value = node.escapedText.toString();
219
- return info;
220
- }
221
- resolveArrayLiteral(node) {
222
- let arrValue = node.elements.map(e => this.resolveNode(e)?.value);
223
- let info = new NodeInfo();
224
- info.value = arrValue;
225
- return info;
226
- }
227
- resolveNumericLiteral(node) {
228
- let info = new NodeInfo();
229
- info.value = Number(node.text);
230
- return info;
231
- }
232
- resolveStringLiteral(node) {
233
- let info = new NodeInfo();
234
- info.value = node.text;
235
- return info;
236
- }
237
- resolveTrueKeyword() {
238
- let info = new NodeInfo();
239
- info.value = true;
240
- return info;
241
- }
242
- resolveFalseKeyword() {
243
- let info = new NodeInfo();
244
- info.value = false;
245
- return info;
246
- }
247
- getSourceFile(filePath) {
248
- if (!hvigor_1.FileUtil.exist(filePath)) {
249
- return null;
250
- }
251
- const sourceCode = hvigor_1.FileUtil.readFileSync(filePath).toString();
252
- return typescript_1.default.createSourceFile(filePath, sourceCode, typescript_1.default.ScriptTarget.ES2021, false);
133
+ });
253
134
  }
254
- findConstantValueInSourceFile(sourceFile, constantName) {
255
- let nodeInfo = new NodeInfo();
256
- typescript_1.default.forEachChild(sourceFile, node => {
257
- if (!typescript_1.default.isVariableStatement(node)) {
258
- return;
259
- }
260
- node.declarationList.declarations.forEach(declaration => {
261
- let info = this.parseVariableDeclaration(declaration);
262
- if (constantName === info?.value['key']) {
263
- nodeInfo = info;
135
+ analyzeComponent() {
136
+ this.sourceFile.getClasses().forEach((cls) => {
137
+ cls.getDecorators().forEach((decorator) => {
138
+ if (this.config.annotation.includes(decorator.getName())) {
139
+ this.addToResultSet(decorator, cls.getName());
264
140
  }
265
141
  });
142
+ cls.getMethods().forEach((method) => {
143
+ method.getDecorators().forEach((decorator) => {
144
+ let serviceResult = this.addToResultSet(decorator, cls.getName());
145
+ serviceResult.functionName = method.getName();
146
+ });
147
+ });
266
148
  });
267
- return nodeInfo;
268
149
  }
269
- findObjectValueInSourceFile(sourceFile, className, propertyName) {
270
- let info = new NodeInfo();
271
- typescript_1.default.forEachChild(sourceFile, node => {
272
- if (!typescript_1.default.isClassDeclaration(node) || node.name?.escapedText.toString() !== className) {
273
- return;
150
+ addToResultSet(decorator, componentName) {
151
+ let decoratorResult = this.parseDecorator(decorator);
152
+ decoratorResult.name = componentName;
153
+ if (decoratorResult.annotation) {
154
+ this.analyzerResultSet.add(decoratorResult);
155
+ }
156
+ return decoratorResult;
157
+ }
158
+ parseDecorator(decorator) {
159
+ let decoratorResult = {};
160
+ let decoratorName = decorator.getName();
161
+ if (this.config.annotation.includes(decoratorName)) {
162
+ decoratorResult.annotation = decoratorName;
163
+ let args = this.parseDecoratorArguments(decorator);
164
+ Object.assign(decoratorResult, args);
165
+ }
166
+ return decoratorResult;
167
+ }
168
+ parseDecoratorArguments(decorator) {
169
+ let argResult = {};
170
+ decorator.getArguments().map(arg => {
171
+ const objLiteral = arg.asKind(ts_morph_1.SyntaxKind.ObjectLiteralExpression);
172
+ if (objLiteral) {
173
+ objLiteral.getProperties().forEach((prop) => {
174
+ let propertyName = prop.getName();
175
+ let propertyValue = propertyName === CommonConstants_1.default.PAGE_URL ?
176
+ this.parsePageUrlValue(prop.getInitializer()) :
177
+ this.parsePropertyValue(prop.getInitializer());
178
+ Reflect.set(argResult, propertyName, propertyValue);
179
+ });
274
180
  }
275
- node.members.forEach(member => {
276
- if (member.name?.escapedText.toString() === propertyName) {
277
- info = this.parseVariableDeclaration(member);
278
- }
279
- });
280
181
  });
281
- return info;
282
- }
283
- resolveConstantValue(constantName) {
284
- const sourceFile = this.getSourceFile(this.resolvePath(constantName));
285
- if (!sourceFile) {
286
- return null;
287
- }
288
- const constantValueStr = this.findConstantValueInSourceFile(sourceFile, constantName).value['value'];
289
- if (!constantValueStr) {
290
- Logger_1.Logger.error(Logger_1.PluginError.ERR_NOT_EMPTY_STRING, constantName);
291
- throw new Error('constant value cannot be an empty string');
292
- }
293
- return constantValueStr;
182
+ return argResult;
294
183
  }
295
- resolveObjectValue(className, propertyName) {
296
- const sourceFile = this.getSourceFile(this.resolvePath(className));
297
- if (!sourceFile) {
298
- return null;
299
- }
300
- const objectValueStr = this.findObjectValueInSourceFile(sourceFile, className, propertyName).value['value'];
301
- if (!objectValueStr) {
302
- Logger_1.Logger.error(Logger_1.PluginError.ERR_NOT_EMPTY_STRING, propertyName);
303
- throw new Error('constant value cannot be an empty string');
184
+ parsePageUrlValue(value) {
185
+ switch (value.getKind()) {
186
+ case ts_morph_1.SyntaxKind.Identifier:
187
+ return {
188
+ type: 'constant',
189
+ variableName: value.getText(),
190
+ variableFilePath: this.getVariableFilePath(value.getText())
191
+ };
192
+ case ts_morph_1.SyntaxKind.PropertyAccessExpression:
193
+ return {
194
+ type: 'object',
195
+ variableName: value.getExpression().getText(),
196
+ propertyName: value?.getName(),
197
+ variableFilePath: this.getVariableFilePath(value?.getExpression().getText())
198
+ };
199
+ default:
200
+ return this.parsePropertyValue(value);
304
201
  }
305
- return objectValueStr;
306
202
  }
307
- resolvePath(variableName) {
308
- let filePath = '';
309
- this.importMap.forEach((value, key) => {
310
- if (value.includes(variableName)) {
311
- filePath = key;
312
- }
203
+ parsePropertyValue(value) {
204
+ let propertyValue;
205
+ switch (value.getKind()) {
206
+ case ts_morph_1.SyntaxKind.StringLiteral:
207
+ propertyValue = value.asKind(ts_morph_1.SyntaxKind.StringLiteral)?.getLiteralValue();
208
+ break;
209
+ case ts_morph_1.SyntaxKind.TrueKeyword:
210
+ propertyValue = true;
211
+ break;
212
+ case ts_morph_1.SyntaxKind.FalseKeyword:
213
+ propertyValue = false;
214
+ break;
215
+ case ts_morph_1.SyntaxKind.ArrayLiteralExpression:
216
+ propertyValue = value.asKind(ts_morph_1.SyntaxKind.ArrayLiteralExpression)?.getElements()
217
+ .map(item => item.asKind(ts_morph_1.SyntaxKind.StringLiteral)?.getLiteralValue());
218
+ break;
219
+ }
220
+ return propertyValue;
221
+ }
222
+ getVariableFilePath(variableName) {
223
+ let classesNames = this.sourceFile.getClasses().map((classes) => {
224
+ return classes.getName();
313
225
  });
314
- if (filePath) {
315
- filePath =
316
- hvigor_1.FileUtil.pathResolve(this.sourcePath.split(Constant_1.HMRouterPluginConstant.FILE_SEPARATOR).slice(0, -1)
317
- .join(Constant_1.HMRouterPluginConstant.FILE_SEPARATOR), filePath) + Constant_1.HMRouterPluginConstant.VIEW_NAME_SUFFIX;
226
+ let variableNames = this.sourceFile.getVariableDeclarations().map((variableDeclaration) => {
227
+ return variableDeclaration.getName();
228
+ });
229
+ if (classesNames.includes(variableName) || variableNames.includes(variableName)) {
230
+ return this.sourceFilePath;
318
231
  }
319
232
  else {
320
- filePath = this.sourcePath;
321
- }
322
- return filePath;
323
- }
324
- parseVariableDeclaration(node) {
325
- let variableName = this.resolveNode(node.name)?.value;
326
- let variableValue = this.resolveNode(node.initializer)?.value;
327
- if (typeof variableValue !== 'string') {
328
- Logger_1.Logger.error(Logger_1.PluginError.ERR_INVALID_STRING_VALUE, variableName);
329
- throw new Error('Invalid constant value');
233
+ let filePath = '';
234
+ this.importMap.forEach((value, key) => {
235
+ if (value.includes(variableName)) {
236
+ filePath =
237
+ FileUtil_1.default.pathResolve(this.sourceFilePath.split(CommonConstants_1.default.FILE_SEPARATOR).slice(0, -1)
238
+ .join(CommonConstants_1.default.FILE_SEPARATOR), key) + CommonConstants_1.default.VIEW_NAME_SUFFIX;
239
+ }
240
+ });
241
+ return filePath;
330
242
  }
331
- let info = new NodeInfo();
332
- info.value = { key: variableName, value: variableValue };
333
- return info;
334
243
  }
335
244
  }
336
- exports.Analyzer = Analyzer;
@@ -4,12 +4,12 @@ export declare class HMRouterHvigorPlugin {
4
4
  config: HMRouterPluginConfig;
5
5
  routerMap: RouterInfo[];
6
6
  private scanFiles;
7
- private HMRouterNum;
7
+ private analyzerController;
8
8
  constructor(config: HMRouterPluginConfig);
9
9
  analyzeAnnotation(): void;
10
+ generateRouterMap(): void;
10
11
  private pushRouterInfo;
11
12
  private generateBuilder;
12
- generateRouterMap(): void;
13
13
  private deepScan;
14
14
  private stringToHashCode;
15
15
  }