@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 CHANGED
@@ -21,7 +21,7 @@ HMRouter编译插件是一个基于hvigor的编译插件,用于:
21
21
  ```json5
22
22
  {
23
23
  "dependencies": {
24
- "@hadss/hmrouter-plugin": "^1.2.0-rc.0" // 使用最新版本
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
- node.subNodes(subNode => {
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
- if (!aIsHMRouter && bIsHMRouter)
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, any> | undefined;
19
- getTemplateDataMap(): Map<string, Record<string, any>>;
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, ...args: unknown[]) => void;
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
- const viewResult = currentView[i];
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
- if (prop.getKind() === ts_morph_1.SyntaxKind.PropertyAssignment) {
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?: any;
26
- constructor(code: ErrorCode, module: string, params?: string | string[], data?: any);
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,6 +1,6 @@
1
1
  import { BaseAnalyzeResult } from '../../framework';
2
2
  export interface HMRouterResult extends BaseAnalyzeResult {
3
- pageUrl: any;
3
+ pageUrl: string;
4
4
  dialog?: boolean;
5
5
  singleton?: boolean;
6
6
  interceptors?: string[];
@@ -1,4 +1,5 @@
1
1
  export interface TemplateModel {
2
+ sdkVersion: number;
2
3
  pageUrl: string;
3
4
  importPath: string;
4
5
  componentName: string;
@@ -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
- try {
95
- if (framework_1.PluginFileUtil.exist(packagePath)) {
96
- const packageJson = framework_1.PluginFileUtil.readJson5(packagePath);
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
- catch (error) {
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
- if (!buildOption) {
41
- return false;
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
- const arkOptions = framework_1.ObjectUtils.ensureNestedObject(buildOption, ['arkOptions']);
44
- const obfuscationOptions = framework_1.ObjectUtils.ensureNestedObject(arkOptions, ['obfuscation']);
45
- const ruleOptions = framework_1.ObjectUtils.ensureNestedObject(obfuscationOptions, ['ruleOptions']);
46
- const isObfuscationEnabled = !!ruleOptions.enable;
47
- if (!isObfuscationEnabled) {
48
- return false;
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
- if (this.context.config?.autoObfuscation) {
51
- this.addHMRouterObfuscationRules(ruleOptions, obfuscationOptions);
67
+ else {
68
+ return false;
52
69
  }
53
70
  return true;
54
71
  }
@@ -4,6 +4,7 @@ export declare class RouterMapBuildingProcessor {
4
4
  constructor(context: HMRouterExtensionContext);
5
5
  execute(): void;
6
6
  private buildRouterMap;
7
+ private useAnnotationConfig;
7
8
  private generateRouterMapFile;
8
9
  private readExistingRouterMap;
9
10
  }
@@ -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
- 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
- });
58
+ this.getDecorator(decorator, viewNameArr, index, filePath, context);
59
+ });
60
+ });
61
+ }
84
62
 
85
- // 如果需要后续保存到路由表中请调用addAnalyzeResults添加分析结果
86
- // context.addAnalyzeResults(result);
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
- context.addTemplateData(result.name, {
90
- paramType: result['paramType'] || 'default',
91
- isCustomParam: true,
92
- customParams: result['params'] || [],
93
- sourceFile: filePath
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
- Logger.debug('', `发现RouterParam注解: ${result.name}`);
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): any {
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
- 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
- });
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
- context.addAnalyzeResults(result);
176
+ // 存储自定义页面路径信息
177
+ const customPages = context.customPages || [];
178
+ customPages.push(result);
179
+ context.customPages = customPages;
174
180
 
175
- // 存储自定义页面路径信息
176
- const customPages = context.customPages || [];
177
- customPages.push(result);
178
- context.customPages = customPages;
181
+ Logger.debug('', `发现CustomPage注解: ${className}, pageUrl: ${result.pageUrl}`);
182
+ }
183
+ }
179
184
 
180
- Logger.debug('', `发现CustomPage注解: ${className}, pageUrl: ${result['pageUrl']}`);
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['pageUrl'];
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.0-rc.0",
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
- "release": "rm -rf ./dist && tsc && npm publish --access public"
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",
@@ -30,22 +30,87 @@ export struct <%= componentName %>Generated {
30
30
  private helper: NavDestinationHelper = new NavDestinationHelper(this);
31
31
 
32
32
  build() {
33
- NavDestination() {
34
- <%= componentName %>()
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
- <% if(dialog){ %>.mode(NavDestinationMode.DIALOG)<% } %>
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
  }