@hadss/hmrouter-plugin 1.2.0-rc.0 → 1.2.1
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 +9 -1
- package/dist/HMRouterPluginManager.js +3 -1
- package/dist/Index.js +9 -6
- package/dist/framework/core/TaskManager.js +4 -2
- package/dist/framework/extension/context/ExtensionContextImpl.d.ts +2 -2
- package/dist/framework/extension/context/ExtensionContextImpl.js +3 -1
- package/dist/framework/utils/Logger.d.ts +1 -1
- package/dist/hmrouter_extension/HMRouterExtension.d.ts +1 -0
- package/dist/hmrouter_extension/HMRouterExtension.js +12 -9
- package/dist/hmrouter_extension/analyzer/utils/DecoratorParser.d.ts +1 -0
- package/dist/hmrouter_extension/analyzer/utils/DecoratorParser.js +12 -9
- package/dist/hmrouter_extension/constants/FilePathConstants.d.ts +3 -0
- package/dist/hmrouter_extension/constants/FilePathConstants.js +3 -0
- package/dist/hmrouter_extension/error/PluginError.d.ts +2 -2
- package/dist/hmrouter_extension/model/HMAnnotationModel.d.ts +1 -1
- package/dist/hmrouter_extension/model/TemplateModel.d.ts +1 -0
- package/dist/hmrouter_extension/processor/CodeGenerationProcessor.d.ts +5 -0
- package/dist/hmrouter_extension/processor/CodeGenerationProcessor.js +74 -9
- package/dist/hmrouter_extension/processor/ObfuscationProcessor.js +27 -10
- package/dist/hmrouter_extension/processor/RouterMapBuildingProcessor.d.ts +1 -0
- package/dist/hmrouter_extension/processor/RouterMapBuildingProcessor.js +3 -0
- package/examples/CustomExtension.ts +87 -74
- package/package.json +3 -2
- package/template/viewBuilder.ejs +81 -16
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ HMRouter编译插件是一个基于hvigor的编译插件,用于:
|
|
|
21
21
|
```json5
|
|
22
22
|
{
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@hadss/hmrouter-plugin": "^1.2.
|
|
24
|
+
"@hadss/hmrouter-plugin": "^1.2.1" // 使用最新版本
|
|
25
25
|
},
|
|
26
26
|
// ...其余配置
|
|
27
27
|
}
|
|
@@ -438,6 +438,14 @@ hvigor 5.7.3及以上
|
|
|
438
438
|
|
|
439
439
|
## 更新日志
|
|
440
440
|
|
|
441
|
+
### 1.2.1 (2025.10.20)
|
|
442
|
+
|
|
443
|
+
- [修复低版本IDE编译错误](https://gitcode.com/openharmony-sig/ohrouter/issues/206)
|
|
444
|
+
|
|
445
|
+
### 1.2.0 (2025.09.28)
|
|
446
|
+
|
|
447
|
+
- 支持API20新接口的生成
|
|
448
|
+
|
|
441
449
|
### 1.2.0-rc.0 (2025.09.02)
|
|
442
450
|
|
|
443
451
|
- [修复多target工程下编译app的问题](https://gitcode.com/openharmony-sig/ohrouter/issues/131)
|
|
@@ -13,8 +13,10 @@ class HMRouterPluginManager {
|
|
|
13
13
|
(0, framework_1.registerPluginExtension)(new HMRouterExtension_1.HMRouterDefaultExtension());
|
|
14
14
|
hvigor_1.hvigor.nodesEvaluated(() => {
|
|
15
15
|
this.moduleNodes.forEach((node) => {
|
|
16
|
-
if (this.controllerMap.has(node.getNodeName()))
|
|
16
|
+
if (this.controllerMap.has(node.getNodeName())) {
|
|
17
17
|
return;
|
|
18
|
+
}
|
|
19
|
+
;
|
|
18
20
|
node.getAllPluginIds().forEach((pluginId) => {
|
|
19
21
|
this.registerPlugin(node, pluginId, {});
|
|
20
22
|
});
|
package/dist/Index.js
CHANGED
|
@@ -65,13 +65,16 @@ function appPlugin(options) {
|
|
|
65
65
|
if (!options) {
|
|
66
66
|
throw new Error('No options provided');
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
if (options.ignoreModuleNames.includes(subNode.getNodeName())) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
HMRouterPluginManager_1.HMRouterPluginManager.getInstance().addModuleNode(subNode);
|
|
73
|
-
});
|
|
68
|
+
hondleNode(options, node);
|
|
74
69
|
},
|
|
75
70
|
};
|
|
76
71
|
}
|
|
77
72
|
exports.appPlugin = appPlugin;
|
|
73
|
+
function hondleNode(options, node) {
|
|
74
|
+
node.subNodes(subNode => {
|
|
75
|
+
if (options.ignoreModuleNames.includes(subNode.getNodeName())) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
HMRouterPluginManager_1.HMRouterPluginManager.getInstance().addModuleNode(subNode);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
@@ -43,10 +43,12 @@ class TaskManager {
|
|
|
43
43
|
return allExtensions.sort((a, b) => {
|
|
44
44
|
const aIsHMRouter = a.name?.includes('HMRouter') || false;
|
|
45
45
|
const bIsHMRouter = b.name?.includes('HMRouter') || false;
|
|
46
|
-
if (aIsHMRouter && !bIsHMRouter)
|
|
46
|
+
if (aIsHMRouter && !bIsHMRouter) {
|
|
47
47
|
return -1;
|
|
48
|
-
|
|
48
|
+
}
|
|
49
|
+
if (!aIsHMRouter && bIsHMRouter) {
|
|
49
50
|
return 1;
|
|
51
|
+
}
|
|
50
52
|
return 0;
|
|
51
53
|
});
|
|
52
54
|
}
|
|
@@ -15,8 +15,8 @@ export declare class ExtensionContextImpl implements ExtensionContext {
|
|
|
15
15
|
get currentView(): ReadonlyArray<BaseAnalyzeResult>;
|
|
16
16
|
addAnalyzeResults(results: BaseAnalyzeResult | BaseAnalyzeResult[]): void;
|
|
17
17
|
getAnalyzeResults<T extends BaseAnalyzeResult = BaseAnalyzeResult>(): Set<T>;
|
|
18
|
-
getTemplateData(componentName: string): Record<string,
|
|
19
|
-
getTemplateDataMap(): Map<string, Record<string,
|
|
18
|
+
getTemplateData(componentName: string): Record<string, unknown> | undefined;
|
|
19
|
+
getTemplateDataMap(): Map<string, Record<string, unknown>>;
|
|
20
20
|
addTemplateData(componentName: string, data: Record<string, any>): void;
|
|
21
21
|
private validateAnalyzeResult;
|
|
22
22
|
private syncToCurrentView;
|
|
@@ -76,8 +76,10 @@ class ExtensionContextImpl {
|
|
|
76
76
|
syncToCurrentView(results) {
|
|
77
77
|
const key = this.getActiveTargetKey();
|
|
78
78
|
const state = this.getOrCreateState(key);
|
|
79
|
-
if (!state.currentFilePath)
|
|
79
|
+
if (!state.currentFilePath) {
|
|
80
80
|
return;
|
|
81
|
+
}
|
|
82
|
+
;
|
|
81
83
|
const resultsArray = Array.isArray(results) ? results : [results];
|
|
82
84
|
const currentFileResults = resultsArray.filter(result => result.sourceFilePath === state.currentFilePath);
|
|
83
85
|
state.currentView.push(...currentFileResults);
|
|
@@ -7,6 +7,6 @@ export declare class Logger {
|
|
|
7
7
|
error: (msg: string, ...args: unknown[]) => void;
|
|
8
8
|
info: (msg: string, ...args: unknown[]) => void;
|
|
9
9
|
warn: (msg: string, ...args: unknown[]) => void;
|
|
10
|
-
debug: (msg: string,
|
|
10
|
+
debug: (msg: string, args: unknown[]) => void;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
@@ -6,6 +6,7 @@ export declare class HMRouterDefaultExtension extends PluginExtension<HMRouterEx
|
|
|
6
6
|
afterInitialize(context: HMRouterExtensionContext): void;
|
|
7
7
|
afterAnnotationAnalysis(sourceFile: SourceFile, filePath: string, context: HMRouterExtensionContext): void;
|
|
8
8
|
private executeConstantParsing;
|
|
9
|
+
private getCurrentView;
|
|
9
10
|
afterCodeGeneration(context: HMRouterExtensionContext): void;
|
|
10
11
|
afterRouterMapBuilding(context: HMRouterExtensionContext): void;
|
|
11
12
|
afterConfigUpdate(context: HMRouterExtensionContext): void;
|
|
@@ -58,15 +58,7 @@ class HMRouterDefaultExtension extends framework_1.PluginExtension {
|
|
|
58
58
|
});
|
|
59
59
|
contextImpl.analyzeResults = updatedResults;
|
|
60
60
|
for (let i = 0; i < currentView.length; i++) {
|
|
61
|
-
|
|
62
|
-
if (viewResult.sourceFilePath === currentFilePath) {
|
|
63
|
-
for (const parsedResult of resultsSet) {
|
|
64
|
-
if (parsedResult.name === viewResult.name && parsedResult.sourceFilePath === viewResult.sourceFilePath) {
|
|
65
|
-
currentView[i] = parsedResult;
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
61
|
+
this.getCurrentView(currentView, currentFilePath, resultsSet, i);
|
|
70
62
|
}
|
|
71
63
|
framework_2.Logger.debug(this.name, `Constant parsing completed for file: ${filePath}`);
|
|
72
64
|
}
|
|
@@ -74,6 +66,17 @@ class HMRouterDefaultExtension extends framework_1.PluginExtension {
|
|
|
74
66
|
framework_2.Logger.warn(this.name, `Failed to execute constant parsing for file ${filePath}: ${error}`);
|
|
75
67
|
}
|
|
76
68
|
}
|
|
69
|
+
getCurrentView(currentView, currentFilePath, resultsSet, i) {
|
|
70
|
+
const viewResult = currentView[i];
|
|
71
|
+
if (viewResult.sourceFilePath === currentFilePath) {
|
|
72
|
+
for (const parsedResult of resultsSet) {
|
|
73
|
+
if (parsedResult.name === viewResult.name && parsedResult.sourceFilePath === viewResult.sourceFilePath) {
|
|
74
|
+
currentView[i] = parsedResult;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
77
80
|
afterCodeGeneration(context) {
|
|
78
81
|
const generator = new processor_1.CodeGenerationProcessor(context);
|
|
79
82
|
generator.execute();
|
|
@@ -4,4 +4,5 @@ import { BaseAnalyzeResult } from '../../../framework';
|
|
|
4
4
|
export declare class DecoratorParser {
|
|
5
5
|
static parseDecorator(decorator: Decorator, constantResolver: IConstantResolver, sourceFile: SourceFile, filePath: string): BaseAnalyzeResult;
|
|
6
6
|
static parseDecoratorArguments(decorator: Decorator, constantResolver: IConstantResolver, sourceFile: SourceFile, filePath: string): BaseAnalyzeResult;
|
|
7
|
+
static hondleObjLiteral(prop: any, constantResolver: IConstantResolver, sourceFile: SourceFile, filePath: string, argResult: BaseAnalyzeResult): void;
|
|
7
8
|
}
|
|
@@ -23,19 +23,22 @@ class DecoratorParser {
|
|
|
23
23
|
const objLiteral = arg.asKind(ts_morph_1.SyntaxKind.ObjectLiteralExpression);
|
|
24
24
|
if (objLiteral) {
|
|
25
25
|
objLiteral.getProperties().forEach((prop) => {
|
|
26
|
-
|
|
27
|
-
const propertyAssignment = prop;
|
|
28
|
-
const propertyName = propertyAssignment.getName();
|
|
29
|
-
const initializer = propertyAssignment.getInitializer();
|
|
30
|
-
if (initializer) {
|
|
31
|
-
const propertyValue = constantResolver.resolvePropertyValue(initializer, sourceFile, filePath);
|
|
32
|
-
Reflect.set(argResult, propertyName, propertyValue);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
26
|
+
this.hondleObjLiteral(prop, constantResolver, sourceFile, filePath, argResult);
|
|
35
27
|
});
|
|
36
28
|
}
|
|
37
29
|
});
|
|
38
30
|
return argResult;
|
|
39
31
|
}
|
|
32
|
+
static hondleObjLiteral(prop, constantResolver, sourceFile, filePath, argResult) {
|
|
33
|
+
if (prop.getKind() === ts_morph_1.SyntaxKind.PropertyAssignment) {
|
|
34
|
+
const propertyAssignment = prop;
|
|
35
|
+
const propertyName = propertyAssignment.getName();
|
|
36
|
+
const initializer = propertyAssignment.getInitializer();
|
|
37
|
+
if (initializer) {
|
|
38
|
+
const propertyValue = constantResolver.resolvePropertyValue(initializer, sourceFile, filePath);
|
|
39
|
+
Reflect.set(argResult, propertyName, propertyValue);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
40
43
|
}
|
|
41
44
|
exports.DecoratorParser = DecoratorParser;
|
|
@@ -13,6 +13,9 @@ export default class FilePathConstants {
|
|
|
13
13
|
static readonly OH_MODULE_PATH = "oh_modules";
|
|
14
14
|
static readonly OH_PACKAGE_FILE_NAME = "oh-package.json5";
|
|
15
15
|
static readonly LINE_BREAK = "\n";
|
|
16
|
+
static readonly BUILD_PROFILE = "build-profile.json5";
|
|
17
|
+
static readonly SDK_HOME = "default/openharmony/ets/oh-uni-package.json";
|
|
18
|
+
static readonly DEFAULT_VALUE = 10;
|
|
16
19
|
static readonly DEFAULT_SCAN_DIR = "src/main/ets";
|
|
17
20
|
static readonly DEFAULT_ROUTER_MAP_DIR = "src/main/resources/base/profile";
|
|
18
21
|
static readonly DEFAULT_BUILD_DIR = "src/main/ets/generated";
|
|
@@ -21,6 +21,9 @@ FilePathConstants.CURRENT_DELIMITER = './';
|
|
|
21
21
|
FilePathConstants.OH_MODULE_PATH = 'oh_modules';
|
|
22
22
|
FilePathConstants.OH_PACKAGE_FILE_NAME = 'oh-package.json5';
|
|
23
23
|
FilePathConstants.LINE_BREAK = '\n';
|
|
24
|
+
FilePathConstants.BUILD_PROFILE = 'build-profile.json5';
|
|
25
|
+
FilePathConstants.SDK_HOME = 'default/openharmony/ets/oh-uni-package.json';
|
|
26
|
+
FilePathConstants.DEFAULT_VALUE = 10;
|
|
24
27
|
FilePathConstants.DEFAULT_SCAN_DIR = 'src/main/ets';
|
|
25
28
|
FilePathConstants.DEFAULT_ROUTER_MAP_DIR = 'src/main/resources/base/profile';
|
|
26
29
|
FilePathConstants.DEFAULT_BUILD_DIR = 'src/main/ets/generated';
|
|
@@ -22,8 +22,8 @@ export declare enum ErrorCode {
|
|
|
22
22
|
export declare class PluginError extends Error {
|
|
23
23
|
readonly code: ErrorCode;
|
|
24
24
|
readonly module: string;
|
|
25
|
-
readonly data?:
|
|
26
|
-
constructor(code: ErrorCode, module: string, params?: string | string[], data?:
|
|
25
|
+
readonly data?: unknown;
|
|
26
|
+
constructor(code: ErrorCode, module: string, params?: string | string[], data?: unknown);
|
|
27
27
|
private logError;
|
|
28
28
|
static create(code: ErrorCode, module: string, params?: string | string[], data?: any): PluginError;
|
|
29
29
|
}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { HMRouterExtensionContext } from '../HMRouterExtensionContext';
|
|
2
2
|
export declare class CodeGenerationProcessor {
|
|
3
3
|
private context;
|
|
4
|
+
private sdkVersion;
|
|
4
5
|
constructor(context: HMRouterExtensionContext);
|
|
5
6
|
execute(): void;
|
|
7
|
+
extractVersion(compatibleSdkVersion: string | number): number;
|
|
8
|
+
getCompileSdkVersion(): number;
|
|
9
|
+
getSdkVersion(json5FilePath: string, index: number): number;
|
|
6
10
|
private generatePageFile;
|
|
7
11
|
private matchedPath;
|
|
8
12
|
private prepareTemplateModel;
|
|
9
13
|
private determineTemplatePath;
|
|
10
14
|
private generateFile;
|
|
11
15
|
private detectLibraryVersion;
|
|
16
|
+
private detectLibraryVersion2;
|
|
12
17
|
private getLibraryPossiblePaths;
|
|
13
18
|
}
|
|
@@ -11,9 +11,11 @@ const PluginError_1 = require("../error/PluginError");
|
|
|
11
11
|
const constants_1 = require("../constants");
|
|
12
12
|
class CodeGenerationProcessor {
|
|
13
13
|
constructor(context) {
|
|
14
|
+
this.sdkVersion = 0;
|
|
14
15
|
this.context = context;
|
|
15
16
|
}
|
|
16
17
|
execute() {
|
|
18
|
+
this.sdkVersion = this.getCompileSdkVersion();
|
|
17
19
|
framework_1.Logger.debug(this.context.node.getNodeName(), `Start to code generation...`);
|
|
18
20
|
this.context.generatedPaths = new Map();
|
|
19
21
|
this.context.getAnalyzeResults().forEach((result) => {
|
|
@@ -28,6 +30,63 @@ class CodeGenerationProcessor {
|
|
|
28
30
|
}
|
|
29
31
|
});
|
|
30
32
|
}
|
|
33
|
+
extractVersion(compatibleSdkVersion) {
|
|
34
|
+
if (typeof compatibleSdkVersion === 'number') {
|
|
35
|
+
return compatibleSdkVersion;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const match = compatibleSdkVersion.match(/\((\d+)\)/);
|
|
39
|
+
if (match && match[1]) {
|
|
40
|
+
return parseInt(match[1], 10);
|
|
41
|
+
}
|
|
42
|
+
const num = parseFloat(compatibleSdkVersion);
|
|
43
|
+
if (!isNaN(num) && num > constants_1.FilePathConstants.DEFAULT_VALUE) {
|
|
44
|
+
return num;
|
|
45
|
+
}
|
|
46
|
+
return constants_1.FilePathConstants.DEFAULT_VALUE;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
getCompileSdkVersion() {
|
|
50
|
+
let json5FilePath = '';
|
|
51
|
+
let sdkVersion = constants_1.FilePathConstants.DEFAULT_VALUE;
|
|
52
|
+
let arrData = ['DEVECO_SDK_HOME', 'HOS_SDK_HOME', 'OHOS_SDK_HOME'];
|
|
53
|
+
for (let index = 0; index <= 4; index++) {
|
|
54
|
+
if (index < 3 && process.env[arrData[index]]) {
|
|
55
|
+
json5FilePath = framework_1.PluginFileUtil.pathResolve(process.env[arrData[index]], constants_1.FilePathConstants.SDK_HOME);
|
|
56
|
+
}
|
|
57
|
+
else if (index === 3) {
|
|
58
|
+
json5FilePath = framework_1.PluginFileUtil.pathResolve(framework_1.PluginStore.getInstance().get('projectFilePath'), constants_1.FilePathConstants.BUILD_PROFILE);
|
|
59
|
+
}
|
|
60
|
+
else if (index === 4) {
|
|
61
|
+
json5FilePath = framework_1.PluginFileUtil.pathResolve(framework_1.PluginStore.getInstance().get('projectFilePath'), constants_1.FilePathConstants.BUILD_PROFILE);
|
|
62
|
+
}
|
|
63
|
+
const sdkVer = this.getSdkVersion(json5FilePath, index);
|
|
64
|
+
if (sdkVer > constants_1.FilePathConstants.DEFAULT_VALUE) {
|
|
65
|
+
sdkVersion = sdkVer;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return sdkVersion;
|
|
70
|
+
}
|
|
71
|
+
getSdkVersion(json5FilePath, index) {
|
|
72
|
+
if (framework_1.PluginFileUtil.exist(json5FilePath)) {
|
|
73
|
+
const data = framework_1.PluginFileUtil.readJson5(json5FilePath);
|
|
74
|
+
if (index < 3) {
|
|
75
|
+
return this.extractVersion(data.apiVersion);
|
|
76
|
+
}
|
|
77
|
+
else if (index === 3) {
|
|
78
|
+
if (data.app.products[0].compileSdkVersion) {
|
|
79
|
+
return this.extractVersion(data.app.products[0].compileSdkVersion);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else if (index === 4) {
|
|
83
|
+
if (data.app.products[0].compatibleSdkVersion) {
|
|
84
|
+
return this.extractVersion(data.app.products[0].compatibleSdkVersion);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return constants_1.FilePathConstants.DEFAULT_VALUE;
|
|
89
|
+
}
|
|
31
90
|
generatePageFile(result, pageSourceFile, tempFilePath) {
|
|
32
91
|
const templateModel = this.prepareTemplateModel(result, pageSourceFile);
|
|
33
92
|
tempFilePath = this.determineTemplatePath(result, tempFilePath);
|
|
@@ -53,6 +112,7 @@ class CodeGenerationProcessor {
|
|
|
53
112
|
let generatorViewName = constants_1.PrefixConstants.VIEW_NAME_PREFIX + analyzeResult.name + framework_1.StringUtil.stringToHashCode(analyzeResult.pageUrl);
|
|
54
113
|
let templateData = this.context.getTemplateData(analyzeResult.name);
|
|
55
114
|
return {
|
|
115
|
+
sdkVersion: this.sdkVersion,
|
|
56
116
|
pageUrl: analyzeResult.pageUrl,
|
|
57
117
|
componentName: analyzeResult.name,
|
|
58
118
|
dialog: !!analyzeResult.dialog,
|
|
@@ -91,18 +151,23 @@ class CodeGenerationProcessor {
|
|
|
91
151
|
let libraryVersion = '';
|
|
92
152
|
const possiblePaths = this.getLibraryPossiblePaths();
|
|
93
153
|
for (const packagePath of possiblePaths) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
libraryVersion = packageJson[constants_1.VersionConstants.HMROUTER_VERSION_KEY] || '';
|
|
98
|
-
if (libraryVersion) {
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
154
|
+
libraryVersion = this.detectLibraryVersion2(packagePath);
|
|
155
|
+
if (libraryVersion) {
|
|
156
|
+
break;
|
|
102
157
|
}
|
|
103
|
-
|
|
158
|
+
}
|
|
159
|
+
return libraryVersion;
|
|
160
|
+
}
|
|
161
|
+
detectLibraryVersion2(packagePath) {
|
|
162
|
+
let libraryVersion = '';
|
|
163
|
+
try {
|
|
164
|
+
if (framework_1.PluginFileUtil.exist(packagePath)) {
|
|
165
|
+
const packageJson = framework_1.PluginFileUtil.readJson5(packagePath);
|
|
166
|
+
libraryVersion = packageJson[constants_1.VersionConstants.HMROUTER_VERSION_KEY] || '';
|
|
104
167
|
}
|
|
105
168
|
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
}
|
|
106
171
|
return libraryVersion;
|
|
107
172
|
}
|
|
108
173
|
getLibraryPossiblePaths() {
|
|
@@ -37,18 +37,35 @@ class ObfuscationProcessor {
|
|
|
37
37
|
isEnableObfuscation(buildProfileOpt) {
|
|
38
38
|
const currentBuildMode = framework_1.PluginStore.getInstance().get('buildMode');
|
|
39
39
|
const buildOption = buildProfileOpt.buildOptionSet?.find((item) => item.name === currentBuildMode);
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const target = buildProfileOpt.targets?.find((item) => item.name === this.context.currentTarget?.getTargetName);
|
|
41
|
+
if (target) {
|
|
42
|
+
const config = framework_1.ObjectUtils.ensureNestedObject(target, ['config']);
|
|
43
|
+
const buildOption = framework_1.ObjectUtils.ensureNestedObject(config, ['buildOption']);
|
|
44
|
+
const arkOptions = framework_1.ObjectUtils.ensureNestedObject(buildOption, ['arkOptions']);
|
|
45
|
+
const obfuscation = framework_1.ObjectUtils.ensureNestedObject(arkOptions, ['obfuscation']);
|
|
46
|
+
const ruleOptions = framework_1.ObjectUtils.ensureNestedObject(obfuscation, ['ruleOptions']);
|
|
47
|
+
const isObfuscationEnabled = !!ruleOptions.enable;
|
|
48
|
+
if (!isObfuscationEnabled) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
if (this.context.config?.autoObfuscation) {
|
|
52
|
+
this.addHMRouterObfuscationRules(ruleOptions, obfuscation);
|
|
53
|
+
}
|
|
42
54
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
else if (buildOption) {
|
|
56
|
+
const arkOptions = framework_1.ObjectUtils.ensureNestedObject(buildOption, ['arkOptions']);
|
|
57
|
+
const obfuscationOptions = framework_1.ObjectUtils.ensureNestedObject(arkOptions, ['obfuscation']);
|
|
58
|
+
const ruleOptions = framework_1.ObjectUtils.ensureNestedObject(obfuscationOptions, ['ruleOptions']);
|
|
59
|
+
const isObfuscationEnabled = !!ruleOptions.enable;
|
|
60
|
+
if (!isObfuscationEnabled) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
if (this.context.config?.autoObfuscation) {
|
|
64
|
+
this.addHMRouterObfuscationRules(ruleOptions, obfuscationOptions);
|
|
65
|
+
}
|
|
49
66
|
}
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
else {
|
|
68
|
+
return false;
|
|
52
69
|
}
|
|
53
70
|
return true;
|
|
54
71
|
}
|
|
@@ -35,6 +35,9 @@ class RouterMapBuildingProcessor {
|
|
|
35
35
|
});
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
|
+
this.useAnnotationConfig(result, pageSourceFile);
|
|
39
|
+
}
|
|
40
|
+
useAnnotationConfig(result, pageSourceFile) {
|
|
38
41
|
const annotationConfig = {
|
|
39
42
|
[constants_1.AnnotationConstants.ANIMATOR_ANNOTATION]: {
|
|
40
43
|
prefix: constants_1.PrefixConstants.ANIMATOR_PREFIX,
|
|
@@ -55,51 +55,56 @@ export class RouterParamAnalyzer {
|
|
|
55
55
|
// 解析结构体声明中的RouterParam注解
|
|
56
56
|
sourceFile.getChildrenOfKind(SyntaxKind.MissingDeclaration).forEach((node, index) => {
|
|
57
57
|
node.getChildrenOfKind(SyntaxKind.Decorator).forEach((decorator) => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
annotation: decorator.getName(),
|
|
63
|
-
sourceFilePath: filePath
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// 解析装饰器参数
|
|
67
|
-
decorator.getArguments().forEach((arg) => {
|
|
68
|
-
const objLiteral = arg.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
69
|
-
if (objLiteral) {
|
|
70
|
-
objLiteral.getProperties().forEach((prop) => {
|
|
71
|
-
if (prop.getKind() === SyntaxKind.PropertyAssignment) {
|
|
72
|
-
const propertyAssignment = prop as PropertyAssignment;
|
|
73
|
-
const propertyName = propertyAssignment.getName();
|
|
74
|
-
const initializer = propertyAssignment.getInitializer();
|
|
75
|
-
|
|
76
|
-
if (initializer) {
|
|
77
|
-
// 将解析结果添加到result对象
|
|
78
|
-
result[propertyName] = this.parsePrimitiveValue(initializer);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
});
|
|
58
|
+
this.getDecorator(decorator, viewNameArr, index, filePath, context);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
84
62
|
|
|
85
|
-
|
|
86
|
-
|
|
63
|
+
private getDecorator(decorator: any, viewNameArr: any, index: number, filePath: any, context: MyExtensionContext): void {
|
|
64
|
+
if (decorator.getName() === 'RouterParam') {
|
|
65
|
+
// 解析RouterParam注解的参数
|
|
66
|
+
const result: MyAnalyzeResult = {
|
|
67
|
+
name: viewNameArr[index],
|
|
68
|
+
annotation: decorator.getName(),
|
|
69
|
+
sourceFilePath: filePath
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// 解析装饰器参数
|
|
73
|
+
decorator.getArguments().forEach((arg) => {
|
|
74
|
+
const objLiteral = arg.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
75
|
+
if (objLiteral) {
|
|
76
|
+
this.handleObjLiteral(objLiteral, result);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
87
79
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
80
|
+
// 为组件添加模板数据,用于代码生成
|
|
81
|
+
context.addTemplateData(result.name, {
|
|
82
|
+
paramType: result.paramType || 'default',
|
|
83
|
+
isCustomParam: true,
|
|
84
|
+
customParams: result.params || [],
|
|
85
|
+
sourceFile: filePath
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
Logger.debug('', `发现RouterParam注解: ${result.name}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
95
91
|
|
|
96
|
-
|
|
92
|
+
private handleObjLiteral(objLiteral: any, result: MyAnalyzeResult): void {
|
|
93
|
+
objLiteral.getProperties().forEach((prop) => {
|
|
94
|
+
if (prop.getKind() === SyntaxKind.PropertyAssignment) {
|
|
95
|
+
const propertyAssignment = prop as PropertyAssignment;
|
|
96
|
+
const propertyName = propertyAssignment.getName();
|
|
97
|
+
const initializer = propertyAssignment.getInitializer();
|
|
98
|
+
|
|
99
|
+
if (initializer) {
|
|
100
|
+
// 将解析结果添加到result对象
|
|
101
|
+
result[propertyName] = this.parsePrimitiveValue(initializer);
|
|
97
102
|
}
|
|
98
|
-
}
|
|
103
|
+
}
|
|
99
104
|
});
|
|
100
105
|
}
|
|
101
106
|
|
|
102
|
-
private parsePrimitiveValue(value: Expression):
|
|
107
|
+
private parsePrimitiveValue(value: Expression): string {
|
|
103
108
|
let propertyValue;
|
|
104
109
|
switch (value.getKind()) {
|
|
105
110
|
case SyntaxKind.StringLiteral:
|
|
@@ -141,45 +146,53 @@ export class CustomPageAnalyzer {
|
|
|
141
146
|
// 分析使用@CustomPage注解的类
|
|
142
147
|
sourceFile.getClasses().forEach((cls: ClassDeclaration) => {
|
|
143
148
|
cls.getDecorators().forEach(decorator => {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
});
|
|
149
|
+
this.getDecorator(decorator, cls, filePath, context);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private getDecorator(decorator: any, cls: ClassDeclaration, filePath: any, context: MyExtensionContext): void {
|
|
155
|
+
if (decorator.getName() === 'CustomPage') {
|
|
156
|
+
const className = cls.getName() || '';
|
|
157
|
+
|
|
158
|
+
// 创建分析结果
|
|
159
|
+
const result: MyAnalyzeResult = {
|
|
160
|
+
name: className,
|
|
161
|
+
annotation: 'CustomPage',
|
|
162
|
+
sourceFilePath: filePath
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// 解析装饰器参数
|
|
166
|
+
decorator.getArguments().forEach((arg) => {
|
|
167
|
+
const objLiteral = arg.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
168
|
+
if (objLiteral) {
|
|
169
|
+
this.handleObjLiteral(objLiteral, result);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// 添加分析结果
|
|
174
|
+
context.addAnalyzeResults(result);
|
|
171
175
|
|
|
172
|
-
|
|
173
|
-
|
|
176
|
+
// 存储自定义页面路径信息
|
|
177
|
+
const customPages = context.customPages || [];
|
|
178
|
+
customPages.push(result);
|
|
179
|
+
context.customPages = customPages;
|
|
174
180
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
context.customPages = customPages;
|
|
181
|
+
Logger.debug('', `发现CustomPage注解: ${className}, pageUrl: ${result.pageUrl}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
179
184
|
|
|
180
|
-
|
|
185
|
+
private handleObjLiteral(objLiteral: any, result: MyAnalyzeResult): void {
|
|
186
|
+
objLiteral.getProperties().forEach((prop) => {
|
|
187
|
+
if (prop.getKind() === SyntaxKind.PropertyAssignment) {
|
|
188
|
+
const propertyAssignment = prop as PropertyAssignment;
|
|
189
|
+
const propertyName = propertyAssignment.getName();
|
|
190
|
+
const initializer = propertyAssignment.getInitializer();
|
|
191
|
+
|
|
192
|
+
if (initializer && initializer.getKind() === SyntaxKind.StringLiteral) {
|
|
193
|
+
result[propertyName] = initializer.asKind(SyntaxKind.StringLiteral)?.getLiteralValue();
|
|
181
194
|
}
|
|
182
|
-
}
|
|
195
|
+
}
|
|
183
196
|
});
|
|
184
197
|
}
|
|
185
198
|
}
|
|
@@ -222,7 +235,7 @@ export class CustomPluginExtension extends PluginExtension<MyExtensionContext> {
|
|
|
222
235
|
|
|
223
236
|
// 将CustomPage添加到路由表
|
|
224
237
|
for (const page of customPages) {
|
|
225
|
-
const pageUrl = page.customData
|
|
238
|
+
const pageUrl = page.customData.pageUrl;
|
|
226
239
|
if (pageUrl) {
|
|
227
240
|
// 检查路由表中是否已存在该路径
|
|
228
241
|
const existingRoute = context.routerMap.find(route => route.customData.pageUrl === pageUrl);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hadss/hmrouter-plugin",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "HMRouter Compiler Plugin",
|
|
5
5
|
"main": "dist/Index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha",
|
|
9
9
|
"dev": "tsc && node dist/index.js",
|
|
10
10
|
"build": "tsc",
|
|
11
|
-
"
|
|
11
|
+
"package": "rm -rf ./dist && tsc && npm pack",
|
|
12
|
+
"release": "rm -rf ./dist && npm i && tsc && npm publish --access public"
|
|
12
13
|
},
|
|
13
14
|
"keywords": [
|
|
14
15
|
"hmrouter",
|
package/template/viewBuilder.ejs
CHANGED
|
@@ -30,22 +30,87 @@ export struct <%= componentName %>Generated {
|
|
|
30
30
|
private helper: NavDestinationHelper = new NavDestinationHelper(this);
|
|
31
31
|
|
|
32
32
|
build() {
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
if(this.helper.sdkApiVersion>=19){
|
|
34
|
+
NavDestination() {
|
|
35
|
+
<%= componentName %>()
|
|
36
|
+
}
|
|
37
|
+
<% if(dialog){ %>.mode(NavDestinationMode.DIALOG)<% } %>
|
|
38
|
+
.hideTitleBar(true)
|
|
39
|
+
.attributeModifier(this.helper.modifier)
|
|
40
|
+
.gestureModifier(this.helper.gestureModifier)
|
|
41
|
+
.onWillAppear(()=>{this.helper.onWillAppear()})
|
|
42
|
+
.onAppear(() => {this.helper.onAppear()})
|
|
43
|
+
.onWillShow(()=>{this.helper.onWillShow()})
|
|
44
|
+
.onShown(()=>{this.helper.onShown()})
|
|
45
|
+
.onWillHide(()=>{this.helper.onWillHide()})
|
|
46
|
+
.onHidden(()=>{this.helper.onHidden()})
|
|
47
|
+
.onWillDisappear(()=>{this.helper.onWillDisappear()})
|
|
48
|
+
.onDisAppear(()=>{this.helper.onDisAppear()})
|
|
49
|
+
.onReady((ctx)=>{this.helper.onReady(ctx)})
|
|
50
|
+
.onBackPressed(()=> this.helper.onBackPressed())
|
|
51
|
+
<% if(sdkVersion>=15){ %>.onResult((result:ESObject)=>{this.helper.onResult(result)})<% } %>
|
|
52
|
+
<% if(sdkVersion>=17){ %>.onActive((activeReason:NavDestinationActiveReason)=>{this.helper.onActive(activeReason)})<% } %>
|
|
53
|
+
<% if(sdkVersion>=17){ %>.onInactive((inactiveReason:NavDestinationActiveReason)=>{this.helper.onInactive(inactiveReason)})<% } %>
|
|
54
|
+
<% if(sdkVersion>=19){ %>.onNewParam((newParam:ESObject)=>{this.helper.onNewParam(newParam)})<% } %>
|
|
55
|
+
}else if(this.helper.sdkApiVersion>=17){
|
|
56
|
+
NavDestination() {
|
|
57
|
+
<%= componentName %>()
|
|
58
|
+
}
|
|
59
|
+
<% if(dialog){ %>.mode(NavDestinationMode.DIALOG)<% } %>
|
|
60
|
+
.hideTitleBar(true)
|
|
61
|
+
.attributeModifier(this.helper.modifier)
|
|
62
|
+
.gestureModifier(this.helper.gestureModifier)
|
|
63
|
+
.onWillAppear(()=>{this.helper.onWillAppear()})
|
|
64
|
+
.onAppear(() => {this.helper.onAppear()})
|
|
65
|
+
.onWillShow(()=>{this.helper.onWillShow()})
|
|
66
|
+
.onShown(()=>{this.helper.onShown()})
|
|
67
|
+
.onWillHide(()=>{this.helper.onWillHide()})
|
|
68
|
+
.onHidden(()=>{this.helper.onHidden()})
|
|
69
|
+
.onWillDisappear(()=>{this.helper.onWillDisappear()})
|
|
70
|
+
.onDisAppear(()=>{this.helper.onDisAppear()})
|
|
71
|
+
.onReady((ctx)=>{this.helper.onReady(ctx)})
|
|
72
|
+
.onBackPressed(()=> this.helper.onBackPressed())
|
|
73
|
+
<% if(sdkVersion>=15){ %>.onResult((result:ESObject)=>{this.helper.onResult(result)})<% } %>
|
|
74
|
+
<% if(sdkVersion>=17){ %>.onActive((activeReason:NavDestinationActiveReason)=>{this.helper.onActive(activeReason)})<% } %>
|
|
75
|
+
<% if(sdkVersion>=17){ %>.onInactive((inactiveReason:NavDestinationActiveReason)=>{this.helper.onInactive(inactiveReason)})<% } %>
|
|
76
|
+
}else if(this.helper.sdkApiVersion>=15){
|
|
77
|
+
NavDestination() {
|
|
78
|
+
<%= componentName %>()
|
|
79
|
+
}
|
|
80
|
+
<% if(dialog){ %>.mode(NavDestinationMode.DIALOG)<% } %>
|
|
81
|
+
.hideTitleBar(true)
|
|
82
|
+
.attributeModifier(this.helper.modifier)
|
|
83
|
+
.gestureModifier(this.helper.gestureModifier)
|
|
84
|
+
.onWillAppear(()=>{this.helper.onWillAppear()})
|
|
85
|
+
.onAppear(() => {this.helper.onAppear()})
|
|
86
|
+
.onWillShow(()=>{this.helper.onWillShow()})
|
|
87
|
+
.onShown(()=>{this.helper.onShown()})
|
|
88
|
+
.onWillHide(()=>{this.helper.onWillHide()})
|
|
89
|
+
.onHidden(()=>{this.helper.onHidden()})
|
|
90
|
+
.onWillDisappear(()=>{this.helper.onWillDisappear()})
|
|
91
|
+
.onDisAppear(()=>{this.helper.onDisAppear()})
|
|
92
|
+
.onReady((ctx)=>{this.helper.onReady(ctx)})
|
|
93
|
+
.onBackPressed(()=> this.helper.onBackPressed())
|
|
94
|
+
<% if(sdkVersion>=15){ %>.onResult((result:ESObject)=>{this.helper.onResult(result)})<% } %>
|
|
95
|
+
}else{
|
|
96
|
+
NavDestination() {
|
|
97
|
+
<%= componentName %>()
|
|
98
|
+
}
|
|
99
|
+
<% if(dialog){ %>.mode(NavDestinationMode.DIALOG)<% } %>
|
|
100
|
+
.hideTitleBar(true)
|
|
101
|
+
.attributeModifier(this.helper.modifier)
|
|
102
|
+
.gestureModifier(this.helper.gestureModifier)
|
|
103
|
+
.onWillAppear(()=>{this.helper.onWillAppear()})
|
|
104
|
+
.onAppear(() => {this.helper.onAppear()})
|
|
105
|
+
.onWillShow(()=>{this.helper.onWillShow()})
|
|
106
|
+
.onShown(()=>{this.helper.onShown()})
|
|
107
|
+
.onWillHide(()=>{this.helper.onWillHide()})
|
|
108
|
+
.onHidden(()=>{this.helper.onHidden()})
|
|
109
|
+
.onWillDisappear(()=>{this.helper.onWillDisappear()})
|
|
110
|
+
.onDisAppear(()=>{this.helper.onDisAppear()})
|
|
111
|
+
.onReady((ctx)=>{this.helper.onReady(ctx)})
|
|
112
|
+
.onBackPressed(()=> this.helper.onBackPressed())
|
|
35
113
|
}
|
|
36
|
-
|
|
37
|
-
.hideTitleBar(true)
|
|
38
|
-
.attributeModifier(this.helper.modifier)
|
|
39
|
-
.gestureModifier(this.helper.gestureModifier)
|
|
40
|
-
.onWillAppear(()=>{this.helper.onWillAppear()})
|
|
41
|
-
.onAppear(() => {this.helper.onAppear()})
|
|
42
|
-
.onWillShow(()=>{this.helper.onWillShow()})
|
|
43
|
-
.onShown(()=>{this.helper.onShown()})
|
|
44
|
-
.onWillHide(()=>{this.helper.onWillHide()})
|
|
45
|
-
.onHidden(()=>{this.helper.onHidden()})
|
|
46
|
-
.onWillDisappear(()=>{this.helper.onWillDisappear()})
|
|
47
|
-
.onDisAppear(()=>{this.helper.onDisAppear()})
|
|
48
|
-
.onReady((ctx)=>{this.helper.onReady(ctx)})
|
|
49
|
-
.onBackPressed(()=> this.helper.onBackPressed())
|
|
114
|
+
|
|
50
115
|
}
|
|
51
116
|
}
|