@hadss/turbo-trans-json-plugin 1.0.0-rc.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 (195) hide show
  1. package/LICENSE +177 -0
  2. package/README.md +253 -0
  3. package/dist/core/Types.d.ts +196 -0
  4. package/dist/core/Types.js +47 -0
  5. package/dist/core/analyzers/ClassAnalyzer.d.ts +23 -0
  6. package/dist/core/analyzers/ClassAnalyzer.js +480 -0
  7. package/dist/core/analyzers/CustomTypeAnalyzer.d.ts +21 -0
  8. package/dist/core/analyzers/CustomTypeAnalyzer.js +243 -0
  9. package/dist/core/analyzers/SendableMergeChecker.d.ts +9 -0
  10. package/dist/core/analyzers/SendableMergeChecker.js +100 -0
  11. package/dist/core/analyzers/SendableMergeabilityRegistry.d.ts +7 -0
  12. package/dist/core/analyzers/SendableMergeabilityRegistry.js +23 -0
  13. package/dist/core/constants/DecoratorConstants.d.ts +7 -0
  14. package/dist/core/constants/DecoratorConstants.js +13 -0
  15. package/dist/core/constants/PathConstants.d.ts +6 -0
  16. package/dist/core/constants/PathConstants.js +10 -0
  17. package/dist/core/constants/StringConstants.d.ts +83 -0
  18. package/dist/core/constants/StringConstants.js +87 -0
  19. package/dist/core/constants/index.d.ts +3 -0
  20. package/dist/core/constants/index.js +19 -0
  21. package/dist/core/handlers/BaseTypeHandler.d.ts +23 -0
  22. package/dist/core/handlers/BaseTypeHandler.js +57 -0
  23. package/dist/core/handlers/CustomClassHandler.d.ts +21 -0
  24. package/dist/core/handlers/CustomClassHandler.js +191 -0
  25. package/dist/core/handlers/DateHandler.d.ts +2 -0
  26. package/dist/core/handlers/DateHandler.js +60 -0
  27. package/dist/core/handlers/DecimalHandler.d.ts +2 -0
  28. package/dist/core/handlers/DecimalHandler.js +60 -0
  29. package/dist/core/handlers/EnumHandler.d.ts +2 -0
  30. package/dist/core/handlers/EnumHandler.js +89 -0
  31. package/dist/core/handlers/GenericContainerHandler.d.ts +2 -0
  32. package/dist/core/handlers/GenericContainerHandler.js +440 -0
  33. package/dist/core/handlers/GenericHandler.d.ts +18 -0
  34. package/dist/core/handlers/GenericHandler.js +92 -0
  35. package/dist/core/handlers/HandlerBootstrap.d.ts +2 -0
  36. package/dist/core/handlers/HandlerBootstrap.js +28 -0
  37. package/dist/core/handlers/ITypeHandler.d.ts +23 -0
  38. package/dist/core/handlers/ITypeHandler.js +8 -0
  39. package/dist/core/handlers/PrimitiveHandler.d.ts +2 -0
  40. package/dist/core/handlers/PrimitiveHandler.js +127 -0
  41. package/dist/core/handlers/TupleHandler.d.ts +2 -0
  42. package/dist/core/handlers/TupleHandler.js +98 -0
  43. package/dist/core/handlers/TypeHandlerRegistry.d.ts +20 -0
  44. package/dist/core/handlers/TypeHandlerRegistry.js +113 -0
  45. package/dist/core/handlers/UnionTypeHandler.d.ts +2 -0
  46. package/dist/core/handlers/UnionTypeHandler.js +263 -0
  47. package/dist/core/handlers/index.d.ts +2 -0
  48. package/dist/core/handlers/index.js +5 -0
  49. package/dist/core/import-rewrite/services/BuildProfileUpdater.d.ts +8 -0
  50. package/dist/core/import-rewrite/services/BuildProfileUpdater.js +92 -0
  51. package/dist/core/import-rewrite/services/ImportRewriteService.d.ts +9 -0
  52. package/dist/core/import-rewrite/services/ImportRewriteService.js +61 -0
  53. package/dist/core/import-rewrite/services/ImportTransformService.d.ts +15 -0
  54. package/dist/core/import-rewrite/services/ImportTransformService.js +109 -0
  55. package/dist/core/import-rewrite/strategies/ImportScanStrategy.d.ts +17 -0
  56. package/dist/core/import-rewrite/strategies/ImportScanStrategy.js +137 -0
  57. package/dist/core/import-rewrite/types/ImportRewriteTypes.d.ts +17 -0
  58. package/dist/core/import-rewrite/types/ImportRewriteTypes.js +2 -0
  59. package/dist/core/index.d.ts +9 -0
  60. package/dist/core/index.js +27 -0
  61. package/dist/core/interfaces/ITask.d.ts +7 -0
  62. package/dist/core/interfaces/ITask.js +2 -0
  63. package/dist/core/interfaces/ITaskContext.d.ts +11 -0
  64. package/dist/core/interfaces/ITaskContext.js +2 -0
  65. package/dist/core/interfaces/index.d.ts +2 -0
  66. package/dist/core/interfaces/index.js +2 -0
  67. package/dist/core/logger/Logger.d.ts +13 -0
  68. package/dist/core/logger/Logger.js +78 -0
  69. package/dist/core/services/CodeAnalysisService.d.ts +7 -0
  70. package/dist/core/services/CodeAnalysisService.js +43 -0
  71. package/dist/core/services/CodeGenerationEngine.d.ts +12 -0
  72. package/dist/core/services/CodeGenerationEngine.js +102 -0
  73. package/dist/core/services/CodeGenerationService/CodeGenerationService.d.ts +13 -0
  74. package/dist/core/services/CodeGenerationService/CodeGenerationService.js +110 -0
  75. package/dist/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.d.ts +13 -0
  76. package/dist/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.js +119 -0
  77. package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.d.ts +21 -0
  78. package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.js +224 -0
  79. package/dist/core/services/CodeGenerationService/generators/SendableClassGenerator.d.ts +24 -0
  80. package/dist/core/services/CodeGenerationService/generators/SendableClassGenerator.js +307 -0
  81. package/dist/core/services/CodeGenerationService/generators/SerializerGenerator.d.ts +28 -0
  82. package/dist/core/services/CodeGenerationService/generators/SerializerGenerator.js +259 -0
  83. package/dist/core/services/CodeGenerationService/generators/TempSerializerGenerator.d.ts +19 -0
  84. package/dist/core/services/CodeGenerationService/generators/TempSerializerGenerator.js +178 -0
  85. package/dist/core/services/CodeGenerationService/index.d.ts +1 -0
  86. package/dist/core/services/CodeGenerationService/index.js +5 -0
  87. package/dist/core/services/CodeGenerationService/shared/ImportManager.d.ts +27 -0
  88. package/dist/core/services/CodeGenerationService/shared/ImportManager.js +127 -0
  89. package/dist/core/template/HandlebarsTemplateEngine.d.ts +26 -0
  90. package/dist/core/template/HandlebarsTemplateEngine.js +226 -0
  91. package/dist/core/utils/ConfigManager.d.ts +10 -0
  92. package/dist/core/utils/ConfigManager.js +32 -0
  93. package/dist/core/utils/CustomError.d.ts +30 -0
  94. package/dist/core/utils/CustomError.js +37 -0
  95. package/dist/core/utils/DeepCopyUtil.d.ts +15 -0
  96. package/dist/core/utils/DeepCopyUtil.js +138 -0
  97. package/dist/core/utils/GenericTypeSubstitutionUtil.d.ts +9 -0
  98. package/dist/core/utils/GenericTypeSubstitutionUtil.js +68 -0
  99. package/dist/core/utils/SerializationPathUtil.d.ts +18 -0
  100. package/dist/core/utils/SerializationPathUtil.js +107 -0
  101. package/dist/core/utils/TsMorphUtil.d.ts +8 -0
  102. package/dist/core/utils/TsMorphUtil.js +34 -0
  103. package/dist/index.d.ts +4 -0
  104. package/dist/index.js +57 -0
  105. package/dist/json-plugin/JSONExecuteController.d.ts +13 -0
  106. package/dist/json-plugin/JSONExecuteController.js +103 -0
  107. package/dist/json-plugin/constants/TaskConstants.d.ts +7 -0
  108. package/dist/json-plugin/constants/TaskConstants.js +11 -0
  109. package/dist/json-plugin/interfaces/IModuleContext.d.ts +10 -0
  110. package/dist/json-plugin/interfaces/IModuleContext.js +2 -0
  111. package/dist/json-plugin/interfaces/ITargetContext.d.ts +8 -0
  112. package/dist/json-plugin/interfaces/ITargetContext.js +2 -0
  113. package/dist/json-plugin/interfaces/impl/ModuleContext.d.ts +12 -0
  114. package/dist/json-plugin/interfaces/impl/ModuleContext.js +24 -0
  115. package/dist/json-plugin/interfaces/impl/TargetContext.d.ts +23 -0
  116. package/dist/json-plugin/interfaces/impl/TargetContext.js +113 -0
  117. package/dist/json-plugin/tasks/BaseTask.d.ts +14 -0
  118. package/dist/json-plugin/tasks/BaseTask.js +53 -0
  119. package/dist/json-plugin/tasks/CleanTask.d.ts +8 -0
  120. package/dist/json-plugin/tasks/CleanTask.js +25 -0
  121. package/dist/json-plugin/tasks/CodeProcessingTask.d.ts +8 -0
  122. package/dist/json-plugin/tasks/CodeProcessingTask.js +26 -0
  123. package/dist/json-plugin/tasks/SyncTask.d.ts +8 -0
  124. package/dist/json-plugin/tasks/SyncTask.js +21 -0
  125. package/dist/json-plugin/tasks/WatchTask.d.ts +11 -0
  126. package/dist/json-plugin/tasks/WatchTask.js +102 -0
  127. package/package.json +46 -0
  128. package/src/core/Types.ts +356 -0
  129. package/src/core/analyzers/ClassAnalyzer.ts +824 -0
  130. package/src/core/analyzers/CustomTypeAnalyzer.ts +337 -0
  131. package/src/core/analyzers/SendableMergeChecker.ts +195 -0
  132. package/src/core/analyzers/SendableMergeabilityRegistry.ts +72 -0
  133. package/src/core/constants/DecoratorConstants.ts +27 -0
  134. package/src/core/constants/PathConstants.ts +31 -0
  135. package/src/core/constants/StringConstants.ts +152 -0
  136. package/src/core/constants/index.ts +21 -0
  137. package/src/core/handlers/BaseTypeHandler.ts +121 -0
  138. package/src/core/handlers/CustomClassHandler.ts +278 -0
  139. package/src/core/handlers/DateHandler.ts +75 -0
  140. package/src/core/handlers/DecimalHandler.ts +75 -0
  141. package/src/core/handlers/EnumHandler.ts +142 -0
  142. package/src/core/handlers/GenericContainerHandler.ts +621 -0
  143. package/src/core/handlers/GenericHandler.ts +130 -0
  144. package/src/core/handlers/HandlerBootstrap.ts +64 -0
  145. package/src/core/handlers/ITypeHandler.ts +133 -0
  146. package/src/core/handlers/PrimitiveHandler.ts +159 -0
  147. package/src/core/handlers/TupleHandler.ts +145 -0
  148. package/src/core/handlers/TypeHandlerRegistry.ts +236 -0
  149. package/src/core/handlers/UnionTypeHandler.ts +400 -0
  150. package/src/core/handlers/index.ts +18 -0
  151. package/src/core/import-rewrite/services/BuildProfileUpdater.ts +145 -0
  152. package/src/core/import-rewrite/services/ImportRewriteService.ts +129 -0
  153. package/src/core/import-rewrite/services/ImportTransformService.ts +200 -0
  154. package/src/core/import-rewrite/strategies/ImportScanStrategy.ts +303 -0
  155. package/src/core/import-rewrite/types/ImportRewriteTypes.ts +100 -0
  156. package/src/core/index.ts +31 -0
  157. package/src/core/interfaces/ITask.ts +23 -0
  158. package/src/core/interfaces/ITaskContext.ts +94 -0
  159. package/src/core/interfaces/index.ts +17 -0
  160. package/src/core/logger/Logger.ts +149 -0
  161. package/src/core/services/CodeAnalysisService.ts +67 -0
  162. package/src/core/services/CodeGenerationEngine.ts +181 -0
  163. package/src/core/services/CodeGenerationService/CodeGenerationService.ts +159 -0
  164. package/src/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.ts +189 -0
  165. package/src/core/services/CodeGenerationService/generators/OriginalClassGenerator.ts +314 -0
  166. package/src/core/services/CodeGenerationService/generators/SendableClassGenerator.ts +421 -0
  167. package/src/core/services/CodeGenerationService/generators/SerializerGenerator.ts +392 -0
  168. package/src/core/services/CodeGenerationService/generators/TempSerializerGenerator.ts +277 -0
  169. package/src/core/services/CodeGenerationService/index.ts +16 -0
  170. package/src/core/services/CodeGenerationService/shared/ImportManager.ts +191 -0
  171. package/src/core/template/HandlebarsTemplateEngine.ts +282 -0
  172. package/src/core/utils/ConfigManager.ts +49 -0
  173. package/src/core/utils/CustomError.ts +51 -0
  174. package/src/core/utils/DeepCopyUtil.ts +185 -0
  175. package/src/core/utils/GenericTypeSubstitutionUtil.ts +136 -0
  176. package/src/core/utils/SerializationPathUtil.ts +142 -0
  177. package/src/core/utils/TsMorphUtil.ts +50 -0
  178. package/src/index.ts +81 -0
  179. package/src/json-plugin/JSONExecuteController.ts +134 -0
  180. package/src/json-plugin/constants/TaskConstants.ts +22 -0
  181. package/src/json-plugin/interfaces/IModuleContext.ts +27 -0
  182. package/src/json-plugin/interfaces/ITargetContext.ts +25 -0
  183. package/src/json-plugin/interfaces/impl/ModuleContext.ts +45 -0
  184. package/src/json-plugin/interfaces/impl/TargetContext.ts +196 -0
  185. package/src/json-plugin/tasks/BaseTask.ts +94 -0
  186. package/src/json-plugin/tasks/CleanTask.ts +36 -0
  187. package/src/json-plugin/tasks/CodeProcessingTask.ts +41 -0
  188. package/src/json-plugin/tasks/SyncTask.ts +33 -0
  189. package/src/json-plugin/tasks/WatchTask.ts +99 -0
  190. package/template/SerializerPerformanceTemplate.hbs +35 -0
  191. package/template/SerializerRegisterTemplate.hbs +10 -0
  192. package/template/SerializerStrictTemplate.hbs +89 -0
  193. package/template/SerializerTemplate.hbs +176 -0
  194. package/tsconfig.json +17 -0
  195. package/tslint.json +3 -0
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CodeAnalysisService = void 0;
4
+ const __1 = require("..");
5
+ const ClassAnalyzer_1 = require("../analyzers/ClassAnalyzer");
6
+ const TsMorphUtil_1 = require("../utils/TsMorphUtil");
7
+ class CodeAnalysisService {
8
+ constructor() { }
9
+ analyzeFile(filePath) {
10
+ __1.Logger.debug(`开始分析文件: ${filePath}`);
11
+ const sourceFile = TsMorphUtil_1.TsMorphUtil.getProject().addSourceFileAtPath(filePath);
12
+ const classes = sourceFile.getClasses();
13
+ const results = [];
14
+ for (const cls of classes) {
15
+ const classAnalysis = this.analyzeClass(cls);
16
+ if (classAnalysis) {
17
+ results.push(classAnalysis);
18
+ }
19
+ else {
20
+ __1.Logger.debug(`${cls.getName()}无@Serializable装饰器,跳过分析`);
21
+ }
22
+ }
23
+ __1.Logger.debug(`文件分析完成: ${filePath}, 发现 ${results.length} 个@Serializable类`);
24
+ return results;
25
+ }
26
+ analyzeClass(cls) {
27
+ const decorators = cls.getDecorators();
28
+ for (const decorator of decorators) {
29
+ if (decorator.getName() === __1.DecoratorConstants.SERIALIZABLE) {
30
+ return ClassAnalyzer_1.ClassAnalyzer.analyzeClass(cls);
31
+ }
32
+ }
33
+ return null;
34
+ }
35
+ dispose() {
36
+ const sourceFiles = TsMorphUtil_1.TsMorphUtil.getProject().getSourceFiles();
37
+ __1.Logger.info(`code analysis Clearing ${sourceFiles.length} source files...`);
38
+ sourceFiles.forEach((sourceFile) => {
39
+ TsMorphUtil_1.TsMorphUtil.getProject().removeSourceFile(sourceFile);
40
+ });
41
+ }
42
+ }
43
+ exports.CodeAnalysisService = CodeAnalysisService;
@@ -0,0 +1,12 @@
1
+ import { ClassAnalysis, IGeneratedFile, IGenerationResult, ITaskContext, GeneratedFileInfo } from '..';
2
+ export declare class CodeGenerationEngine {
3
+ private readonly analysisService;
4
+ private readonly generationService;
5
+ private allClassAnalysis;
6
+ constructor();
7
+ processFilesUnified(scanFiles: string[], context: ITaskContext): IGenerationResult;
8
+ processFileUnified(filePath: string, context: ITaskContext): IGeneratedFile | null;
9
+ collectGeneratedFileInfos(context: ITaskContext): GeneratedFileInfo[];
10
+ getAllAnalysisResults(): ClassAnalysis[];
11
+ cleanup(): void;
12
+ }
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CodeGenerationEngine = void 0;
4
+ const __1 = require("..");
5
+ const CodeAnalysisService_1 = require("./CodeAnalysisService");
6
+ const CodeGenerationService_1 = require("./CodeGenerationService");
7
+ const SendableMergeabilityRegistry_1 = require("../analyzers/SendableMergeabilityRegistry");
8
+ const SendableMergeChecker_1 = require("../analyzers/SendableMergeChecker");
9
+ const CustomTypeAnalyzer_1 = require("../analyzers/CustomTypeAnalyzer");
10
+ class CodeGenerationEngine {
11
+ constructor() {
12
+ this.allClassAnalysis = [];
13
+ this.analysisService = new CodeAnalysisService_1.CodeAnalysisService();
14
+ this.generationService = new CodeGenerationService_1.CodeGenerationService();
15
+ }
16
+ processFilesUnified(scanFiles, context) {
17
+ if (!scanFiles || scanFiles.length === 0) {
18
+ __1.Logger.info('没有待处理的源文件');
19
+ return {
20
+ generatedFiles: [],
21
+ skippedFiles: []
22
+ };
23
+ }
24
+ const generatedFiles = [];
25
+ const skippedFiles = [];
26
+ this.allClassAnalysis = [];
27
+ SendableMergeabilityRegistry_1.SendableMergeabilityRegistry.clear();
28
+ __1.Logger.info(`开始处理 ${scanFiles.length} 个源文件`);
29
+ __1.Logger.debug(`[阶段1] 开始分析所有文件`);
30
+ const fileAnalysisMap = new Map();
31
+ for (const filePath of scanFiles) {
32
+ const classAnalysis = this.analysisService.analyzeFile(filePath);
33
+ if (classAnalysis.length === 0) {
34
+ skippedFiles.push(filePath);
35
+ __1.Logger.debug(`跳过文件(无@Serializable类): ${filePath}`);
36
+ continue;
37
+ }
38
+ fileAnalysisMap.set(filePath, classAnalysis);
39
+ this.allClassAnalysis.push(...classAnalysis);
40
+ }
41
+ __1.Logger.debug(`[阶段1.1] 完成基本分析,共 ${this.allClassAnalysis.length} 个类`);
42
+ __1.Logger.debug(`[阶段1.2] 开始检查合并性并注册`);
43
+ for (const analysis of this.allClassAnalysis) {
44
+ if (analysis.decorators.serializable?.generateSendable) {
45
+ analysis.canMerge = SendableMergeChecker_1.SendableMergeChecker.check(analysis);
46
+ SendableMergeabilityRegistry_1.SendableMergeabilityRegistry.register(analysis.className, analysis.canMerge);
47
+ }
48
+ else {
49
+ SendableMergeabilityRegistry_1.SendableMergeabilityRegistry.register(analysis.className, false);
50
+ }
51
+ }
52
+ __1.Logger.debug(`[阶段2] 开始生成所有文件`);
53
+ for (const [filePath, classAnalysis] of fileAnalysisMap.entries()) {
54
+ const generatedFile = this.generationService.generateForSourceFile(filePath, classAnalysis, context);
55
+ if (generatedFile) {
56
+ generatedFiles.push(generatedFile);
57
+ __1.Logger.debug(`成功处理文件: ${filePath}`);
58
+ }
59
+ else {
60
+ __1.Logger.warn(`文件生成失败: ${filePath}`);
61
+ }
62
+ }
63
+ __1.Logger.info(`处理完成,成功 ${generatedFiles.length} 个,跳过 ${skippedFiles.length} 个`);
64
+ return { generatedFiles, skippedFiles };
65
+ }
66
+ processFileUnified(filePath, context) {
67
+ const classAnalysis = this.analysisService.analyzeFile(filePath);
68
+ if (classAnalysis.length === 0) {
69
+ __1.Logger.debug(`源文件 ${filePath} 无@Serializable类,跳过生成`);
70
+ return null;
71
+ }
72
+ this.allClassAnalysis.push(...classAnalysis);
73
+ return this.generationService.generateForSourceFile(filePath, classAnalysis, context);
74
+ }
75
+ collectGeneratedFileInfos(context) {
76
+ const fileInfoMap = new Map();
77
+ for (const analysisResult of this.allClassAnalysis) {
78
+ const sourceFilePath = analysisResult.sourceFilePath;
79
+ if (!fileInfoMap.has(sourceFilePath)) {
80
+ const generatedFilePath = context.mapToOutputPath(sourceFilePath);
81
+ fileInfoMap.set(sourceFilePath, {
82
+ sourceFilePath,
83
+ generatedFilePath,
84
+ classNames: new Set()
85
+ });
86
+ }
87
+ const fileInfo = fileInfoMap.get(sourceFilePath);
88
+ fileInfo.classNames.add(analysisResult.className);
89
+ }
90
+ return Array.from(fileInfoMap.values());
91
+ }
92
+ getAllAnalysisResults() {
93
+ return [...this.allClassAnalysis];
94
+ }
95
+ cleanup() {
96
+ this.analysisService.dispose();
97
+ this.allClassAnalysis = [];
98
+ CustomTypeAnalyzer_1.CustomTypeAnalyzer.getInstance().clearCache();
99
+ SendableMergeabilityRegistry_1.SendableMergeabilityRegistry.clear();
100
+ }
101
+ }
102
+ exports.CodeGenerationEngine = CodeGenerationEngine;
@@ -0,0 +1,13 @@
1
+ import { ClassAnalysis, IGeneratedFile, ITaskContext } from '../..';
2
+ export declare class CodeGenerationService {
3
+ private readonly importManger;
4
+ private readonly originalClassGenerator;
5
+ private readonly serializerGenerator;
6
+ private readonly sendableGenerator;
7
+ constructor();
8
+ generateForSourceFile(sourcePath: string, results: ClassAnalysis[], context: ITaskContext): IGeneratedFile | null;
9
+ private generateMainModelFile;
10
+ private generateSendableModelFiles;
11
+ private generateSendableFile;
12
+ private cleanup;
13
+ }
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CodeGenerationService = void 0;
7
+ const OriginalClassGenerator_1 = require("./generators/OriginalClassGenerator");
8
+ const SendableClassGenerator_1 = require("./generators/SendableClassGenerator");
9
+ const SerializerGenerator_1 = require("./generators/SerializerGenerator");
10
+ const ImportManager_1 = require("./shared/ImportManager");
11
+ const __1 = require("../..");
12
+ const SerializationPathUtil_1 = __importDefault(require("../../utils/SerializationPathUtil"));
13
+ const CustomError_1 = require("../../utils/CustomError");
14
+ const TsMorphUtil_1 = require("../../utils/TsMorphUtil");
15
+ class CodeGenerationService {
16
+ constructor() {
17
+ this.importManger = new ImportManager_1.ImportManager();
18
+ this.originalClassGenerator = new OriginalClassGenerator_1.OriginalClassGenerator(this.importManger);
19
+ this.serializerGenerator = new SerializerGenerator_1.SerializerGenerator(this.importManger);
20
+ this.sendableGenerator = new SendableClassGenerator_1.SendableClassGenerator();
21
+ }
22
+ generateForSourceFile(sourcePath, results, context) {
23
+ __1.Logger.debug(`开始为 ${sourcePath} 文件生成代码: ${results.length} 个类`);
24
+ this.importManger.setContext(context);
25
+ this.generateSendableModelFiles(results, context);
26
+ return this.generateMainModelFile(sourcePath, results, context);
27
+ }
28
+ generateMainModelFile(sourceFileAbs, results, context) {
29
+ const originalSourceFile = TsMorphUtil_1.TsMorphUtil.getProject().addSourceFileAtPath(sourceFileAbs);
30
+ const outputPath = context.mapToOutputPath(sourceFileAbs);
31
+ context.ensureOutputDirectory(outputPath);
32
+ if (!context.isValidOutputPath(outputPath)) {
33
+ throw new CustomError_1.CustomError(`输出路径无效: ${outputPath}`, CustomError_1.ErrorCodes.INVALID_OUTPUT_FAIL);
34
+ }
35
+ const outputSourceFile = TsMorphUtil_1.TsMorphUtil.getProject().createSourceFile(outputPath, '', { overwrite: true });
36
+ const serializableGeneratorContext = [];
37
+ for (const classAnalysis of results) {
38
+ serializableGeneratorContext.push(this.serializerGenerator.generate(outputSourceFile, classAnalysis, context));
39
+ }
40
+ this.originalClassGenerator.generate(outputSourceFile, originalSourceFile, results, context);
41
+ for (const content of serializableGeneratorContext) {
42
+ this.serializerGenerator.generateRegistration(outputSourceFile, content);
43
+ }
44
+ this.importManger.getImportDeclarations().forEach((importDeclaration) => {
45
+ outputSourceFile.addImportDeclaration({
46
+ moduleSpecifier: importDeclaration.specifier,
47
+ namedImports: [...new Set(importDeclaration.names)]
48
+ });
49
+ });
50
+ this.importManger.getDefaultImport().forEach((importDeclaration) => {
51
+ outputSourceFile.addImportDeclaration({
52
+ moduleSpecifier: importDeclaration.specifier,
53
+ defaultImport: importDeclaration.name
54
+ });
55
+ });
56
+ outputSourceFile.formatText();
57
+ outputSourceFile.saveSync();
58
+ this.cleanup();
59
+ return {
60
+ sourcePath: sourceFileAbs,
61
+ outputPath,
62
+ contentLength: outputSourceFile.getFullText().length,
63
+ serializerCount: results.length,
64
+ generatedAt: Date.now()
65
+ };
66
+ }
67
+ generateSendableModelFiles(results, context) {
68
+ for (const classAnalysis of results) {
69
+ if (classAnalysis.canMerge) {
70
+ __1.Logger.debug(`类 ${classAnalysis.className} 采用合并策略,跳过独立Sendable文件生成`);
71
+ continue;
72
+ }
73
+ if (this.sendableGenerator.canHandle(classAnalysis)) {
74
+ this.generateSendableFile(classAnalysis, context);
75
+ }
76
+ }
77
+ }
78
+ generateSendableFile(result, context) {
79
+ __1.Logger.debug(`类 ${result.className} 采用独立Sendable文件生成`);
80
+ const sendableOutputPath = SerializationPathUtil_1.default.mapToSendableOutputPath(result.className, context);
81
+ context.ensureOutputDirectory(sendableOutputPath);
82
+ const sendableImportManager = new ImportManager_1.ImportManager();
83
+ sendableImportManager.setContext(context);
84
+ sendableImportManager.registerArkTSImports(['lang']);
85
+ const sendableSourceFile = TsMorphUtil_1.TsMorphUtil.getProject().createSourceFile(sendableOutputPath, '', { overwrite: true });
86
+ this.sendableGenerator.generate(sendableSourceFile, result, sendableImportManager);
87
+ if (this.sendableGenerator.needsCollectionsImport(result)) {
88
+ this.importManger.registerArkTSImports(['collections']);
89
+ }
90
+ this.importManger.registerCustomTypeImport(sendableOutputPath, `Sendable${result.className}`);
91
+ sendableImportManager.getImportDeclarations().forEach((importDeclaration) => {
92
+ sendableSourceFile.addImportDeclaration({
93
+ moduleSpecifier: importDeclaration.specifier,
94
+ namedImports: [...new Set(importDeclaration.names)]
95
+ });
96
+ });
97
+ sendableImportManager.getDefaultImport().forEach((importDeclaration) => {
98
+ sendableSourceFile.addImportDeclaration({
99
+ moduleSpecifier: importDeclaration.specifier,
100
+ defaultImport: importDeclaration.name
101
+ });
102
+ });
103
+ sendableSourceFile.formatText();
104
+ sendableSourceFile.saveSync();
105
+ }
106
+ cleanup() {
107
+ this.importManger.clear();
108
+ }
109
+ }
110
+ exports.CodeGenerationService = CodeGenerationService;
@@ -0,0 +1,13 @@
1
+ import { ClassDeclaration } from 'ts-morph';
2
+ import { ClassAnalysis } from '../../..';
3
+ export declare class MergedSendableClassGenerator {
4
+ private static readonly TURBO_TRANS_DECORATORS;
5
+ generate(classDecl: ClassDeclaration, classAnalysis: ClassAnalysis): void;
6
+ private removeTurboTransDecorators;
7
+ private addSendableDecorator;
8
+ private addITSerializableInterface;
9
+ private generateGetTypeMethod;
10
+ private generateConvertToSendableMethod;
11
+ private generateToOriginMethod;
12
+ private generateToJsonMethod;
13
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MergedSendableClassGenerator = void 0;
4
+ const __1 = require("../../..");
5
+ const constants_1 = require("../../../constants");
6
+ class MergedSendableClassGenerator {
7
+ generate(classDecl, classAnalysis) {
8
+ this.removeTurboTransDecorators(classDecl);
9
+ this.addSendableDecorator(classDecl);
10
+ this.addITSerializableInterface(classDecl);
11
+ this.generateConvertToSendableMethod(classDecl, classAnalysis);
12
+ this.generateToOriginMethod(classDecl, classAnalysis);
13
+ this.generateToJsonMethod(classDecl, classAnalysis);
14
+ __1.Logger.debug(`成功生成合并版Sendable类: ${classAnalysis.className}`);
15
+ }
16
+ removeTurboTransDecorators(classDecl) {
17
+ const classDecorators = classDecl.getDecorators();
18
+ classDecorators.forEach(decorator => {
19
+ const decoratorName = decorator.getName();
20
+ if (MergedSendableClassGenerator.TURBO_TRANS_DECORATORS.has(decoratorName)) {
21
+ decorator.remove();
22
+ __1.Logger.debug(`移除类 ${classDecl.getName()} 的装饰器: @${decoratorName}`);
23
+ }
24
+ });
25
+ const properties = classDecl.getProperties();
26
+ properties.forEach(property => {
27
+ const propDecorators = property.getDecorators();
28
+ propDecorators.forEach(decorator => {
29
+ const decoratorName = decorator.getName();
30
+ if (MergedSendableClassGenerator.TURBO_TRANS_DECORATORS.has(decoratorName)) {
31
+ decorator.remove();
32
+ __1.Logger.debug(`移除属性 ${property.getName()} 的装饰器: @${decoratorName}`);
33
+ }
34
+ });
35
+ });
36
+ }
37
+ addSendableDecorator(classDecl) {
38
+ classDecl.addDecorator({ name: 'Sendable' });
39
+ }
40
+ addITSerializableInterface(classDecl) {
41
+ const existingImplements = classDecl.getImplements().map(impl => impl.getText());
42
+ if (existingImplements.some(impl => impl.includes('ITSerializable'))) {
43
+ __1.Logger.warn(`类 ${classDecl.getName()} 已经实现了ITSerializable接口, 跳过接口添加`);
44
+ return;
45
+ }
46
+ classDecl.addImplements(['ITSerializable', 'lang.ISendable']);
47
+ }
48
+ generateGetTypeMethod(classDecl, classAnalysis) {
49
+ if (classDecl.getMethod('getType')) {
50
+ __1.Logger.warn(`类 ${classAnalysis.className} 已存在getType方法,跳过生成`);
51
+ return;
52
+ }
53
+ const methodBody = `return ${classAnalysis.className};`;
54
+ classDecl.addMethod({
55
+ name: 'getType',
56
+ returnType: 'Function',
57
+ statements: [methodBody]
58
+ });
59
+ }
60
+ generateConvertToSendableMethod(classDecl, classAnalysis) {
61
+ if (classDecl.getMethod('toSendable')) {
62
+ __1.Logger.warn(`类 ${classAnalysis.className} 已存在toSendable方法,跳过生成`);
63
+ return;
64
+ }
65
+ let returnType = classAnalysis.className;
66
+ if (classAnalysis.generics.parameters.length > 0) {
67
+ returnType += `<${classAnalysis.generics.parameters.join(', ')}>`;
68
+ }
69
+ classDecl.addMethod({
70
+ name: 'toSendable',
71
+ returnType: returnType,
72
+ statements: ['return this;']
73
+ });
74
+ __1.Logger.debug(`为合并版Sendable类 ${classAnalysis.className} 生成toSendable方法(返回自身)`);
75
+ }
76
+ generateToOriginMethod(classDecl, classAnalysis) {
77
+ if (classDecl.getMethod('toOrigin')) {
78
+ __1.Logger.warn(`类 ${classAnalysis.className} 已存在toOrigin方法,跳过生成`);
79
+ return;
80
+ }
81
+ let returnType = classAnalysis.className;
82
+ if (classAnalysis.generics.parameters.length > 0) {
83
+ returnType += `<${classAnalysis.generics.parameters.join(', ')}>`;
84
+ }
85
+ classDecl.addMethod({
86
+ name: 'toOrigin',
87
+ returnType: returnType,
88
+ statements: ['return this;']
89
+ });
90
+ __1.Logger.debug(`为合并版Sendable类 ${classAnalysis.className} 生成toOrigin方法(返回自身)`);
91
+ }
92
+ generateToJsonMethod(classDecl, classAnalysis) {
93
+ if (classDecl.getMethod('toJson')) {
94
+ __1.Logger.warn(`类 ${classAnalysis.className} 已存在toJson方法,跳过生成`);
95
+ return;
96
+ }
97
+ const methodBody = 'return TJSON.toString(this, typeKey)';
98
+ const genericParameters = classAnalysis.generics.parameters;
99
+ let fullTypeName;
100
+ if (genericParameters.length > 0) {
101
+ fullTypeName = `${classDecl.getNameOrThrow()}<${genericParameters.join(', ')}>`;
102
+ }
103
+ else {
104
+ fullTypeName = classDecl.getNameOrThrow();
105
+ }
106
+ classDecl.addMethod({
107
+ name: 'toJson',
108
+ returnType: 'string',
109
+ parameters: [{
110
+ name: 'typeKey',
111
+ type: 'TypeKey',
112
+ hasQuestionToken: true
113
+ }],
114
+ statements: [methodBody]
115
+ });
116
+ }
117
+ }
118
+ exports.MergedSendableClassGenerator = MergedSendableClassGenerator;
119
+ MergedSendableClassGenerator.TURBO_TRANS_DECORATORS = new Set(constants_1.DecoratorConstants.SERIAL_DECORATORS);
@@ -0,0 +1,21 @@
1
+ import { SourceFile } from 'ts-morph';
2
+ import { ClassAnalysis, ITaskContext } from '../../..';
3
+ import { ImportManager } from '../shared/ImportManager';
4
+ export declare class OriginalClassGenerator {
5
+ private readonly importManager;
6
+ private readonly mergedSendableGenerator;
7
+ constructor(importManager: ImportManager);
8
+ generate(outputSourceFile: SourceFile, originalSourceFile: SourceFile, results: ClassAnalysis[], context: ITaskContext): void;
9
+ private copySourceFileContentWithoutImports;
10
+ private addITSerializableInterface;
11
+ private generateSerialNameConstant;
12
+ private addStaticSerialName;
13
+ private generateGetTypeMethod;
14
+ private generateConvertToSendableMethod;
15
+ private generateToJsonMethod;
16
+ private registerImports;
17
+ private generateConvertToSendableMethodBody;
18
+ private generateConstructorCall;
19
+ private generatePropertyAssignment;
20
+ private generatePropertyConversion;
21
+ }
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.OriginalClassGenerator = void 0;
7
+ const __1 = require("../../..");
8
+ const SerializationPathUtil_1 = __importDefault(require("../../../utils/SerializationPathUtil"));
9
+ const ITypeHandler_1 = require("../../../handlers/ITypeHandler");
10
+ const handlers_1 = require("../../../handlers");
11
+ const MergedSendableClassGenerator_1 = require("./MergedSendableClassGenerator");
12
+ const CustomError_1 = require("../../../utils/CustomError");
13
+ const TsMorphUtil_1 = require("../../../utils/TsMorphUtil");
14
+ class OriginalClassGenerator {
15
+ constructor(importManager) {
16
+ this.importManager = importManager;
17
+ this.mergedSendableGenerator = new MergedSendableClassGenerator_1.MergedSendableClassGenerator();
18
+ }
19
+ generate(outputSourceFile, originalSourceFile, results, context) {
20
+ this.registerImports();
21
+ const contentWithoutImports = this.copySourceFileContentWithoutImports(originalSourceFile);
22
+ const tempSourceFile = TsMorphUtil_1.TsMorphUtil.getProject().createSourceFile('temp.ts', contentWithoutImports, {
23
+ overwrite: true
24
+ });
25
+ for (const result of results) {
26
+ const className = result.className;
27
+ const targetClass = tempSourceFile.getClassOrThrow(className);
28
+ if (result.canMerge && result.decorators.serializable?.generateSendable) {
29
+ this.importManager.registerArkTSImports(['lang']);
30
+ this.mergedSendableGenerator.generate(targetClass, result);
31
+ }
32
+ else {
33
+ this.addITSerializableInterface(targetClass);
34
+ this.addStaticSerialName(targetClass, result, context);
35
+ this.generateConvertToSendableMethod(targetClass, result);
36
+ this.generateToJsonMethod(targetClass, result);
37
+ }
38
+ }
39
+ outputSourceFile.addStatements(tempSourceFile.getFullText());
40
+ }
41
+ copySourceFileContentWithoutImports(originalSourceFile) {
42
+ const originalFilePath = originalSourceFile.getFilePath();
43
+ const originalDir = SerializationPathUtil_1.default.dirname(originalFilePath);
44
+ const tempSourceFile = TsMorphUtil_1.TsMorphUtil.getProject().createSourceFile('temp-original.ts', originalSourceFile.getFullText(), {
45
+ overwrite: true
46
+ });
47
+ const importDeclarations = tempSourceFile.getImportDeclarations();
48
+ importDeclarations.forEach((importDecl) => {
49
+ const specifier = importDecl.getModuleSpecifierValue();
50
+ const names = importDecl.getNamedImports().map((names) => names.getName());
51
+ const defaultImport = importDecl.getDefaultImport();
52
+ const importOriginAbs = SerializationPathUtil_1.default.pathResolve(originalDir, specifier);
53
+ if (SerializationPathUtil_1.default.exist(importOriginAbs + '.ets')) {
54
+ const importOriginAbsWithExt = importOriginAbs + '.ets';
55
+ names.forEach((name) => {
56
+ this.importManager.registerCustomTypeImport(importOriginAbsWithExt, name);
57
+ });
58
+ if (defaultImport) {
59
+ this.importManager.registerDefaultImport(importOriginAbsWithExt, defaultImport.getText());
60
+ }
61
+ }
62
+ else {
63
+ names.forEach((name) => {
64
+ this.importManager.registerCustomImport(specifier, name);
65
+ });
66
+ if (defaultImport) {
67
+ this.importManager.registerDefaultImport(specifier, defaultImport.getText());
68
+ }
69
+ }
70
+ importDecl.remove();
71
+ });
72
+ const contentWithoutImports = tempSourceFile.getFullText();
73
+ if (!contentWithoutImports || contentWithoutImports.trim().length === 0) {
74
+ throw new CustomError_1.CustomError(`Source file content is empty for ${originalFilePath}`, CustomError_1.ErrorCodes.INVALID_FILE_CONTENT);
75
+ }
76
+ __1.Logger.debug(`成功拷贝 ${originalFilePath} 文件内容并替换import语句`);
77
+ return contentWithoutImports;
78
+ }
79
+ addITSerializableInterface(classDecl) {
80
+ const existingImplements = classDecl.getImplements().map((impl) => impl.getText());
81
+ if (existingImplements.some((impl) => impl.includes('ITSerializable'))) {
82
+ __1.Logger.warn(`类 ${classDecl.getName()} 已经实现了ITSerializable接口, 跳过接口添加`);
83
+ return;
84
+ }
85
+ classDecl.addImplements('ITSerializable');
86
+ __1.Logger.debug(`为类 ${classDecl.getName()} 添加ITSerializable接口实现`);
87
+ }
88
+ generateSerialNameConstant(result, context) {
89
+ const relativePath = context.calculateSourceRootToModuleRoot(result.sourceFilePath);
90
+ const serialName = SerializationPathUtil_1.default.join(context.getPackageName(), relativePath, result.className + '.class')
91
+ .replaceAll(SerializationPathUtil_1.default.sep, '/');
92
+ return result.decorators.serialName || serialName;
93
+ }
94
+ addStaticSerialName(classDecl, result, context) {
95
+ classDecl.addProperty({
96
+ name: 'SERIAL_NAME',
97
+ type: 'string',
98
+ initializer: `${result.className}_SERIAL_NAME`,
99
+ isStatic: true,
100
+ isReadonly: true,
101
+ });
102
+ __1.Logger.debug(`为类 ${classDecl.getName()} 添加静态属性 serialName`);
103
+ }
104
+ generateGetTypeMethod(classDecl, result) {
105
+ if (classDecl.getMethod('getType')) {
106
+ __1.Logger.warn(`类 ${result.className} 已存在getType方法,跳过生成`);
107
+ return;
108
+ }
109
+ const methodBody = `return ${result.className};`;
110
+ classDecl.addMethod({
111
+ name: 'getType',
112
+ returnType: 'Function',
113
+ statements: [methodBody]
114
+ });
115
+ }
116
+ generateConvertToSendableMethod(classDecl, result) {
117
+ if (classDecl.getMethod('toSendable')) {
118
+ __1.Logger.warn(`类 ${result.className} 已存在toSendable方法,跳过生成`);
119
+ return;
120
+ }
121
+ const isSendable = result.decorators.serializable?.generateSendable;
122
+ if (!isSendable) {
123
+ classDecl.addMethod({
124
+ name: 'toSendable',
125
+ returnType: 'undefined',
126
+ statements: ['return undefined']
127
+ });
128
+ return;
129
+ }
130
+ let returnType = `Sendable${result.className}`;
131
+ if (result.generics.parameters.length > 0) {
132
+ returnType += `<${result.generics.parameters.join(', ')}>`;
133
+ }
134
+ const methodBody = this.generateConvertToSendableMethodBody(result, returnType);
135
+ classDecl.addMethod({
136
+ name: 'toSendable',
137
+ returnType: returnType,
138
+ statements: [methodBody]
139
+ });
140
+ }
141
+ generateToJsonMethod(classDecl, result) {
142
+ if (classDecl.getMethod('toJson')) {
143
+ __1.Logger.warn(`类 ${result.className} 已存在toJson方法,跳过生成`);
144
+ return;
145
+ }
146
+ const methodBody = 'return TJSON.toString(this, typeKey)';
147
+ const genericParameters = result.generics.parameters;
148
+ let fullTypeName;
149
+ if (genericParameters.length > 0) {
150
+ fullTypeName = `${classDecl.getNameOrThrow()}<${genericParameters.join(', ')}>`;
151
+ }
152
+ else {
153
+ fullTypeName = classDecl.getNameOrThrow();
154
+ }
155
+ classDecl.addMethod({
156
+ name: 'toJson',
157
+ returnType: 'string',
158
+ parameters: [{
159
+ name: 'typeKey',
160
+ type: 'TypeKey',
161
+ hasQuestionToken: true
162
+ }],
163
+ statements: [methodBody]
164
+ });
165
+ }
166
+ registerImports() {
167
+ this.importManager.registerJsonImports(['ITSerializable', 'TJSON']);
168
+ this.importManager.registerCoreImports(['TypeKey', 'Serializable']);
169
+ }
170
+ generateConvertToSendableMethodBody(classAnalysis, returnType) {
171
+ const constructorProps = [];
172
+ classAnalysis.constructorParams.forEach((cp) => {
173
+ const matchingProperty = classAnalysis.properties.find((p) => p.name === cp.name);
174
+ if (matchingProperty) {
175
+ constructorProps.push({
176
+ ...matchingProperty,
177
+ type: {
178
+ ...matchingProperty.type,
179
+ isOptional: cp.isOptional,
180
+ }
181
+ });
182
+ }
183
+ });
184
+ const assignmentProps = classAnalysis.properties.filter((p) => {
185
+ return classAnalysis.constructorParams.every((cp) => cp.name !== p.name);
186
+ });
187
+ const statements = [];
188
+ const constructorCall = this.generateConstructorCall(constructorProps, returnType);
189
+ statements.push(`const sendable = ${constructorCall};`);
190
+ if (assignmentProps.length > 0) {
191
+ statements.push('');
192
+ statements.push('// 非构造函数属性赋值');
193
+ assignmentProps.forEach((prop) => {
194
+ const assignment = this.generatePropertyAssignment(prop);
195
+ statements.push(`sendable.${prop.name} = ${assignment};`);
196
+ });
197
+ }
198
+ statements.push('');
199
+ statements.push('return sendable;');
200
+ return statements.join('\n');
201
+ }
202
+ generateConstructorCall(constructorProps, returnType) {
203
+ if (constructorProps.length === 0) {
204
+ return `new ${returnType}()`;
205
+ }
206
+ const args = constructorProps.map(prop => {
207
+ return this.generatePropertyConversion(prop, 'this.');
208
+ }).join(', ');
209
+ return `new ${returnType}(${args})`;
210
+ }
211
+ generatePropertyAssignment(prop) {
212
+ return this.generatePropertyConversion(prop, 'this.');
213
+ }
214
+ generatePropertyConversion(prop, prefix) {
215
+ const sourceValue = `${prefix}${prop.name}`;
216
+ if (prop.type.kind === __1.PropertyKind.UNKNOWN) {
217
+ return sourceValue;
218
+ }
219
+ const registry = handlers_1.TypeHandlerRegistry.getInstance();
220
+ const handler = registry.getHandlerForKind(prop.type.kind);
221
+ return handler.generatePropertyConversion(prop.type, sourceValue, ITypeHandler_1.ConversionDirection.TO_SENDABLE);
222
+ }
223
+ }
224
+ exports.OriginalClassGenerator = OriginalClassGenerator;