@hadss/hmrouter-plugin 1.1.0-beta.0 → 1.1.1-alpha.0

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.
Files changed (120) hide show
  1. package/README.md +246 -67
  2. package/dist/HMRouterPluginManager.d.ts +9 -0
  3. package/dist/HMRouterPluginManager.js +55 -0
  4. package/dist/Index.d.ts +9 -3
  5. package/dist/Index.js +29 -109
  6. package/dist/framework/constants/TaskConstants.d.ts +8 -0
  7. package/dist/framework/constants/TaskConstants.js +12 -0
  8. package/dist/framework/constants/index.d.ts +1 -0
  9. package/dist/framework/constants/index.js +17 -0
  10. package/dist/framework/core/PluginExecutionController.d.ts +15 -0
  11. package/dist/framework/core/PluginExecutionController.js +62 -0
  12. package/dist/framework/core/TaskManager.d.ts +12 -0
  13. package/dist/framework/core/TaskManager.js +67 -0
  14. package/dist/framework/core/TaskStage.d.ts +10 -0
  15. package/dist/framework/core/TaskStage.js +14 -0
  16. package/dist/framework/core/index.d.ts +3 -0
  17. package/dist/framework/core/index.js +19 -0
  18. package/dist/framework/extension/ExtensionManager.d.ts +11 -0
  19. package/dist/framework/extension/ExtensionManager.js +33 -0
  20. package/dist/framework/extension/PluginExtension.d.ts +13 -0
  21. package/dist/framework/extension/PluginExtension.js +6 -0
  22. package/dist/framework/extension/context/ExtensionContextImpl.d.ts +23 -0
  23. package/dist/framework/extension/context/ExtensionContextImpl.js +64 -0
  24. package/dist/framework/extension/context/Interface.d.ts +21 -0
  25. package/dist/framework/extension/context/Interface.js +2 -0
  26. package/dist/framework/extension/context/TemplateMetadataImpl.d.ts +12 -0
  27. package/dist/framework/extension/context/TemplateMetadataImpl.js +22 -0
  28. package/dist/framework/extension/index.d.ts +4 -0
  29. package/dist/framework/extension/index.js +20 -0
  30. package/dist/framework/index.d.ts +4 -0
  31. package/dist/framework/index.js +20 -0
  32. package/dist/framework/utils/FileUtil.d.ts +13 -0
  33. package/dist/framework/utils/FileUtil.js +20 -0
  34. package/dist/framework/utils/Logger.d.ts +12 -0
  35. package/dist/framework/utils/Logger.js +31 -0
  36. package/dist/framework/utils/ModuleTypeUtil.d.ts +4 -0
  37. package/dist/framework/utils/ModuleTypeUtil.js +16 -0
  38. package/dist/framework/utils/ObjectUtils.d.ts +3 -0
  39. package/dist/framework/utils/ObjectUtils.js +14 -0
  40. package/dist/framework/utils/PluginStore.d.ts +10 -0
  41. package/dist/framework/utils/PluginStore.js +29 -0
  42. package/dist/framework/utils/StringUtil.d.ts +3 -0
  43. package/dist/framework/utils/StringUtil.js +18 -0
  44. package/dist/framework/utils/TsAstUtil.d.ts +6 -0
  45. package/dist/framework/utils/TsAstUtil.js +19 -0
  46. package/dist/framework/utils/index.d.ts +7 -0
  47. package/dist/framework/utils/index.js +23 -0
  48. package/dist/hmrouter_extension/HMRouterExtension.d.ts +14 -0
  49. package/dist/hmrouter_extension/HMRouterExtension.js +47 -0
  50. package/dist/hmrouter_extension/HMRouterExtensionContext.d.ts +8 -0
  51. package/dist/hmrouter_extension/HMRouterExtensionContext.js +2 -0
  52. package/dist/hmrouter_extension/analyzer/AnnotationAnalyzerRegistry.d.ts +14 -0
  53. package/dist/hmrouter_extension/analyzer/AnnotationAnalyzerRegistry.js +45 -0
  54. package/dist/hmrouter_extension/analyzer/ComponentAnalyzer.d.ts +12 -0
  55. package/dist/hmrouter_extension/analyzer/ComponentAnalyzer.js +52 -0
  56. package/dist/hmrouter_extension/analyzer/RouterAnalyzer.d.ts +11 -0
  57. package/dist/hmrouter_extension/analyzer/RouterAnalyzer.js +79 -0
  58. package/dist/hmrouter_extension/analyzer/interface/AbstractAnnotationAnalyzer.d.ts +9 -0
  59. package/dist/hmrouter_extension/analyzer/interface/AbstractAnnotationAnalyzer.js +9 -0
  60. package/dist/hmrouter_extension/analyzer/interface/IConstantResolver.d.ts +7 -0
  61. package/dist/hmrouter_extension/analyzer/interface/IConstantResolver.js +2 -0
  62. package/dist/hmrouter_extension/analyzer/utils/ConstantAnalyzer.d.ts +9 -0
  63. package/dist/hmrouter_extension/analyzer/utils/ConstantAnalyzer.js +32 -0
  64. package/dist/hmrouter_extension/analyzer/utils/ConstantResolver.d.ts +15 -0
  65. package/dist/hmrouter_extension/analyzer/utils/ConstantResolver.js +217 -0
  66. package/dist/hmrouter_extension/analyzer/utils/DecoratorParser.d.ts +7 -0
  67. package/dist/hmrouter_extension/analyzer/utils/DecoratorParser.js +41 -0
  68. package/dist/hmrouter_extension/analyzer/utils/ImportAnalyzer.d.ts +4 -0
  69. package/dist/hmrouter_extension/analyzer/utils/ImportAnalyzer.js +35 -0
  70. package/dist/hmrouter_extension/config/HMRouterPluginConfig.d.ts +38 -0
  71. package/dist/hmrouter_extension/config/HMRouterPluginConfig.js +64 -0
  72. package/dist/hmrouter_extension/constants/AnnotationConstants.d.ts +8 -0
  73. package/dist/hmrouter_extension/constants/AnnotationConstants.js +11 -0
  74. package/dist/hmrouter_extension/constants/FilePathConstants.d.ts +19 -0
  75. package/dist/hmrouter_extension/constants/FilePathConstants.js +26 -0
  76. package/dist/hmrouter_extension/constants/ObfuscationConstants.d.ts +5 -0
  77. package/dist/hmrouter_extension/constants/ObfuscationConstants.js +8 -0
  78. package/dist/hmrouter_extension/constants/PluginConstants.d.ts +6 -0
  79. package/dist/hmrouter_extension/constants/PluginConstants.js +9 -0
  80. package/dist/hmrouter_extension/constants/PrefixConstants.d.ts +8 -0
  81. package/dist/hmrouter_extension/constants/PrefixConstants.js +11 -0
  82. package/dist/hmrouter_extension/constants/RouterMapConstants.d.ts +5 -0
  83. package/dist/hmrouter_extension/constants/RouterMapConstants.js +8 -0
  84. package/dist/hmrouter_extension/constants/TemplateConstants.d.ts +6 -0
  85. package/dist/hmrouter_extension/constants/TemplateConstants.js +9 -0
  86. package/dist/hmrouter_extension/constants/VersionConstants.d.ts +6 -0
  87. package/dist/hmrouter_extension/constants/VersionConstants.js +9 -0
  88. package/dist/hmrouter_extension/constants/index.d.ts +8 -0
  89. package/dist/hmrouter_extension/constants/index.js +22 -0
  90. package/dist/hmrouter_extension/error/PluginError.d.ts +29 -0
  91. package/dist/hmrouter_extension/error/PluginError.js +75 -0
  92. package/dist/hmrouter_extension/model/HMAnnotationModel.d.ts +28 -0
  93. package/dist/hmrouter_extension/model/HMAnnotationModel.js +2 -0
  94. package/dist/hmrouter_extension/model/RouterInfo.d.ts +6 -0
  95. package/dist/hmrouter_extension/model/RouterInfo.js +2 -0
  96. package/dist/hmrouter_extension/model/TemplateModel.d.ts +8 -0
  97. package/dist/hmrouter_extension/model/TemplateModel.js +2 -0
  98. package/dist/hmrouter_extension/model/index.d.ts +3 -0
  99. package/dist/hmrouter_extension/model/index.js +19 -0
  100. package/dist/hmrouter_extension/processor/CodeGenerationProcessor.d.ts +13 -0
  101. package/dist/hmrouter_extension/processor/CodeGenerationProcessor.js +117 -0
  102. package/dist/hmrouter_extension/processor/CompletionProcessor.d.ts +11 -0
  103. package/dist/hmrouter_extension/processor/CompletionProcessor.js +59 -0
  104. package/dist/hmrouter_extension/processor/ConfigUpdateProcessor.d.ts +11 -0
  105. package/dist/hmrouter_extension/processor/ConfigUpdateProcessor.js +53 -0
  106. package/dist/hmrouter_extension/processor/InitializerProcessor.d.ts +15 -0
  107. package/dist/hmrouter_extension/processor/InitializerProcessor.js +95 -0
  108. package/dist/hmrouter_extension/processor/ObfuscationProcessor.d.ts +13 -0
  109. package/dist/hmrouter_extension/processor/ObfuscationProcessor.js +121 -0
  110. package/dist/hmrouter_extension/processor/ResourceProcessor.d.ts +9 -0
  111. package/dist/hmrouter_extension/processor/ResourceProcessor.js +53 -0
  112. package/dist/hmrouter_extension/processor/RouterMapBuildingProcessor.d.ts +9 -0
  113. package/dist/hmrouter_extension/processor/RouterMapBuildingProcessor.js +122 -0
  114. package/dist/hmrouter_extension/processor/index.d.ts +7 -0
  115. package/dist/hmrouter_extension/processor/index.js +23 -0
  116. package/examples/CustomExtension.ts +256 -0
  117. package/package.json +2 -2
  118. package/template/customBuilder.ejs +1 -0
  119. package/template/viewBuilder.ejs +1 -0
  120. package/template/viewBuilder_v1.ejs +104 -0
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObfuscationProcessor = void 0;
4
+ const framework_1 = require("../../framework");
5
+ const constants_1 = require("../constants");
6
+ class ObfuscationProcessor {
7
+ constructor(context) {
8
+ this.context = context;
9
+ }
10
+ execute() {
11
+ framework_1.Logger.debug(this.context.node.getNodeName(), `Start to obfuscation...`);
12
+ if (!this.checkObfuscationEnabled()) {
13
+ framework_1.Logger.info(this.context.node.getNodeName(), 'This compilation does not turn on code obfuscation, skip hmrouter_obfuscation_rules.txt file generation');
14
+ return;
15
+ }
16
+ const obfuscationString = this.generateObfuscationRuleFile();
17
+ this.handleHarPackageLogic(obfuscationString);
18
+ }
19
+ checkObfuscationEnabled() {
20
+ return this.isEnableObfuscation();
21
+ }
22
+ generateObfuscationRuleFile() {
23
+ const obfuscationFilePath = framework_1.PluginFileUtil.pathResolve(this.context.config.modulePath, constants_1.FilePathConstants.OBFUSCATION_FILE_NAME);
24
+ const routerMap = JSON.parse(framework_1.PluginFileUtil.readFileSync(this.context.config.getRouterMapDir()).toString()).routerMap;
25
+ const obfuscationString = this.buildObfuscatedStrings(routerMap);
26
+ framework_1.PluginFileUtil.ensureFileSync(obfuscationFilePath);
27
+ framework_1.PluginFileUtil.writeFileSync(obfuscationFilePath, obfuscationString);
28
+ framework_1.Logger.info(this.context.node.getNodeName(), `Generate obfuscation rule file successfully, filePath: ${obfuscationFilePath}`);
29
+ return obfuscationString;
30
+ }
31
+ handleHarPackageLogic(obfuscationString) {
32
+ if (this.context.moduleContext.getModuleType() === constants_1.PluginConstants.HAR_MODULE_NAME) {
33
+ const consumerRulesPath = framework_1.PluginFileUtil.pathResolve(this.context.config.modulePath, constants_1.FilePathConstants.CONSUMER_FILE_NAME);
34
+ framework_1.PluginFileUtil.ensureFileSync(consumerRulesPath);
35
+ framework_1.PluginFileUtil.writeFileSync(consumerRulesPath, obfuscationString);
36
+ }
37
+ }
38
+ isEnableObfuscation() {
39
+ const currentBuildMode = framework_1.PluginStore.getInstance().get('buildMode');
40
+ const buildOption = this.context.moduleContext
41
+ ?.getBuildProfileOpt()
42
+ .buildOptionSet?.find((item) => item.name === currentBuildMode);
43
+ if (!buildOption) {
44
+ return false;
45
+ }
46
+ const arkOptions = framework_1.ObjectUtils.ensureNestedObject(buildOption, ['arkOptions']);
47
+ const obfuscationOptions = framework_1.ObjectUtils.ensureNestedObject(arkOptions, ['obfuscation']);
48
+ const ruleOptions = framework_1.ObjectUtils.ensureNestedObject(obfuscationOptions, ['ruleOptions']);
49
+ const isObfuscationEnabled = !!ruleOptions.enable;
50
+ if (!isObfuscationEnabled) {
51
+ return false;
52
+ }
53
+ if (this.context.config?.autoObfuscation) {
54
+ this.addHMRouterObfuscationRules(ruleOptions, obfuscationOptions);
55
+ }
56
+ return true;
57
+ }
58
+ addHMRouterObfuscationRules(ruleOptions, obfuscationOptions) {
59
+ const obfuscationFilePath = constants_1.FilePathConstants.CURRENT_DELIMITER + constants_1.FilePathConstants.OBFUSCATION_FILE_NAME;
60
+ ruleOptions.files = this.appendFilePathSafely(ruleOptions.files, obfuscationFilePath);
61
+ if (this.context.moduleContext.getModuleType() === constants_1.PluginConstants.HAR_MODULE_NAME) {
62
+ const consumerRulesPath = constants_1.FilePathConstants.CURRENT_DELIMITER + constants_1.FilePathConstants.CONSUMER_FILE_NAME;
63
+ obfuscationOptions.consumerFiles = this.appendFilePathSafely(obfuscationOptions.consumerFiles, consumerRulesPath);
64
+ }
65
+ }
66
+ appendFilePathSafely(target, filePath) {
67
+ if (typeof target === 'string') {
68
+ return target === filePath ? [target] : [target, filePath];
69
+ }
70
+ else if (Array.isArray(target)) {
71
+ if (!target.includes(filePath)) {
72
+ target.push(filePath);
73
+ }
74
+ return target;
75
+ }
76
+ else {
77
+ return [filePath];
78
+ }
79
+ }
80
+ buildObfuscatedStrings(routerMap) {
81
+ let srcPathArr = [
82
+ ...new Set(routerMap.map((routerInfo) => {
83
+ return constants_1.FilePathConstants.CURRENT_DELIMITER + routerInfo.pageSourceFile;
84
+ })),
85
+ ];
86
+ let classNameArr = [
87
+ ...new Set(routerMap
88
+ .filter((routerInfo) => {
89
+ return routerInfo.name.includes('__');
90
+ })
91
+ .map((routerInfo) => {
92
+ return routerInfo.customData.className;
93
+ })),
94
+ ];
95
+ let functionName = [
96
+ ...new Set(routerMap
97
+ .filter((routerInfo) => {
98
+ return routerInfo.name.includes(constants_1.PrefixConstants.SERVICE_PREFIX);
99
+ })
100
+ .map((routerInfo) => {
101
+ return routerInfo.customData.functionName;
102
+ })),
103
+ ];
104
+ let watchFunctionName = [
105
+ ...new Set(routerMap
106
+ .filter((routerInfo) => {
107
+ return routerInfo.buildFunction;
108
+ })
109
+ .map((routerInfo) => {
110
+ return routerInfo.buildFunction + constants_1.TemplateConstants.WARP_BUILDER;
111
+ })),
112
+ ];
113
+ return (constants_1.ObfuscationConstants.KEEP_FILE_NAME +
114
+ constants_1.FilePathConstants.LINE_BREAK +
115
+ srcPathArr
116
+ .concat(constants_1.ObfuscationConstants.KEEP_PROPERTY_NAME, functionName)
117
+ .concat(constants_1.ObfuscationConstants.KEEP_GLOBAL_NAME, classNameArr, watchFunctionName)
118
+ .join(constants_1.FilePathConstants.LINE_BREAK));
119
+ }
120
+ }
121
+ exports.ObfuscationProcessor = ObfuscationProcessor;
@@ -0,0 +1,9 @@
1
+ import { HMRouterExtensionContext } from '../HMRouterExtensionContext';
2
+ export declare class ResourceProcessProcessor {
3
+ private context;
4
+ constructor(context: HMRouterExtensionContext);
5
+ execute(): void;
6
+ private copyRouterMapToRawFile;
7
+ private processHspModuleName;
8
+ private getRemoteHspModuleNames;
9
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResourceProcessProcessor = void 0;
4
+ const framework_1 = require("../../framework");
5
+ const constants_1 = require("../constants");
6
+ class ResourceProcessProcessor {
7
+ constructor(context) {
8
+ this.context = context;
9
+ }
10
+ execute() {
11
+ framework_1.Logger.debug(this.context.node.getNodeName(), `Start to copy router map to raw file...`);
12
+ this.copyRouterMapToRawFile();
13
+ this.processHspModuleName();
14
+ }
15
+ copyRouterMapToRawFile() {
16
+ let routerMapFilePath = framework_1.PluginFileUtil.pathResolve(this.context.currentTarget?.getBuildTargetOutputPath(), constants_1.FilePathConstants.TEMP_ROUTER_MAP_PATH, this.context.currentTarget?.getTargetName(), constants_1.RouterMapConstants.ROUTER_MAP_NAME);
17
+ let rawFilePath = this.context.config.getRawFilePath();
18
+ framework_1.PluginFileUtil.ensureFileSync(rawFilePath);
19
+ framework_1.PluginFileUtil.copyFileSync(routerMapFilePath, rawFilePath);
20
+ framework_1.Logger.info(this.context.node.getNodeName(), `Copy router map to raw file successfully, filePath: ${rawFilePath}`);
21
+ }
22
+ processHspModuleName() {
23
+ if (!(0, framework_1.isHapModule)(this.context.node)) {
24
+ return;
25
+ }
26
+ let rawFilePath = this.context.config.getRawFilePath();
27
+ let rawFileRouterMap = JSON.parse(framework_1.PluginFileUtil.readFileSync(rawFilePath).toString());
28
+ rawFileRouterMap.hspModuleNames = [...new Set(framework_1.PluginStore.getInstance().get('hspModuleNames'))];
29
+ rawFileRouterMap.hspModuleNames.push(...this.getRemoteHspModuleNames(this.context.node.getAllPluginIds()));
30
+ framework_1.PluginFileUtil.writeFileSync(rawFilePath, JSON.stringify(rawFileRouterMap));
31
+ }
32
+ getRemoteHspModuleNames(pluginIds) {
33
+ let remoteHspModuleNames = [];
34
+ try {
35
+ pluginIds.forEach((id) => {
36
+ let context = this.context.node.getContext(id);
37
+ let signedHspObj = context.getOhpmRemoteHspDependencyInfo(true);
38
+ let remoteHspObj = context.getOhpmRemoteHspDependencyInfo(false);
39
+ for (const key in signedHspObj) {
40
+ remoteHspModuleNames.push(signedHspObj[key].name);
41
+ }
42
+ for (const key in remoteHspObj) {
43
+ remoteHspModuleNames.push(remoteHspObj[key].name);
44
+ }
45
+ });
46
+ }
47
+ catch (error) {
48
+ framework_1.Logger.warn(this.context.node.getNodeName(), 'Your DevEco Studio version less than 5.0.3.800, may cause remote hsp dependencies get failed');
49
+ }
50
+ return remoteHspModuleNames;
51
+ }
52
+ }
53
+ exports.ResourceProcessProcessor = ResourceProcessProcessor;
@@ -0,0 +1,9 @@
1
+ import { HMRouterExtensionContext } from '../HMRouterExtensionContext';
2
+ export declare class RouterMapBuildingProcessor {
3
+ private context;
4
+ constructor(context: HMRouterExtensionContext);
5
+ execute(): void;
6
+ private buildRouterMap;
7
+ private generateRouterMapFile;
8
+ private readExistingRouterMap;
9
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RouterMapBuildingProcessor = void 0;
4
+ const framework_1 = require("../../framework");
5
+ const constants_1 = require("../constants");
6
+ const AnnotationAnalyzerRegistry_1 = require("../analyzer/AnnotationAnalyzerRegistry");
7
+ const ConstantAnalyzer_1 = require("../analyzer/utils/ConstantAnalyzer");
8
+ const PluginError_1 = require("../error/PluginError");
9
+ class RouterMapBuildingProcessor {
10
+ constructor(context) {
11
+ this.context = context;
12
+ }
13
+ execute() {
14
+ framework_1.Logger.debug(this.context.node.getNodeName(), `Start to build router map...`);
15
+ this.readExistingRouterMap();
16
+ const constantResolver = AnnotationAnalyzerRegistry_1.AnnotationAnalyzerRegistry.getInstance().getConstantResolver();
17
+ const constantAnalyzer = new ConstantAnalyzer_1.ConstantAnalyzer(constantResolver);
18
+ constantAnalyzer.parseConstants(this.context.getAnalyzeResults());
19
+ for (const result of this.context.getAnalyzeResults()) {
20
+ this.buildRouterMap(result);
21
+ }
22
+ this.generateRouterMapFile();
23
+ }
24
+ buildRouterMap(result) {
25
+ if (!result.sourceFilePath) {
26
+ throw PluginError_1.PluginError.create(PluginError_1.ErrorCode.ERROR_PAGE_SOURCE_FILE, this.context.config.moduleName, result.sourceFilePath);
27
+ }
28
+ let pageSourceFile = this.context.config
29
+ .getRelativeSourcePath(result.sourceFilePath)
30
+ .replaceAll(constants_1.FilePathConstants.FILE_SEPARATOR, constants_1.FilePathConstants.DELIMITER);
31
+ if (result.annotation === constants_1.AnnotationConstants.ROUTER_ANNOTATION) {
32
+ let pageUrl = result.pageUrl;
33
+ let builderPath = this.context.generatedPaths.get(result.name) || '';
34
+ this.context.routerMap.push({
35
+ name: pageUrl,
36
+ pageSourceFile: builderPath,
37
+ buildFunction: result.name + 'Builder',
38
+ customData: result,
39
+ });
40
+ return;
41
+ }
42
+ const annotationConfig = {
43
+ [constants_1.AnnotationConstants.ANIMATOR_ANNOTATION]: {
44
+ prefix: constants_1.PrefixConstants.ANIMATOR_PREFIX,
45
+ propertyName: 'animatorName',
46
+ resultType: 'HMAnimatorResult',
47
+ },
48
+ [constants_1.AnnotationConstants.INTERCEPTOR_ANNOTATION]: {
49
+ prefix: constants_1.PrefixConstants.INTERCEPTOR_PREFIX,
50
+ propertyName: 'interceptorName',
51
+ resultType: 'HMInterceptorResult',
52
+ },
53
+ [constants_1.AnnotationConstants.LIFECYCLE_ANNOTATION]: {
54
+ prefix: constants_1.PrefixConstants.LIFECYCLE_PREFIX,
55
+ propertyName: 'lifecycleName',
56
+ resultType: 'HMLifecycleResult',
57
+ },
58
+ [constants_1.AnnotationConstants.SERVICE_ANNOTATION]: {
59
+ prefix: constants_1.PrefixConstants.SERVICE_PREFIX,
60
+ propertyName: 'serviceName',
61
+ resultType: 'HMServiceResult',
62
+ },
63
+ [constants_1.AnnotationConstants.SERVICE_PROVIDE_ANNOTATION]: {
64
+ prefix: constants_1.PrefixConstants.SERVICE_PROVIDE_PREFIX,
65
+ propertyName: 'serviceName',
66
+ resultType: 'HMServiceResult',
67
+ },
68
+ };
69
+ const config = annotationConfig[result.annotation];
70
+ const nameValue = result[config.propertyName];
71
+ const fullName = config.prefix + nameValue;
72
+ this.context.routerMap.push({
73
+ name: fullName,
74
+ pageSourceFile: pageSourceFile,
75
+ buildFunction: '',
76
+ customData: result,
77
+ });
78
+ }
79
+ generateRouterMapFile() {
80
+ let set = new Set();
81
+ this.context.routerMap.forEach((item) => {
82
+ if (set.has(item.name)) {
83
+ throw PluginError_1.PluginError.create(PluginError_1.ErrorCode.DUPLICATE_NAME, this.context.config.moduleName, item.name);
84
+ }
85
+ set.add(item.name);
86
+ });
87
+ let routerMap = {
88
+ routerMap: this.context.routerMap.map((item) => {
89
+ if (item.customData && item.customData.annotation) {
90
+ delete item.customData.annotation;
91
+ delete item.customData.sourceFilePath;
92
+ delete item.customData.isDefaultExport;
93
+ delete item.customData.templateData;
94
+ }
95
+ return item;
96
+ }),
97
+ };
98
+ const routerMapJsonStr = JSON.stringify(routerMap, null, 2);
99
+ const routerMapFilePath = this.context.config.getRouterMapDir();
100
+ framework_1.PluginFileUtil.ensureFileSync(routerMapFilePath);
101
+ framework_1.PluginFileUtil.writeFileSync(routerMapFilePath, routerMapJsonStr);
102
+ framework_1.Logger.info(this.context.node.getNodeName(), `hm_router_map.json has been generated in ${routerMapFilePath}`);
103
+ }
104
+ readExistingRouterMap() {
105
+ const moduleJsonOpt = this.context.moduleContext.getModuleJsonOpt();
106
+ if (!moduleJsonOpt?.module.routerMap) {
107
+ framework_1.Logger.debug(this.context.node.getNodeName(), `No routerMap found in the module configuration`);
108
+ return;
109
+ }
110
+ const routerMapFileName = moduleJsonOpt.module.routerMap.split(':')[1];
111
+ if (routerMapFileName !== 'hm_router_map') {
112
+ const routerMapFilePath = this.context.config.getModuleRouterMapFilePath(routerMapFileName);
113
+ const routerMapObj = framework_1.PluginFileUtil.readJson5(routerMapFilePath);
114
+ const systemRouterMap = routerMapObj[constants_1.RouterMapConstants.ROUTER_MAP_KEY];
115
+ if (systemRouterMap && systemRouterMap.length > 0) {
116
+ this.context.routerMap.unshift(...systemRouterMap);
117
+ framework_1.Logger.debug(this.context.node.getNodeName(), `System routerMap added to the current routerMap`);
118
+ }
119
+ }
120
+ }
121
+ }
122
+ exports.RouterMapBuildingProcessor = RouterMapBuildingProcessor;
@@ -0,0 +1,7 @@
1
+ export * from './CodeGenerationProcessor';
2
+ export * from './CompletionProcessor';
3
+ export * from './ConfigUpdateProcessor';
4
+ export * from './ObfuscationProcessor';
5
+ export * from './InitializerProcessor';
6
+ export * from './RouterMapBuildingProcessor';
7
+ export * from './ResourceProcessor';
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./CodeGenerationProcessor"), exports);
18
+ __exportStar(require("./CompletionProcessor"), exports);
19
+ __exportStar(require("./ConfigUpdateProcessor"), exports);
20
+ __exportStar(require("./ObfuscationProcessor"), exports);
21
+ __exportStar(require("./InitializerProcessor"), exports);
22
+ __exportStar(require("./RouterMapBuildingProcessor"), exports);
23
+ __exportStar(require("./ResourceProcessor"), exports);
@@ -0,0 +1,256 @@
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
+ import { appTasks } from '@ohos/hvigor-ohos-plugin';
17
+ import {
18
+ BaseAnalyzeResult,
19
+ ExtensionContext,
20
+ Logger,
21
+ PluginExtension,
22
+ registerPluginExtension
23
+ } from '@hadss/hmrouter-plugin';
24
+ import { ClassDeclaration, Expression, PropertyAssignment, SourceFile, SyntaxKind } from 'ts-morph';
25
+
26
+ interface RouterInfo {
27
+ name: string;
28
+ pageSourceFile: string;
29
+ buildFunction: string;
30
+ customData: Record<string, any>;
31
+ }
32
+
33
+ interface MyExtensionContext extends ExtensionContext {
34
+ customPages?: RouterInfo[];
35
+ routerMap: RouterInfo[];
36
+ }
37
+
38
+ interface MyAnalyzeResult extends BaseAnalyzeResult {
39
+ [key: string]: any;
40
+ }
41
+
42
+ // 示例1: RouterParam注解分析器
43
+ export class RouterParamAnalyzer {
44
+ readonly name = 'RouterParamAnalyzer';
45
+
46
+ analyze(sourceFile: SourceFile, filePath: string, context: MyExtensionContext): void {
47
+ Logger.debug('', `开始分析RouterParam注解: ${filePath}`);
48
+
49
+ // 获取所有ExpressionStatement以获取struct关键字后面的组件名称
50
+ const viewNameArr = sourceFile
51
+ .getChildrenOfKind(SyntaxKind.ExpressionStatement)
52
+ .map((node) => node.getText())
53
+ .filter((text) => text !== 'struct');
54
+
55
+ // 解析结构体声明中的RouterParam注解
56
+ sourceFile.getChildrenOfKind(SyntaxKind.MissingDeclaration).forEach((node, index) => {
57
+ node.getChildrenOfKind(SyntaxKind.Decorator).forEach((decorator) => {
58
+ if (decorator.getName() === "RouterParam") {
59
+ // 解析RouterParam注解的参数
60
+ const result: MyAnalyzeResult = {
61
+ name: viewNameArr[index],
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
+ });
84
+
85
+ // 如果需要后续保存到路由表中请调用addAnalyzeResults添加分析结果
86
+ // context.addAnalyzeResults(result);
87
+
88
+ // 为组件添加模板数据,用于代码生成
89
+ context.addTemplateData(result.name, {
90
+ paramType: result['paramType'] || 'default',
91
+ isCustomParam: true,
92
+ customParams: result['params'] || [],
93
+ sourceFile: filePath
94
+ });
95
+
96
+ Logger.debug('', `发现RouterParam注解: ${result.name}`);
97
+ }
98
+ });
99
+ });
100
+ }
101
+
102
+ private parsePrimitiveValue(value: Expression): any {
103
+ let propertyValue;
104
+ switch (value.getKind()) {
105
+ case SyntaxKind.StringLiteral:
106
+ propertyValue = value.asKind(SyntaxKind.StringLiteral)?.getLiteralValue();
107
+ break;
108
+ case SyntaxKind.NumericLiteral:
109
+ propertyValue = value.asKind(SyntaxKind.NumericLiteral)?.getLiteralValue();
110
+ break;
111
+ case SyntaxKind.TrueKeyword:
112
+ propertyValue = true;
113
+ break;
114
+ case SyntaxKind.FalseKeyword:
115
+ propertyValue = false;
116
+ break;
117
+ case SyntaxKind.ArrayLiteralExpression:
118
+ propertyValue = value
119
+ .asKind(SyntaxKind.ArrayLiteralExpression)
120
+ ?.getElements()
121
+ .map((item) => {
122
+ if (item.getKind() === SyntaxKind.StringLiteral) {
123
+ return item.asKind(SyntaxKind.StringLiteral)?.getLiteralValue();
124
+ }
125
+ return null;
126
+ })
127
+ .filter(item => item !== null);
128
+ break;
129
+ }
130
+ return propertyValue;
131
+ }
132
+ }
133
+
134
+ // 示例2: CustomPage注解分析器
135
+ export class CustomPageAnalyzer {
136
+ readonly name = 'CustomPageAnalyzer';
137
+
138
+ analyze(sourceFile: SourceFile, filePath: string, context: MyExtensionContext): void {
139
+ Logger.debug('', `开始分析CustomPage注解: ${filePath}`);
140
+
141
+ // 分析使用@CustomPage注解的类
142
+ sourceFile.getClasses().forEach((cls: ClassDeclaration) => {
143
+ cls.getDecorators().forEach(decorator => {
144
+ if (decorator.getName() === 'CustomPage') {
145
+ const className = cls.getName() || '';
146
+
147
+ // 创建分析结果
148
+ const result: MyAnalyzeResult = {
149
+ name: className,
150
+ annotation: 'CustomPage',
151
+ sourceFilePath: filePath
152
+ };
153
+
154
+ // 解析装饰器参数
155
+ decorator.getArguments().forEach((arg) => {
156
+ const objLiteral = arg.asKind(SyntaxKind.ObjectLiteralExpression);
157
+ if (objLiteral) {
158
+ objLiteral.getProperties().forEach((prop) => {
159
+ if (prop.getKind() === SyntaxKind.PropertyAssignment) {
160
+ const propertyAssignment = prop as PropertyAssignment;
161
+ const propertyName = propertyAssignment.getName();
162
+ const initializer = propertyAssignment.getInitializer();
163
+
164
+ if (initializer && initializer.getKind() === SyntaxKind.StringLiteral) {
165
+ result[propertyName] = initializer.asKind(SyntaxKind.StringLiteral)?.getLiteralValue();
166
+ }
167
+ }
168
+ });
169
+ }
170
+ });
171
+
172
+ // 添加分析结果
173
+ context.addAnalyzeResults(result);
174
+
175
+ // 存储自定义页面路径信息
176
+ const customPages = context.customPages || [];
177
+ customPages.push(result);
178
+ context.customPages = customPages;
179
+
180
+ Logger.debug('', `发现CustomPage注解: ${className}, pageUrl: ${result['pageUrl']}`);
181
+ }
182
+ });
183
+ });
184
+ }
185
+ }
186
+
187
+ // 插件扩展类
188
+ export class CustomPluginExtension extends PluginExtension<MyExtensionContext> {
189
+ get name(): string {
190
+ return 'CustomPluginExtension';
191
+ }
192
+
193
+ // 提供注解分析器
194
+ afterAnnotationAnalysis(sourceFile: SourceFile, filePath: string, context: MyExtensionContext): void {
195
+ const analyzers = [new RouterParamAnalyzer(), new CustomPageAnalyzer()];
196
+ for (const analyzer of analyzers) {
197
+ analyzer.analyze(sourceFile, filePath, context);
198
+ }
199
+ }
200
+
201
+ // 代码生成阶段,可以使用RouterParam注解分析结果
202
+ afterCodeGeneration(context: MyExtensionContext): void {
203
+ // 获取所有模板数据
204
+ const templateDataMap = context.getTemplateDataMap();
205
+
206
+ // 示例: 输出找到的RouterParam数据
207
+ for (const [componentName, templateData] of templateDataMap.entries()) {
208
+ if (templateData.isCustomParam) {
209
+ Logger.info(
210
+ this.name,
211
+ `组件 ${componentName} 将使用自定义参数类型: ${templateData.paramType}`
212
+ );
213
+ // 实际场景可以在此生成额外的代码
214
+ }
215
+ }
216
+ }
217
+
218
+ // 路由表构建阶段,将CustomPage注解分析结果添加到路由表
219
+ afterRouterMapBuilding(context: MyExtensionContext): void {
220
+ // 从私有存储获取CustomPage分析结果
221
+ const customPages = context.customPages || [];
222
+
223
+ // 将CustomPage添加到路由表
224
+ for (const page of customPages) {
225
+ const pageUrl = page.customData['pageUrl'];
226
+ if (pageUrl) {
227
+ // 检查路由表中是否已存在该路径
228
+ const existingRoute = context.routerMap.find(route => route.customData.pageUrl === pageUrl);
229
+ if (!existingRoute) {
230
+ // 创建新的路由项并添加到路由表
231
+ context.routerMap.push({
232
+ name: pageUrl,
233
+ buildFunction: page.name,
234
+ pageSourceFile: page.pageSourceFile,
235
+ customData: {
236
+ ...page.customData,
237
+ }
238
+ });
239
+
240
+ Logger.info(
241
+ this.name,
242
+ `添加自定义页面到路由表: ${pageUrl} -> ${page.name}`
243
+ );
244
+ }
245
+ }
246
+ }
247
+ }
248
+ }
249
+
250
+ // 注册扩展
251
+ registerPluginExtension(new CustomPluginExtension());
252
+
253
+ export default {
254
+ system: appTasks,
255
+ plugins: []
256
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hadss/hmrouter-plugin",
3
- "version": "1.1.0-beta.0",
3
+ "version": "1.1.1-alpha.0",
4
4
  "description": "HMRouter Compiler Plugin",
5
5
  "main": "dist/Index.js",
6
6
  "scripts": {
@@ -42,7 +42,7 @@
42
42
  "homepage": "https://gitcode.com/openharmony-sig/ohrouter",
43
43
  "repository": {
44
44
  "type": "git",
45
- "url": "git+https://gitcode.com/openharmony-sig/ohrouter.git",
45
+ "url": "https://gitcode.com/openharmony-sig/ohrouter.git",
46
46
  "directory": "HMRouterPlugin"
47
47
  }
48
48
  }
@@ -13,6 +13,7 @@
13
13
  * limitations under the License.
14
14
  */
15
15
 
16
+ // instrument ignore file
16
17
  // auto-generated <%= componentName %>Builder.ets by HMRouter
17
18
  import <%if(isDefaultExport) {%> <%= componentName %> <% } else {%> { <%= componentName %> } <% } %> from '<%= importPath %>'
18
19
 
@@ -13,6 +13,7 @@
13
13
  * limitations under the License.
14
14
  */
15
15
 
16
+ // instrument ignore file
16
17
  // auto-generated <%= componentName %>Builder.ets by HMRouter
17
18
  import <%if(isDefaultExport) {%> <%= componentName %> <% } else {%> { <%= componentName %> } <% } %> from '<%= importPath %>'
18
19
  import { NavDestinationHelper } from '@hadss/hmrouter';