@hadss/turbo-trans-json-plugin 1.0.0-rc.0 → 1.0.0-rc.2

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 (88) hide show
  1. package/README.md +1 -1
  2. package/dist/core/Types.d.ts +7 -0
  3. package/dist/core/Types.js +7 -1
  4. package/dist/core/analyzers/ClassAnalyzer.d.ts +15 -0
  5. package/dist/core/analyzers/ClassAnalyzer.js +200 -120
  6. package/dist/core/analyzers/CustomTypeAnalyzer.d.ts +3 -0
  7. package/dist/core/analyzers/CustomTypeAnalyzer.js +65 -60
  8. package/dist/core/constants/DecoratorConstants.d.ts +1 -0
  9. package/dist/core/constants/DecoratorConstants.js +3 -1
  10. package/dist/core/handlers/CustomClassHandler.js +0 -1
  11. package/dist/core/import-rewrite/services/BuildProfileUpdater.js +1 -1
  12. package/dist/core/import-rewrite/services/ImportRewriteService.js +1 -1
  13. package/dist/core/interfaces/index.d.ts +2 -2
  14. package/dist/core/services/CodeAnalysisService.js +2 -1
  15. package/dist/core/services/CodeGenerationService/CodeGenerationService.js +1 -1
  16. package/dist/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.d.ts +0 -1
  17. package/dist/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.js +0 -20
  18. package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.d.ts +4 -4
  19. package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.js +26 -45
  20. package/dist/core/services/CodeGenerationService/generators/SendableClassGenerator.d.ts +22 -0
  21. package/dist/core/services/CodeGenerationService/generators/SendableClassGenerator.js +194 -129
  22. package/dist/core/services/CodeGenerationService/generators/SerializerGenerator.js +20 -15
  23. package/dist/core/services/CodeGenerationService/generators/TempSerializerGenerator.js +2 -1
  24. package/dist/core/services/CodeGenerationService/shared/ImportManager.d.ts +2 -2
  25. package/dist/core/template/HandlebarsTemplateEngine.d.ts +2 -0
  26. package/dist/core/template/HandlebarsTemplateEngine.js +24 -2
  27. package/dist/core/utils/DeepCopyUtil.js +4 -2
  28. package/dist/core/utils/GenericTypeSubstitutionUtil.d.ts +1 -0
  29. package/dist/core/utils/GenericTypeSubstitutionUtil.js +27 -1
  30. package/dist/core/utils/SerializationPathUtil.d.ts +1 -1
  31. package/dist/core/utils/TsMorphUtil.js +6 -1
  32. package/dist/json-plugin/JSONExecuteController.d.ts +4 -0
  33. package/dist/json-plugin/JSONExecuteController.js +46 -36
  34. package/dist/json-plugin/interfaces/impl/TargetContext.js +4 -2
  35. package/dist/json-plugin/tasks/BaseTask.d.ts +2 -2
  36. package/dist/json-plugin/tasks/WatchTask.js +2 -1
  37. package/package.json +1 -1
  38. package/src/core/Types.ts +97 -89
  39. package/src/core/analyzers/ClassAnalyzer.ts +358 -197
  40. package/src/core/analyzers/CustomTypeAnalyzer.ts +145 -74
  41. package/src/core/constants/DecoratorConstants.ts +7 -5
  42. package/src/core/constants/PathConstants.ts +7 -7
  43. package/src/core/constants/StringConstants.ts +95 -97
  44. package/src/core/handlers/BaseTypeHandler.ts +11 -2
  45. package/src/core/handlers/CustomClassHandler.ts +4 -7
  46. package/src/core/handlers/DateHandler.ts +54 -46
  47. package/src/core/handlers/DecimalHandler.ts +53 -45
  48. package/src/core/handlers/EnumHandler.ts +2 -1
  49. package/src/core/handlers/GenericContainerHandler.ts +3 -1
  50. package/src/core/handlers/TupleHandler.ts +2 -1
  51. package/src/core/handlers/TypeHandlerRegistry.ts +3 -2
  52. package/src/core/handlers/UnionTypeHandler.ts +8 -7
  53. package/src/core/import-rewrite/services/BuildProfileUpdater.ts +7 -5
  54. package/src/core/import-rewrite/services/ImportRewriteService.ts +1 -3
  55. package/src/core/import-rewrite/services/ImportTransformService.ts +2 -2
  56. package/src/core/import-rewrite/types/ImportRewriteTypes.ts +3 -3
  57. package/src/core/index.ts +4 -4
  58. package/src/core/interfaces/ITask.ts +6 -5
  59. package/src/core/interfaces/ITaskContext.ts +9 -9
  60. package/src/core/interfaces/index.ts +2 -2
  61. package/src/core/logger/Logger.ts +28 -28
  62. package/src/core/services/CodeAnalysisService.ts +3 -2
  63. package/src/core/services/CodeGenerationEngine.ts +42 -42
  64. package/src/core/services/CodeGenerationService/CodeGenerationService.ts +1 -2
  65. package/src/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.ts +0 -29
  66. package/src/core/services/CodeGenerationService/generators/OriginalClassGenerator.ts +31 -64
  67. package/src/core/services/CodeGenerationService/generators/SendableClassGenerator.ts +261 -170
  68. package/src/core/services/CodeGenerationService/generators/SerializerGenerator.ts +26 -19
  69. package/src/core/services/CodeGenerationService/generators/TempSerializerGenerator.ts +5 -3
  70. package/src/core/services/CodeGenerationService/shared/ImportManager.ts +8 -8
  71. package/src/core/template/HandlebarsTemplateEngine.ts +43 -10
  72. package/src/core/utils/ConfigManager.ts +2 -1
  73. package/src/core/utils/DeepCopyUtil.ts +4 -2
  74. package/src/core/utils/GenericTypeSubstitutionUtil.ts +45 -2
  75. package/src/core/utils/SerializationPathUtil.ts +7 -6
  76. package/src/core/utils/TsMorphUtil.ts +9 -2
  77. package/src/index.ts +2 -2
  78. package/src/json-plugin/JSONExecuteController.ts +51 -38
  79. package/src/json-plugin/interfaces/IModuleContext.ts +8 -8
  80. package/src/json-plugin/interfaces/ITargetContext.ts +6 -6
  81. package/src/json-plugin/interfaces/impl/ModuleContext.ts +10 -10
  82. package/src/json-plugin/interfaces/impl/TargetContext.ts +63 -58
  83. package/src/json-plugin/tasks/BaseTask.ts +5 -4
  84. package/src/json-plugin/tasks/CleanTask.ts +7 -7
  85. package/src/json-plugin/tasks/WatchTask.ts +20 -18
  86. package/template/SerializerPerformanceTemplate.hbs +14 -4
  87. package/template/SerializerStrictTemplate.hbs +9 -1
  88. package/template/SerializerTemplate.hbs +71 -46
@@ -13,8 +13,13 @@
13
13
  * limitations under the License.
14
14
  */
15
15
 
16
- import { ClassDeclaration, SourceFile } from 'ts-morph';
17
- import { ClassAnalysis, ClassDetails, Logger, PropertyAnalysis, PropertyKind, TypeKind, TypeStructure } from '../../..';
16
+ import {
17
+ ClassDeclaration, ConstructorDeclaration, Decorator, Identifier, ImportDeclaration, ParameterDeclaration,
18
+ PropertyDeclaration, SourceFile
19
+ } from 'ts-morph';
20
+ import {
21
+ ClassAnalysis, ClassDetails, Logger, PropertyAnalysis, PropertyKind, TypeDependency, TypeKind, TypeStructure
22
+ } from '../../..';
18
23
  import { ImportManager } from '../shared/ImportManager';
19
24
  import { ClassAnalyzer } from '../../../analyzers/ClassAnalyzer';
20
25
  import { TypeHandlerRegistry } from '../../../handlers';
@@ -64,7 +69,8 @@ export class SendableClassGenerator {
64
69
 
65
70
  private getOriginClassDeclaration(result: ClassAnalysis): ClassDeclaration {
66
71
  const originalContent = result.originalClass?.getFullText();
67
- const copiedSourceFile = TsMorphUtil.getProject().createSourceFile('copied-file.ts', originalContent, { overwrite: true });
72
+ const copiedSourceFile = TsMorphUtil.getProject()
73
+ .createSourceFile('copied-file.ts', originalContent, { overwrite: true });
68
74
  return copiedSourceFile.getClassOrThrow(result.className);
69
75
  }
70
76
 
@@ -90,77 +96,93 @@ export class SendableClassGenerator {
90
96
  }
91
97
 
92
98
  private removeAllDecorators(classDecl: ClassDeclaration): void {
93
- // 剔除类级别装饰器
99
+ this.removeClassDecorators(classDecl);
100
+ this.removePropertyDecorators(classDecl);
101
+ this.removeMethodDecorators(classDecl);
102
+ }
103
+
104
+ private removeClassDecorators(classDecl: ClassDeclaration): void {
94
105
  classDecl.getDecorators().forEach((decorator) => {
95
- Logger.warn(
96
- `Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`
97
- );
98
- decorator.remove();
106
+ this.logAndRemoveDecorator(decorator);
99
107
  });
108
+ }
100
109
 
101
- // 剔除属性装饰器,@Sendable无法与其他装饰器共存
110
+ private removePropertyDecorators(classDecl: ClassDeclaration): void {
102
111
  classDecl.getProperties().forEach((property) => {
103
- property.getDecorators().forEach((decorator) => {
104
- Logger.warn(
105
- `Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`
106
- );
107
- decorator.remove();
108
- });
112
+ property.getDecorators().forEach((decorator) => this.logAndRemoveDecorator(decorator));
109
113
  });
114
+ }
110
115
 
111
- // 剔除方法装饰器,@Sendable无法与其他装饰器共存
116
+ private removeMethodDecorators(classDecl: ClassDeclaration): void {
112
117
  classDecl.getMethods().forEach((method) => {
113
- method.getDecorators().forEach((decorator) => {
114
- Logger.warn(
115
- `Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`
116
- );
117
- decorator.remove();
118
- });
118
+ method.getDecorators().forEach((decorator) => this.logAndRemoveDecorator(decorator));
119
119
  });
120
120
  }
121
121
 
122
+ private logAndRemoveDecorator(decorator: Decorator): void {
123
+ Logger.warn(
124
+ `Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`
125
+ );
126
+ decorator.remove();
127
+ }
128
+
122
129
  private convertPropertyTypesToSendable(classDecl: ClassDeclaration, result: ClassAnalysis): void {
123
130
  const properties = classDecl.getProperties();
124
-
125
131
  properties.forEach((property) => {
126
- const propertyName = property.getName();
127
-
128
- Logger.debug(`Converting property ${propertyName} to sendable`);
129
-
130
- // 从分析结果中找到对应的属性信息
131
- const propertyAnalysis = result.properties.find((p) => p.name === propertyName);
132
- if (!propertyAnalysis) {
133
- Logger.warn(`未找到属性 ${propertyName} 的分析信息`);
134
- return;
135
- }
136
-
137
- Logger.debug(
138
- `Found property ${propertyName} analysis info: ${propertyAnalysis.name} ${propertyAnalysis.type.sourceText}`
139
- );
140
-
141
- // 转换类型为Sendable兼容类型
142
- const sendableType = this.convertToSendableType(propertyAnalysis.type);
143
-
144
- Logger.debug(`Converted type ${propertyAnalysis.type.sourceText} to ${sendableType}`);
145
-
146
- if (sendableType !== propertyAnalysis.type.sourceText) {
147
- property.setType(sendableType);
148
- Logger.debug(`属性 ${propertyName} 类型从 ${propertyAnalysis.type.sourceText} 转换为 ${sendableType}`);
149
- }
150
-
151
- // 处理默认值中的构造函数调用
152
- const initializer = property.getInitializer();
153
- if (initializer) {
154
- const initializerText = initializer.getText();
155
- const convertedInitializer = this.convertInitializerToSendable(initializerText);
156
- if (convertedInitializer !== initializerText) {
157
- property.setInitializer(convertedInitializer);
158
- Logger.debug(`属性 ${propertyName} 默认值从 ${initializerText} 转换为 ${convertedInitializer}`);
159
- }
160
- }
132
+ this.convertSinglePropertyToSendable(property, result);
161
133
  });
162
134
  }
163
135
 
136
+ private convertSinglePropertyToSendable(
137
+ property: PropertyDeclaration,
138
+ result: ClassAnalysis
139
+ ): void {
140
+ const propertyName = property.getName();
141
+ Logger.debug(`Converting property ${propertyName} to sendable`);
142
+
143
+ const propertyAnalysis = result.properties.find((p) => p.name === propertyName);
144
+ if (!propertyAnalysis) {
145
+ Logger.warn(`未找到属性 ${propertyName} 的分析信息`);
146
+ return;
147
+ }
148
+
149
+ Logger.debug(
150
+ `Found property ${propertyName} analysis info: ${propertyAnalysis.name} ${propertyAnalysis.type.sourceText}`
151
+ );
152
+
153
+ this.updatePropertyType(property, propertyAnalysis);
154
+ this.updatePropertyInitializer(property, propertyAnalysis.name);
155
+ }
156
+
157
+ private updatePropertyType(
158
+ property: PropertyDeclaration,
159
+ propertyAnalysis: PropertyAnalysis
160
+ ): void {
161
+ const sendableType = this.convertToSendableType(propertyAnalysis.type);
162
+ Logger.debug(`Converted type ${propertyAnalysis.type.sourceText} to ${sendableType}`);
163
+
164
+ if (sendableType !== propertyAnalysis.type.sourceText) {
165
+ property.setType(sendableType);
166
+ Logger.debug(`属性 ${propertyAnalysis.name} 类型从 ${propertyAnalysis.type.sourceText} 转换为 ${sendableType}`);
167
+ }
168
+ }
169
+
170
+ private updatePropertyInitializer(
171
+ property: PropertyDeclaration,
172
+ propertyName: string
173
+ ): void {
174
+ const initializer = property.getInitializer();
175
+ if (!initializer) {
176
+ return;
177
+ }
178
+ const initializerText = initializer.getText();
179
+ const convertedInitializer = this.convertInitializerToSendable(initializerText);
180
+ if (convertedInitializer !== initializerText) {
181
+ property.setInitializer(convertedInitializer);
182
+ Logger.debug(`属性 ${propertyName} 默认值从 ${initializerText} 转换为 ${convertedInitializer}`);
183
+ }
184
+ }
185
+
164
186
  private addSendableConstraints(classDecl: ClassDeclaration): void {
165
187
  // 添加@Sendable装饰器
166
188
  classDecl.addDecorator({ name: 'Sendable' });
@@ -187,7 +209,29 @@ export class SendableClassGenerator {
187
209
 
188
210
  private generatedToOriginMethodBody(result: ClassAnalysis, returnType: string): string {
189
211
  const statements: string[] = [];
190
- let constructorCall;
212
+ const constructorCall = this.getConstructorCall(result, returnType);
213
+ statements.push(`const origin = ${constructorCall};`);
214
+
215
+ const assignmentProps = result.properties.filter((p) => {
216
+ return result.constructorParams.every((cp) => cp.name !== p.name);
217
+ });
218
+ // 生成属性赋值语句
219
+ if (assignmentProps.length > 0) {
220
+ statements.push('');
221
+ statements.push('// 非构造函数属性赋值');
222
+ assignmentProps.forEach((prop) => {
223
+ const assignment = this.generatePropertyConversion(prop, 'this.');
224
+ statements.push(`origin.${prop.name} = ${assignment};`);
225
+ });
226
+ }
227
+
228
+ statements.push('');
229
+ statements.push('return origin;');
230
+
231
+ return statements.join('\n');
232
+ }
233
+
234
+ private getConstructorCall(result: ClassAnalysis, returnType: string): string {
191
235
  if (result.constructorParams.length > 0) {
192
236
  const constructorProps: PropertyAnalysis[] = [];
193
237
  result.properties.forEach((p) => {
@@ -209,29 +253,10 @@ export class SendableClassGenerator {
209
253
  })
210
254
  .join(', ');
211
255
 
212
- constructorCall = `new ${returnType}(${args})`;
256
+ return `new ${returnType}(${args})`;
213
257
  } else {
214
- constructorCall = `new ${returnType}()`;
258
+ return `new ${returnType}()`;
215
259
  }
216
- statements.push(`const origin = ${constructorCall};`);
217
-
218
- const assignmentProps = result.properties.filter((p) => {
219
- return result.constructorParams.every((cp) => cp.name !== p.name);
220
- });
221
- // 生成属性赋值语句
222
- if (assignmentProps.length > 0) {
223
- statements.push('');
224
- statements.push('// 非构造函数属性赋值');
225
- assignmentProps.forEach((prop) => {
226
- const assignment = this.generatePropertyConversion(prop, 'this.');
227
- statements.push(`origin.${prop.name} = ${assignment};`);
228
- });
229
- }
230
-
231
- statements.push('');
232
- statements.push('return origin;');
233
-
234
- return statements.join('\n');
235
260
  }
236
261
 
237
262
  private generatePropertyConversion(prop: PropertyAnalysis, prefix: string): string {
@@ -257,84 +282,141 @@ export class SendableClassGenerator {
257
282
  }
258
283
 
259
284
  private addNecessaryImports(result: ClassAnalysis, importManager: ImportManager): void {
260
- // 1. 处理类导入
285
+ this.processPropertyDependencyImports(result, importManager);
286
+ this.processBaseClassImport(result, importManager);
287
+ this.processCollectionsImport(result, importManager);
288
+ this.copySourceFileImports(result, importManager);
289
+ }
290
+
291
+ private processPropertyDependencyImports(result: ClassAnalysis, importManager: ImportManager): void {
261
292
  result.properties.forEach((property) => {
262
293
  property.type.dependencies.forEach((dependency) => {
263
- if (dependency.typeKind === TypeKind.CLASS) {
264
- const classAnalysis = ClassAnalyzer.analyzeClass((dependency.details as ClassDetails).classDecl);
265
- if (classAnalysis.decorators.serializable?.generateSendable) {
266
- importManager.registerCustomImport('./Sendable' + dependency.typeName, 'Sendable' + dependency.typeName);
267
- } else {
268
- importManager.registerCustomTypeImport(dependency.source.sourceFilePath!, dependency.typeName);
269
- }
270
- } else {
271
- importManager.registerCustomTypeImport(dependency.source.sourceFilePath!, dependency.typeName);
272
- }
294
+ this.registerDependencyImport(dependency, importManager);
273
295
  });
274
296
  });
297
+ }
298
+
299
+ private registerDependencyImport(
300
+ dependency: TypeDependency,
301
+ importManager: ImportManager
302
+ ): void {
303
+ if (dependency.typeKind !== TypeKind.CLASS) {
304
+ importManager.registerCustomTypeImport(dependency.source.sourceFilePath!, dependency.typeName);
305
+ return;
306
+ }
307
+ const classAnalysis = ClassAnalyzer.analyzeClass((dependency.details as ClassDetails).classDecl);
308
+ if (classAnalysis.decorators.serializable?.generateSendable) {
309
+ importManager.registerCustomImport('./Sendable' + dependency.typeName, 'Sendable' + dependency.typeName);
310
+ } else {
311
+ importManager.registerCustomTypeImport(dependency.source.sourceFilePath!, dependency.typeName);
312
+ }
313
+ }
275
314
 
315
+ private processBaseClassImport(result: ClassAnalysis, importManager: ImportManager): void {
276
316
  const baseClass = result.inheritance.baseClassAnalysis;
277
- if (baseClass) {
278
- importManager.registerCustomImport('./Sendable' + baseClass.className, 'Sendable' + baseClass.className);
317
+ if (!baseClass) {
318
+ return;
279
319
  }
280
- // 2. 检查是否需要collections导入
320
+ importManager.registerCustomImport('./Sendable' + baseClass.className, 'Sendable' + baseClass.className);
321
+ }
322
+
323
+ private processCollectionsImport(result: ClassAnalysis, importManager: ImportManager): void {
281
324
  const needsCollections = this.needsCollectionsImport(result);
282
- if (needsCollections) {
283
- importManager.registerArkTSImports(['collections']);
325
+ if (!needsCollections) {
326
+ return;
284
327
  }
285
- // 3. 拷贝源文件导入
286
- result.originalClass?.getSourceFile().getImportDeclarations().forEach(importDecl => {
287
- const specifier = importDecl.getModuleSpecifierValue();
288
- const names = importDecl.getNamedImports().map((names) => names.getName());
289
- const defaultImport = importDecl.getDefaultImport();
290
- const originalDir = SerializationPathUtil.dirname(result.sourceFilePath);
291
-
292
- const importOriginAbs = SerializationPathUtil.pathResolve(originalDir, specifier);
293
- if (SerializationPathUtil.exist(importOriginAbs + '.ets')) {
294
- // 路径存在,使用模块化路径计算
295
- const importOriginAbsWithExt = importOriginAbs + '.ets';
296
- names.forEach((name) => {
297
- importManager.registerCustomTypeImport(importOriginAbsWithExt, name);
298
- });
299
- if (defaultImport) {
300
- importManager.registerDefaultImport(importOriginAbsWithExt, defaultImport.getText());
301
- }
302
- } else {
303
- // 不存在该路径,说明可能为包名,暂时不动
304
- names.forEach((name) => {
305
- importManager.registerCustomImport(specifier, name);
306
- });
307
- if (defaultImport) {
308
- importManager.registerDefaultImport(specifier, defaultImport.getText());
309
- }
310
- }
328
+ importManager.registerArkTSImports(['collections']);
329
+ }
330
+
331
+ private copySourceFileImports(result: ClassAnalysis, importManager: ImportManager): void {
332
+ const importDeclarations = result.originalClass?.getSourceFile().getImportDeclarations();
333
+ if (!importDeclarations) {
334
+ return;
335
+ }
336
+ importDeclarations.forEach((importDecl) => {
337
+ this.processSingleImportDeclaration(importDecl, result, importManager);
338
+ });
339
+ }
340
+
341
+ private processSingleImportDeclaration(
342
+ importDecl: ImportDeclaration,
343
+ result: ClassAnalysis,
344
+ importManager: ImportManager
345
+ ): void {
346
+ const specifier = importDecl.getModuleSpecifierValue();
347
+ const names = importDecl.getNamedImports().map((n) => n.getName());
348
+ const defaultImport = importDecl.getDefaultImport();
349
+ const originalDir = SerializationPathUtil.dirname(result.sourceFilePath);
350
+ const importOriginAbs = SerializationPathUtil.pathResolve(originalDir, specifier);
351
+
352
+ if (SerializationPathUtil.exist(importOriginAbs + '.ets')) {
353
+ this.registerModuleImports(importOriginAbs + '.ets', names, defaultImport, importManager);
354
+ } else {
355
+ this.registerPackageImports(specifier, names, defaultImport, importManager);
356
+ }
357
+ }
358
+
359
+ private registerModuleImports(
360
+ absPath: string,
361
+ names: string[],
362
+ defaultImport: Identifier | undefined,
363
+ importManager: ImportManager
364
+ ): void {
365
+ names.forEach((name) => {
366
+ importManager.registerCustomTypeImport(absPath, name);
367
+ });
368
+ if (defaultImport) {
369
+ importManager.registerDefaultImport(absPath, defaultImport.getText());
370
+ }
371
+ }
372
+
373
+ private registerPackageImports(
374
+ specifier: string,
375
+ names: string[],
376
+ defaultImport: Identifier | undefined,
377
+ importManager: ImportManager
378
+ ): void {
379
+ names.forEach((name) => {
380
+ importManager.registerCustomImport(specifier, name);
311
381
  });
382
+ if (defaultImport) {
383
+ importManager.registerDefaultImport(specifier, defaultImport.getText());
384
+ }
312
385
  }
313
386
 
314
387
  private convertConstructorParameterTypes(classDecl: ClassDeclaration, result: ClassAnalysis): void {
315
388
  const constructors = classDecl.getConstructors();
316
-
317
389
  constructors.forEach((constructor) => {
318
- const parameters = constructor.getParameters();
390
+ this.convertSingleConstructorParameters(constructor, result);
391
+ });
392
+ }
319
393
 
320
- parameters.forEach((parameter) => {
321
- const paramName = parameter.getName();
394
+ private convertSingleConstructorParameters(
395
+ constructor: ConstructorDeclaration,
396
+ result: ClassAnalysis
397
+ ): void {
398
+ const parameters = constructor.getParameters();
399
+ parameters.forEach((parameter) => {
400
+ this.convertSingleParameter(parameter, result);
401
+ });
402
+ }
322
403
 
323
- // 从分析结果中找到对应的属性信息
324
- const propertyAnalysis = result.properties.find((p) => p.name === paramName);
325
- if (!propertyAnalysis) {
326
- Logger.warn(`未找到构造函数参数 ${paramName} 的分析信息`);
327
- return;
328
- }
404
+ private convertSingleParameter(
405
+ parameter: ParameterDeclaration,
406
+ result: ClassAnalysis
407
+ ): void {
408
+ const paramName = parameter.getName();
409
+ const propertyAnalysis = result.properties.find((p) => p.name === paramName);
410
+ if (!propertyAnalysis) {
411
+ Logger.warn(`未找到构造函数参数 ${paramName} 的分析信息`);
412
+ return;
413
+ }
329
414
 
330
- // 转换参数类型为Sendable兼容类型
331
- const sendableType = this.convertToSendableType(propertyAnalysis.type);
332
- if (sendableType !== propertyAnalysis.type.sourceText) {
333
- parameter.setType(sendableType);
334
- Logger.debug(`构造函数参数 ${paramName} 类型从 ${propertyAnalysis.type.sourceText} 转换为 ${sendableType}`);
335
- }
336
- });
337
- });
415
+ const sendableType = this.convertToSendableType(propertyAnalysis.type);
416
+ if (sendableType !== propertyAnalysis.type.sourceText) {
417
+ parameter.setType(sendableType);
418
+ Logger.debug(`构造函数参数 ${paramName} 类型从 ${propertyAnalysis.type.sourceText} 转换为 ${sendableType}`);
419
+ }
338
420
  }
339
421
 
340
422
  private isObjectType(typeName: string): boolean {
@@ -371,41 +453,50 @@ export class SendableClassGenerator {
371
453
  }
372
454
 
373
455
  private convertInitializerToSendable(initializerText: string): string {
374
- let convertedText = initializerText;
375
-
376
- // 1. 处理数组字面量(最优先)
377
- if (convertedText === '[]') {
378
- convertedText = 'new collections.Array()';
379
- } else if (convertedText.startsWith('[') && convertedText.endsWith(']')) {
380
- // 处理 [1, 2, 3] 这种情况
381
- const arrayContent = convertedText.slice(1, -1);
382
- if (arrayContent.trim()) {
383
- convertedText = `new collections.Array(${arrayContent})`;
384
- } else {
385
- convertedText = 'new collections.Array()';
386
- }
387
- }
456
+ let convertedText = this.convertArrayLiteralToSendable(initializerText);
457
+ convertedText = this.replaceCollectionTypes(convertedText);
458
+ convertedText = this.replaceObjectConstructors(convertedText);
388
459
 
389
- // 2. 处理集合类型构造函数(优先于对象类型)
390
- convertedText = convertedText.replace(/new\s+Set\s*\(/g, 'new collections.Set(');
391
- convertedText = convertedText.replace(/new\s+Map\s*\(/g, 'new collections.Map(');
392
- convertedText = convertedText.replace(/new\s+Array\s*\(/g, 'new collections.Array(');
460
+ Logger.debug(`初始化器转换: ${initializerText} -> ${convertedText}`);
461
+ return convertedText;
462
+ }
393
463
 
394
- // 3. 处理对象构造函数:new Person(...) -> new SendablePerson(...)
464
+ private convertArrayLiteralToSendable(text: string): string {
465
+ if (text === '[]') {
466
+ return 'new collections.Array()';
467
+ }
468
+ if (!text.startsWith('[') || !text.endsWith(']')) {
469
+ return text;
470
+ }
471
+ const arrayContent = text.slice(1, -1);
472
+ if (arrayContent.trim()) {
473
+ return `new collections.Array(${arrayContent})`;
474
+ }
475
+ return 'new collections.Array()';
476
+ }
477
+
478
+ private replaceObjectConstructors(text: string): string {
395
479
  const objectConstructorPattern = /new\s+(\w+)\s*\(/g;
396
- convertedText = convertedText.replace(objectConstructorPattern, (match, className) => {
397
- // 跳过已经转换的集合类型
398
- if (className === 'collections' || match.includes('collections.')) {
399
- return match;
400
- }
401
-
402
- if (this.isObjectType(className)) {
403
- return match.replace(className, `Sendable${className}`);
404
- }
405
- return match;
480
+ return text.replace(objectConstructorPattern, (match, className) => {
481
+ return this.replaceObjectConstructorMatch(match, className);
406
482
  });
483
+ }
407
484
 
408
- Logger.debug(`初始化器转换: ${initializerText} -> ${convertedText}`);
485
+ private replaceObjectConstructorMatch(match: string, className: string): string {
486
+ if (className === 'collections' || match.includes('collections.')) {
487
+ return match;
488
+ }
489
+ if (this.isObjectType(className)) {
490
+ return match.replace(className, `Sendable${className}`);
491
+ }
492
+ return match;
493
+ }
494
+
495
+ private replaceCollectionTypes(text: string): string {
496
+ let convertedText = text;
497
+ convertedText = convertedText.replace(/new\s+Set\s*\(/g, 'new collections.Set(');
498
+ convertedText = convertedText.replace(/new\s+Map\s*\(/g, 'new collections.Map(');
499
+ convertedText = convertedText.replace(/new\s+Array\s*\(/g, 'new collections.Array(');
409
500
  return convertedText;
410
501
  }
411
502
 
@@ -50,12 +50,14 @@ export class SerializerGenerator {
50
50
  this.templateEngine = new HandlebarsTemplateEngine();
51
51
  }
52
52
 
53
- generate(sourceFile: SourceFile, result: ClassAnalysis | InterfaceAnalysis, context: ITaskContext): GenerationContext | string {
53
+ generate(sourceFile: SourceFile, result: ClassAnalysis | InterfaceAnalysis,
54
+ context: ITaskContext): GenerationContext | string {
54
55
  // 检查是否使用自定义序列化器
55
56
  if (result.decorators?.serializable?.with) {
56
- sourceFile.addStatements(this.generateBuiltinSerializerRegistrationForSupplementary(context, result as ClassAnalysis));
57
+ sourceFile.addStatements(
58
+ this.generateBuiltinSerializerRegistrationForSupplementary(context, result as ClassAnalysis));
57
59
  // 使用自定义序列化器,仅生成注册语句
58
- return this.generateCustomSerializerRegistration(sourceFile, result as ClassAnalysis);
60
+ return this.generateCustomSerializerRegistration(result as ClassAnalysis);
59
61
  }
60
62
 
61
63
  // 1. 注册必要的导入
@@ -103,7 +105,8 @@ export class SerializerGenerator {
103
105
  // 基础导入 + 动态内置序列化器导入
104
106
  this.importManager.registerCoreImports([
105
107
  'Serializer', 'SerialDescriptor', 'buildClassSerialDescriptor',
106
- 'Encoder', 'Decoder', 'registerAutoGeneratedSerializerEntry', 'registerAutoGeneratedSerializerEntryProviderForSupplementary',
108
+ 'Encoder', 'Decoder', 'registerAutoGeneratedSerializerEntry', 'ObjectUtils',
109
+ 'registerAutoGeneratedSerializerEntryProviderForSupplementary', 'lazy',
107
110
  ...requiredBuiltinSerializers
108
111
  ]);
109
112
 
@@ -201,17 +204,17 @@ export class SerializerGenerator {
201
204
  }
202
205
 
203
206
  // 注册属性相关的序列化器导入
204
- this.execPropertyImports(property.type.dependencies);
207
+ this.execPropertyImports(property.type.dependencies, !!property.decorators?.with);
205
208
  }
206
209
  }
207
210
 
208
- private execPropertyImports(dependencies: TypeDependency[]): void {
211
+ private execPropertyImports(dependencies: TypeDependency[], hasWithParam: boolean): void {
209
212
  dependencies.forEach((dependency: TypeDependency) => {
210
- this.processDependency(dependency);
213
+ this.processDependency(dependency, hasWithParam);
211
214
  });
212
215
  }
213
216
 
214
- private processDependency(dependency: TypeDependency): void {
217
+ private processDependency(dependency: TypeDependency, hasWithParam: boolean): void {
215
218
  const source = dependency.source;
216
219
 
217
220
  // 提前返回,减少嵌套
@@ -226,16 +229,16 @@ export class SerializerGenerator {
226
229
  // 根据类型种类分别处理
227
230
  switch (dependency.typeKind) {
228
231
  case TypeKind.CLASS:
229
- this.processClassDependency(dependency, source);
232
+ this.processClassDependency(dependency, source, hasWithParam);
230
233
  break;
231
234
 
232
235
  case TypeKind.INTERFACE:
233
- this.processInterfaceDependency(dependency);
236
+ this.processInterfaceDependency(dependency, hasWithParam);
234
237
  break;
235
238
  }
236
239
  }
237
240
 
238
- private processClassDependency(dependency: TypeDependency, source: DependencySource): void {
241
+ private processClassDependency(dependency: TypeDependency, source: DependencySource, hasWithParam: boolean): void {
239
242
  const classDetails = dependency.details as ClassDetails;
240
243
  const tempClassAnalysis = ClassAnalyzer.analyzeClass(classDetails.classDecl);
241
244
 
@@ -249,6 +252,10 @@ export class SerializerGenerator {
249
252
  if (tempClassAnalysis.decorators.serializable) {
250
253
  this.handleSerializableClass(dependency, source, serializerName);
251
254
  } else {
255
+ if (hasWithParam) {
256
+ // 有自定义序列化器,无需关注这个导入了
257
+ return;
258
+ }
252
259
  // 从 tempSerializer 目录(index.ets)导入
253
260
  this.importManager.registerTempSerializerImport(`${dependency.typeName}${serializerName}`);
254
261
  }
@@ -263,7 +270,11 @@ export class SerializerGenerator {
263
270
  }
264
271
  }
265
272
 
266
- private processInterfaceDependency(dependency: TypeDependency): void {
273
+ private processInterfaceDependency(dependency: TypeDependency, hasWithParam: boolean): void {
274
+ if (hasWithParam) {
275
+ // 有自定义序列化器,无需关注这个导入了
276
+ return;
277
+ }
267
278
  const interfaceDetails = dependency.details as InterfaceDetails;
268
279
  const tempClassAnalysis = ClassAnalyzer.analyzeInterface(interfaceDetails.interfaceDecl);
269
280
  TempSerializerGenerator.getInstance().generateSerializer(tempClassAnalysis);
@@ -275,13 +286,11 @@ export class SerializerGenerator {
275
286
  this.importManager.registerTempSerializerImport(`${dependency.typeName}${serializerName}`);
276
287
  }
277
288
 
278
- private generateCustomSerializerRegistration(sourceFile: SourceFile, result: ClassAnalysis): string {
289
+ private generateCustomSerializerRegistration(result: ClassAnalysis): string {
279
290
  this.importManager.registerCoreImports(['registerAutoGeneratedSerializerEntry']);
280
291
 
281
292
  const customSerializer = result.decorators.serializable!.with;
282
- const registrationCode = `registerAutoGeneratedSerializerEntry(${result.className}, ${customSerializer});`;
283
-
284
- return registrationCode;
293
+ return `registerAutoGeneratedSerializerEntry(${result.className}, ${customSerializer});`;
285
294
  }
286
295
 
287
296
  private generateBuiltinSerializerRegistrationForSupplementary(context: ITaskContext, result: ClassAnalysis): string {
@@ -289,10 +298,8 @@ export class SerializerGenerator {
289
298
  const serialNameConstant = this.generateSerialNameConstant(result, context);
290
299
 
291
300
  const customSerializer = result.decorators.serializable!.with;
292
- const registrationCode = `const ${result.className}_SERIAL_NAME = '${serialNameConstant}';\n
301
+ return `const ${result.className}_SERIAL_NAME = '${serialNameConstant}';\n
293
302
  registerAutoGeneratedSerializerEntryProviderForSupplementary(${result.className}_SERIAL_NAME, () => [${result.className}, ${customSerializer}]);`;
294
-
295
- return registrationCode;
296
303
  }
297
304
 
298
305
  private getAllRequiredSerializers(properties: PropertyAnalysis[]): string[] {
@@ -38,7 +38,8 @@ export class TempSerializerGenerator {
38
38
  private context: ITaskContext | null = null;
39
39
  private serializerFiles: Map<string, SerializerFileInfo> = new Map();
40
40
 
41
- private constructor() { }
41
+ private constructor() {
42
+ }
42
43
 
43
44
  static getInstance(): TempSerializerGenerator {
44
45
  return this.INSTANCE;
@@ -102,7 +103,7 @@ export class TempSerializerGenerator {
102
103
  });
103
104
  }
104
105
 
105
- private registerImports(classAnalysis: ClassAnalysis | InterfaceAnalysis, importManager: ImportManager) {
106
+ private registerImports(classAnalysis: ClassAnalysis | InterfaceAnalysis, importManager: ImportManager): void {
106
107
  // 注册源文件导入
107
108
  importManager.registerCustomTypeImport(classAnalysis.sourceFilePath, classAnalysis.className);
108
109
  // 拷贝源文件导入
@@ -174,7 +175,8 @@ export class TempSerializerGenerator {
174
175
  // 检测类名冲突
175
176
  const classNameMap = new Map<string, SerializerFileInfo[]>();
176
177
  for (const [_, fileInfo] of this.serializerFiles) {
177
- const serializerName = `${fileInfo.className}${fileInfo.isGeneric ? StringConstants.SERIALIZER_FACTORY : StringConstants.SERIALIZER}`;
178
+ const serializerName = `${fileInfo.className}${fileInfo.isGeneric ? StringConstants.SERIALIZER_FACTORY :
179
+ StringConstants.SERIALIZER}`;
178
180
  if (!classNameMap.has(serializerName)) {
179
181
  classNameMap.set(serializerName, []);
180
182
  }