@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,24 @@
1
+ import { SourceFile } from 'ts-morph';
2
+ import { ClassAnalysis } from '../../..';
3
+ import { ImportManager } from '../shared/ImportManager';
4
+ export declare class SendableClassGenerator {
5
+ canHandle(result: ClassAnalysis): boolean;
6
+ generate(sourceFile: SourceFile, result: ClassAnalysis, importManager: ImportManager): void;
7
+ private getOriginClassDeclaration;
8
+ private renameSendableClass;
9
+ private updateInheritanceToSendable;
10
+ private removeImplements;
11
+ private removeAllDecorators;
12
+ private convertPropertyTypesToSendable;
13
+ private addSendableConstraints;
14
+ private addToOriginMethod;
15
+ private generatedToOriginMethodBody;
16
+ private generatePropertyConversion;
17
+ private getSendableClassName;
18
+ private addNecessaryImports;
19
+ private convertConstructorParameterTypes;
20
+ private isObjectType;
21
+ needsCollectionsImport(result: ClassAnalysis): boolean;
22
+ private convertInitializerToSendable;
23
+ private convertToSendableType;
24
+ }
@@ -0,0 +1,307 @@
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.SendableClassGenerator = void 0;
7
+ const __1 = require("../../..");
8
+ const ClassAnalyzer_1 = require("../../../analyzers/ClassAnalyzer");
9
+ const handlers_1 = require("../../../handlers");
10
+ const ITypeHandler_1 = require("../../../handlers/ITypeHandler");
11
+ const TsMorphUtil_1 = require("../../../utils/TsMorphUtil");
12
+ const SerializationPathUtil_1 = __importDefault(require("../../../utils/SerializationPathUtil"));
13
+ class SendableClassGenerator {
14
+ canHandle(result) {
15
+ return !!result.decorators.serializable?.generateSendable;
16
+ }
17
+ generate(sourceFile, result, importManager) {
18
+ const sendableClass = this.getOriginClassDeclaration(result);
19
+ this.renameSendableClass(sendableClass, result);
20
+ this.updateInheritanceToSendable(sendableClass, result);
21
+ this.removeImplements(sendableClass);
22
+ this.removeAllDecorators(sendableClass);
23
+ this.convertPropertyTypesToSendable(sendableClass, result);
24
+ this.convertConstructorParameterTypes(sendableClass, result);
25
+ this.addSendableConstraints(sendableClass);
26
+ this.addToOriginMethod(sendableClass, result, importManager);
27
+ this.addNecessaryImports(result, importManager);
28
+ sourceFile.addClasses([sendableClass.getStructure()]);
29
+ }
30
+ getOriginClassDeclaration(result) {
31
+ const originalContent = result.originalClass?.getFullText();
32
+ const copiedSourceFile = TsMorphUtil_1.TsMorphUtil.getProject().createSourceFile('copied-file.ts', originalContent, { overwrite: true });
33
+ return copiedSourceFile.getClassOrThrow(result.className);
34
+ }
35
+ renameSendableClass(classDecl, result) {
36
+ const sendableClassName = this.getSendableClassName(result);
37
+ classDecl.set({ name: sendableClassName });
38
+ }
39
+ updateInheritanceToSendable(classDecl, result) {
40
+ if (!result.inheritance.isInherited) {
41
+ return;
42
+ }
43
+ const extendsClause = classDecl.getExtendsOrThrow();
44
+ const sendableBaseClassName = `Sendable${result.inheritance.baseClassAnalysis?.className}`;
45
+ extendsClause.setExpression(sendableBaseClassName);
46
+ }
47
+ removeImplements(classDecl) {
48
+ const implementsClauses = classDecl.getImplements();
49
+ implementsClauses.forEach(imple => {
50
+ classDecl.removeImplements(imple);
51
+ });
52
+ }
53
+ removeAllDecorators(classDecl) {
54
+ classDecl.getDecorators().forEach((decorator) => {
55
+ __1.Logger.warn(`Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`);
56
+ decorator.remove();
57
+ });
58
+ classDecl.getProperties().forEach((property) => {
59
+ property.getDecorators().forEach((decorator) => {
60
+ __1.Logger.warn(`Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`);
61
+ decorator.remove();
62
+ });
63
+ });
64
+ classDecl.getMethods().forEach((method) => {
65
+ method.getDecorators().forEach((decorator) => {
66
+ __1.Logger.warn(`Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`);
67
+ decorator.remove();
68
+ });
69
+ });
70
+ }
71
+ convertPropertyTypesToSendable(classDecl, result) {
72
+ const properties = classDecl.getProperties();
73
+ properties.forEach((property) => {
74
+ const propertyName = property.getName();
75
+ __1.Logger.debug(`Converting property ${propertyName} to sendable`);
76
+ const propertyAnalysis = result.properties.find((p) => p.name === propertyName);
77
+ if (!propertyAnalysis) {
78
+ __1.Logger.warn(`未找到属性 ${propertyName} 的分析信息`);
79
+ return;
80
+ }
81
+ __1.Logger.debug(`Found property ${propertyName} analysis info: ${propertyAnalysis.name} ${propertyAnalysis.type.sourceText}`);
82
+ const sendableType = this.convertToSendableType(propertyAnalysis.type);
83
+ __1.Logger.debug(`Converted type ${propertyAnalysis.type.sourceText} to ${sendableType}`);
84
+ if (sendableType !== propertyAnalysis.type.sourceText) {
85
+ property.setType(sendableType);
86
+ __1.Logger.debug(`属性 ${propertyName} 类型从 ${propertyAnalysis.type.sourceText} 转换为 ${sendableType}`);
87
+ }
88
+ const initializer = property.getInitializer();
89
+ if (initializer) {
90
+ const initializerText = initializer.getText();
91
+ const convertedInitializer = this.convertInitializerToSendable(initializerText);
92
+ if (convertedInitializer !== initializerText) {
93
+ property.setInitializer(convertedInitializer);
94
+ __1.Logger.debug(`属性 ${propertyName} 默认值从 ${initializerText} 转换为 ${convertedInitializer}`);
95
+ }
96
+ }
97
+ });
98
+ }
99
+ addSendableConstraints(classDecl) {
100
+ classDecl.addDecorator({ name: 'Sendable' });
101
+ classDecl.addImplements('lang.ISendable');
102
+ }
103
+ addToOriginMethod(classDecl, result, importManger) {
104
+ let returnType = result.className;
105
+ if (result.generics.isGeneric) {
106
+ returnType += `<${result.generics.parameters.join(', ')}>`;
107
+ }
108
+ const methodBody = this.generatedToOriginMethodBody(result, returnType);
109
+ classDecl.addMethod({
110
+ name: 'toOrigin',
111
+ returnType,
112
+ statements: [methodBody]
113
+ });
114
+ importManger.registerCustomTypeImport(result.sourceFilePath, result.className);
115
+ }
116
+ generatedToOriginMethodBody(result, returnType) {
117
+ const statements = [];
118
+ let constructorCall;
119
+ if (result.constructorParams.length > 0) {
120
+ const constructorProps = [];
121
+ result.properties.forEach((p) => {
122
+ const isConstructorProp = result.constructorParams.find((cp) => cp.name === p.name);
123
+ if (isConstructorProp) {
124
+ constructorProps.push({
125
+ ...p,
126
+ type: {
127
+ ...p.type,
128
+ isOptional: isConstructorProp.isOptional
129
+ }
130
+ });
131
+ }
132
+ });
133
+ const args = constructorProps
134
+ .map((prop) => {
135
+ return this.generatePropertyConversion(prop, 'this.');
136
+ })
137
+ .join(', ');
138
+ constructorCall = `new ${returnType}(${args})`;
139
+ }
140
+ else {
141
+ constructorCall = `new ${returnType}()`;
142
+ }
143
+ statements.push(`const origin = ${constructorCall};`);
144
+ const assignmentProps = result.properties.filter((p) => {
145
+ return result.constructorParams.every((cp) => cp.name !== p.name);
146
+ });
147
+ if (assignmentProps.length > 0) {
148
+ statements.push('');
149
+ statements.push('// 非构造函数属性赋值');
150
+ assignmentProps.forEach((prop) => {
151
+ const assignment = this.generatePropertyConversion(prop, 'this.');
152
+ statements.push(`origin.${prop.name} = ${assignment};`);
153
+ });
154
+ }
155
+ statements.push('');
156
+ statements.push('return origin;');
157
+ return statements.join('\n');
158
+ }
159
+ generatePropertyConversion(prop, prefix) {
160
+ const sourceValue = `${prefix}${prop.name}`;
161
+ if (prop.type.kind === __1.PropertyKind.UNKNOWN) {
162
+ return sourceValue;
163
+ }
164
+ const registry = handlers_1.TypeHandlerRegistry.getInstance();
165
+ const handler = registry.getHandlerForKind(prop.type.kind);
166
+ try {
167
+ return handler.generatePropertyConversion(prop.type, sourceValue, ITypeHandler_1.ConversionDirection.TO_ORIGIN);
168
+ }
169
+ catch (error) {
170
+ __1.Logger.error(`生成属性转换代码失败: ${error}`);
171
+ return sourceValue;
172
+ }
173
+ }
174
+ getSendableClassName(result) {
175
+ return `Sendable${result.className}`;
176
+ }
177
+ addNecessaryImports(result, importManager) {
178
+ result.properties.forEach((property) => {
179
+ property.type.dependencies.forEach((dependency) => {
180
+ if (dependency.typeKind === __1.TypeKind.CLASS) {
181
+ const classAnalysis = ClassAnalyzer_1.ClassAnalyzer.analyzeClass(dependency.details.classDecl);
182
+ if (classAnalysis.decorators.serializable?.generateSendable) {
183
+ importManager.registerCustomImport('./Sendable' + dependency.typeName, 'Sendable' + dependency.typeName);
184
+ }
185
+ else {
186
+ importManager.registerCustomTypeImport(dependency.source.sourceFilePath, dependency.typeName);
187
+ }
188
+ }
189
+ else {
190
+ importManager.registerCustomTypeImport(dependency.source.sourceFilePath, dependency.typeName);
191
+ }
192
+ });
193
+ });
194
+ const baseClass = result.inheritance.baseClassAnalysis;
195
+ if (baseClass) {
196
+ importManager.registerCustomImport('./Sendable' + baseClass.className, 'Sendable' + baseClass.className);
197
+ }
198
+ const needsCollections = this.needsCollectionsImport(result);
199
+ if (needsCollections) {
200
+ importManager.registerArkTSImports(['collections']);
201
+ }
202
+ result.originalClass?.getSourceFile().getImportDeclarations().forEach(importDecl => {
203
+ const specifier = importDecl.getModuleSpecifierValue();
204
+ const names = importDecl.getNamedImports().map((names) => names.getName());
205
+ const defaultImport = importDecl.getDefaultImport();
206
+ const originalDir = SerializationPathUtil_1.default.dirname(result.sourceFilePath);
207
+ const importOriginAbs = SerializationPathUtil_1.default.pathResolve(originalDir, specifier);
208
+ if (SerializationPathUtil_1.default.exist(importOriginAbs + '.ets')) {
209
+ const importOriginAbsWithExt = importOriginAbs + '.ets';
210
+ names.forEach((name) => {
211
+ importManager.registerCustomTypeImport(importOriginAbsWithExt, name);
212
+ });
213
+ if (defaultImport) {
214
+ importManager.registerDefaultImport(importOriginAbsWithExt, defaultImport.getText());
215
+ }
216
+ }
217
+ else {
218
+ names.forEach((name) => {
219
+ importManager.registerCustomImport(specifier, name);
220
+ });
221
+ if (defaultImport) {
222
+ importManager.registerDefaultImport(specifier, defaultImport.getText());
223
+ }
224
+ }
225
+ });
226
+ }
227
+ convertConstructorParameterTypes(classDecl, result) {
228
+ const constructors = classDecl.getConstructors();
229
+ constructors.forEach((constructor) => {
230
+ const parameters = constructor.getParameters();
231
+ parameters.forEach((parameter) => {
232
+ const paramName = parameter.getName();
233
+ const propertyAnalysis = result.properties.find((p) => p.name === paramName);
234
+ if (!propertyAnalysis) {
235
+ __1.Logger.warn(`未找到构造函数参数 ${paramName} 的分析信息`);
236
+ return;
237
+ }
238
+ const sendableType = this.convertToSendableType(propertyAnalysis.type);
239
+ if (sendableType !== propertyAnalysis.type.sourceText) {
240
+ parameter.setType(sendableType);
241
+ __1.Logger.debug(`构造函数参数 ${paramName} 类型从 ${propertyAnalysis.type.sourceText} 转换为 ${sendableType}`);
242
+ }
243
+ });
244
+ });
245
+ }
246
+ isObjectType(typeName) {
247
+ const primitiveTypes = ['string', 'number', 'boolean', 'bigint', 'null', 'undefined'];
248
+ if (primitiveTypes.includes(typeName)) {
249
+ return false;
250
+ }
251
+ if (typeName.startsWith('collections.') ||
252
+ typeName.startsWith('Array<') ||
253
+ typeName.startsWith('Map<') ||
254
+ typeName.startsWith('Set<')) {
255
+ return false;
256
+ }
257
+ if (typeName.startsWith('Sendable')) {
258
+ return false;
259
+ }
260
+ return true;
261
+ }
262
+ needsCollectionsImport(result) {
263
+ return result.properties.some((prop) => {
264
+ const typeText = this.convertToSendableType(prop.type);
265
+ return typeText.includes('collections');
266
+ });
267
+ }
268
+ convertInitializerToSendable(initializerText) {
269
+ let convertedText = initializerText;
270
+ if (convertedText === '[]') {
271
+ convertedText = 'new collections.Array()';
272
+ }
273
+ else if (convertedText.startsWith('[') && convertedText.endsWith(']')) {
274
+ const arrayContent = convertedText.slice(1, -1);
275
+ if (arrayContent.trim()) {
276
+ convertedText = `new collections.Array(${arrayContent})`;
277
+ }
278
+ else {
279
+ convertedText = 'new collections.Array()';
280
+ }
281
+ }
282
+ convertedText = convertedText.replace(/new\s+Set\s*\(/g, 'new collections.Set(');
283
+ convertedText = convertedText.replace(/new\s+Map\s*\(/g, 'new collections.Map(');
284
+ convertedText = convertedText.replace(/new\s+Array\s*\(/g, 'new collections.Array(');
285
+ const objectConstructorPattern = /new\s+(\w+)\s*\(/g;
286
+ convertedText = convertedText.replace(objectConstructorPattern, (match, className) => {
287
+ if (className === 'collections' || match.includes('collections.')) {
288
+ return match;
289
+ }
290
+ if (this.isObjectType(className)) {
291
+ return match.replace(className, `Sendable${className}`);
292
+ }
293
+ return match;
294
+ });
295
+ __1.Logger.debug(`初始化器转换: ${initializerText} -> ${convertedText}`);
296
+ return convertedText;
297
+ }
298
+ convertToSendableType(structure) {
299
+ if (structure.kind === __1.PropertyKind.UNKNOWN) {
300
+ return structure.sourceText;
301
+ }
302
+ const registry = handlers_1.TypeHandlerRegistry.getInstance();
303
+ const handler = registry.getHandlerForKind(structure.kind);
304
+ return handler.generateSendableTypeDeclaration(structure);
305
+ }
306
+ }
307
+ exports.SendableClassGenerator = SendableClassGenerator;
@@ -0,0 +1,28 @@
1
+ import { SourceFile } from 'ts-morph';
2
+ import { ImportManager } from '../shared/ImportManager';
3
+ import { ClassAnalysis, GenerationContext, InterfaceAnalysis, ITaskContext } from '../../..';
4
+ export declare class SerializerGenerator {
5
+ private readonly importManager;
6
+ private readonly templateEngine;
7
+ private readonly registry;
8
+ constructor(importManager: ImportManager);
9
+ generate(sourceFile: SourceFile, result: ClassAnalysis | InterfaceAnalysis, context: ITaskContext): GenerationContext | string;
10
+ generateRegistration(sourceFile: SourceFile, content: GenerationContext | string): void;
11
+ private registerImports;
12
+ private registerDecoratorsImports;
13
+ private registerInheritancePropertyImports;
14
+ private execInheritancePropertyImports;
15
+ private registerPropertyImports;
16
+ private execPropertyImports;
17
+ private processDependency;
18
+ private processClassDependency;
19
+ private handleSerializableClass;
20
+ private processInterfaceDependency;
21
+ private generateCustomSerializerRegistration;
22
+ private generateBuiltinSerializerRegistrationForSupplementary;
23
+ private getAllRequiredSerializers;
24
+ private analyzeNestedSerializers;
25
+ private containsGenericType;
26
+ private propertyAnalysisToPropertyGenerationInfo;
27
+ private generateSerialNameConstant;
28
+ }
@@ -0,0 +1,259 @@
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.SerializerGenerator = void 0;
7
+ const __1 = require("../../..");
8
+ const HandlebarsTemplateEngine_1 = require("../../../template/HandlebarsTemplateEngine");
9
+ const ConfigManager_1 = require("../../../utils/ConfigManager");
10
+ const ClassAnalyzer_1 = require("../../../analyzers/ClassAnalyzer");
11
+ const TempSerializerGenerator_1 = require("./TempSerializerGenerator");
12
+ const handlers_1 = require("../../../handlers");
13
+ const SerializationPathUtil_1 = __importDefault(require("../../../utils/SerializationPathUtil"));
14
+ class SerializerGenerator {
15
+ constructor(importManager) {
16
+ this.registry = handlers_1.TypeHandlerRegistry.getInstance();
17
+ this.importManager = importManager;
18
+ this.templateEngine = new HandlebarsTemplateEngine_1.HandlebarsTemplateEngine();
19
+ }
20
+ generate(sourceFile, result, context) {
21
+ if (result.decorators?.serializable?.with) {
22
+ sourceFile.addStatements(this.generateBuiltinSerializerRegistrationForSupplementary(context, result));
23
+ return this.generateCustomSerializerRegistration(sourceFile, result);
24
+ }
25
+ this.registerImports(result);
26
+ const templateContext = {
27
+ class: result,
28
+ properties: this.propertyAnalysisToPropertyGenerationInfo(result.properties),
29
+ serialNameConstant: this.generateSerialNameConstant(result, context)
30
+ };
31
+ const templateMode = result.decorators?.serializable?.deserializationMode
32
+ ? result.decorators.serializable?.deserializationMode
33
+ : ConfigManager_1.ConfigManager.getInstance().getConfig().deserializationMode;
34
+ const generatedCode = this.templateEngine.render(templateMode, templateContext);
35
+ sourceFile.addStatements(generatedCode);
36
+ return templateContext;
37
+ }
38
+ generateRegistration(sourceFile, content) {
39
+ if (typeof content === 'string') {
40
+ sourceFile.addStatements(content);
41
+ }
42
+ else {
43
+ const generatedCode = this.templateEngine.renderRegister(content);
44
+ sourceFile.addStatements(generatedCode);
45
+ }
46
+ }
47
+ registerImports(result) {
48
+ __1.Logger.debug('SerializerGenerator', 'registerImports', `注册导入: ${result.className}`);
49
+ const requiredBuiltinSerializers = this.getAllRequiredSerializers(result.properties);
50
+ this.importManager.registerCoreImports([
51
+ 'Serializer', 'SerialDescriptor', 'buildClassSerialDescriptor',
52
+ 'Encoder', 'Decoder', 'registerAutoGeneratedSerializerEntry', 'registerAutoGeneratedSerializerEntryProviderForSupplementary',
53
+ ...requiredBuiltinSerializers
54
+ ]);
55
+ this.registerDecoratorsImports(result);
56
+ const deserializationMode = result.decorators?.serializable?.deserializationMode ||
57
+ ConfigManager_1.ConfigManager.getInstance().getConfig().deserializationMode;
58
+ if (deserializationMode === __1.DeserializationMode.STRICT) {
59
+ this.importManager.registerCoreImports([
60
+ 'SerializationError', 'SerializationErrorCodes',
61
+ 'TypeUtils', 'DecodedElementIndex', 'TurboTransLogger'
62
+ ]);
63
+ }
64
+ if (result.generics.isGeneric) {
65
+ this.importManager.registerCoreImports(['BaseSerializerFactory']);
66
+ }
67
+ this.registerPropertyImports(result);
68
+ this.registerInheritancePropertyImports(result);
69
+ }
70
+ registerDecoratorsImports(result) {
71
+ result.ownProperties.forEach(property => {
72
+ if (property.decorators?.serialName) {
73
+ this.importManager.registerCoreImports(['SerialName']);
74
+ }
75
+ if (property.decorators?.isRequired) {
76
+ this.importManager.registerCoreImports(['Required']);
77
+ }
78
+ if (property.decorators?.isTransient) {
79
+ this.importManager.registerCoreImports(['Transient']);
80
+ }
81
+ });
82
+ }
83
+ registerInheritancePropertyImports(result) {
84
+ const baseClass = result.inheritance.baseClassAnalysis;
85
+ if (baseClass && baseClass.sourceFilePath !== result.sourceFilePath) {
86
+ this.importManager.registerCustomTypeImport(baseClass.sourceFilePath, baseClass.className);
87
+ baseClass.ownProperties.forEach(property => {
88
+ this.execInheritancePropertyImports(property.type.dependencies);
89
+ });
90
+ }
91
+ }
92
+ execInheritancePropertyImports(dependencies) {
93
+ dependencies.forEach((dependency) => {
94
+ const source = dependency.source;
95
+ if (source.type === 'local') {
96
+ this.importManager.registerCustomTypeImport(source.sourceFilePath, dependency.typeName);
97
+ const classDetails = dependency.details;
98
+ const tempClassAnalysis = ClassAnalyzer_1.ClassAnalyzer.analyzeClass(classDetails.classDecl);
99
+ if (!tempClassAnalysis.decorators.serializable) {
100
+ TempSerializerGenerator_1.TempSerializerGenerator.getInstance().generateSerializer(tempClassAnalysis);
101
+ }
102
+ const serializerName = classDetails.isGeneric ? __1.StringConstants.SERIALIZER_FACTORY :
103
+ __1.StringConstants.SERIALIZER;
104
+ if (tempClassAnalysis.decorators.serializable) {
105
+ this.importManager.registerCustomTypeImport(source.sourceFilePath, `${dependency.typeName}${serializerName}`);
106
+ }
107
+ }
108
+ });
109
+ }
110
+ registerPropertyImports(result) {
111
+ for (const property of result.properties) {
112
+ if (property.decorators?.isTransient) {
113
+ continue;
114
+ }
115
+ if (property.decorators?.with) {
116
+ if (this.containsGenericType(property.type)) {
117
+ this.importManager.registerCoreImports(['WithEntrySerializer']);
118
+ }
119
+ else {
120
+ this.importManager.registerCoreImports(['WithEntryContextualSerializer']);
121
+ }
122
+ }
123
+ this.execPropertyImports(property.type.dependencies);
124
+ }
125
+ }
126
+ execPropertyImports(dependencies) {
127
+ dependencies.forEach((dependency) => {
128
+ this.processDependency(dependency);
129
+ });
130
+ }
131
+ processDependency(dependency) {
132
+ const source = dependency.source;
133
+ if (source.type !== 'imported' && source.type !== 'local') {
134
+ return;
135
+ }
136
+ if (source.type === 'imported') {
137
+ this.importManager.registerCustomTypeImport(source.sourceFilePath, dependency.typeName);
138
+ }
139
+ switch (dependency.typeKind) {
140
+ case __1.TypeKind.CLASS:
141
+ this.processClassDependency(dependency, source);
142
+ break;
143
+ case __1.TypeKind.INTERFACE:
144
+ this.processInterfaceDependency(dependency);
145
+ break;
146
+ }
147
+ }
148
+ processClassDependency(dependency, source) {
149
+ const classDetails = dependency.details;
150
+ const tempClassAnalysis = ClassAnalyzer_1.ClassAnalyzer.analyzeClass(classDetails.classDecl);
151
+ if (!tempClassAnalysis.decorators.serializable) {
152
+ TempSerializerGenerator_1.TempSerializerGenerator.getInstance().generateSerializer(tempClassAnalysis);
153
+ }
154
+ const serializerName = classDetails.isGeneric ? __1.StringConstants.SERIALIZER_FACTORY :
155
+ __1.StringConstants.SERIALIZER;
156
+ if (tempClassAnalysis.decorators.serializable) {
157
+ this.handleSerializableClass(dependency, source, serializerName);
158
+ }
159
+ else {
160
+ this.importManager.registerTempSerializerImport(`${dependency.typeName}${serializerName}`);
161
+ }
162
+ }
163
+ handleSerializableClass(dependency, source, serializerName) {
164
+ if (source.type === 'imported') {
165
+ this.importManager.registerCustomTypeImport(source.sourceFilePath, `${dependency.typeName}${serializerName}`);
166
+ }
167
+ }
168
+ processInterfaceDependency(dependency) {
169
+ const interfaceDetails = dependency.details;
170
+ const tempClassAnalysis = ClassAnalyzer_1.ClassAnalyzer.analyzeInterface(interfaceDetails.interfaceDecl);
171
+ TempSerializerGenerator_1.TempSerializerGenerator.getInstance().generateSerializer(tempClassAnalysis);
172
+ const serializerName = dependency.details.isGeneric ? __1.StringConstants.SERIALIZER_FACTORY :
173
+ __1.StringConstants.SERIALIZER;
174
+ this.importManager.registerTempSerializerImport(`${dependency.typeName}${serializerName}`);
175
+ }
176
+ generateCustomSerializerRegistration(sourceFile, result) {
177
+ this.importManager.registerCoreImports(['registerAutoGeneratedSerializerEntry']);
178
+ const customSerializer = result.decorators.serializable.with;
179
+ const registrationCode = `registerAutoGeneratedSerializerEntry(${result.className}, ${customSerializer});`;
180
+ return registrationCode;
181
+ }
182
+ generateBuiltinSerializerRegistrationForSupplementary(context, result) {
183
+ this.importManager.registerCoreImports(['registerAutoGeneratedSerializerEntryProviderForSupplementary']);
184
+ const serialNameConstant = this.generateSerialNameConstant(result, context);
185
+ const customSerializer = result.decorators.serializable.with;
186
+ const registrationCode = `const ${result.className}_SERIAL_NAME = '${serialNameConstant}';\n
187
+ registerAutoGeneratedSerializerEntryProviderForSupplementary(${result.className}_SERIAL_NAME, () => [${result.className}, ${customSerializer}]);`;
188
+ return registrationCode;
189
+ }
190
+ getAllRequiredSerializers(properties) {
191
+ const requiredSerializers = new Set();
192
+ properties.forEach(property => {
193
+ const nestedSerializers = this.analyzeNestedSerializers(property.type);
194
+ nestedSerializers.forEach(serializer => requiredSerializers.add(serializer));
195
+ });
196
+ return Array.from(requiredSerializers);
197
+ }
198
+ analyzeNestedSerializers(structure) {
199
+ const requiredSerializers = new Set();
200
+ const analyzeType = (type) => {
201
+ if (type.kind === __1.PropertyKind.UNKNOWN) {
202
+ return;
203
+ }
204
+ if (type.kind === __1.PropertyKind.GENERIC) {
205
+ return;
206
+ }
207
+ const handler = this.registry.getHandlerForKind(type.kind);
208
+ const metadata = handler.getSerializerMetadata(type);
209
+ __1.Logger.debug(`Analyzing type ${type.sourceText}, metadata ${metadata.name}`);
210
+ if (type.kind !== __1.PropertyKind.OBJECT) {
211
+ requiredSerializers.add(metadata.name);
212
+ }
213
+ if (type.args && type.args.length > 0) {
214
+ type.args.forEach(arg => analyzeType(arg));
215
+ }
216
+ if (type.unionDetails && type.unionDetails.length > 0) {
217
+ type.unionDetails.forEach(member => analyzeType(member));
218
+ }
219
+ };
220
+ analyzeType(structure);
221
+ return Array.from(requiredSerializers);
222
+ }
223
+ containsGenericType(structure) {
224
+ if (structure.kind === __1.PropertyKind.GENERIC) {
225
+ return true;
226
+ }
227
+ if (structure.args) {
228
+ return structure.args.some(arg => this.containsGenericType(arg));
229
+ }
230
+ if (structure.unionDetails) {
231
+ return structure.unionDetails.some(member => this.containsGenericType(member));
232
+ }
233
+ return false;
234
+ }
235
+ propertyAnalysisToPropertyGenerationInfo(properties) {
236
+ return properties.filter((prop) => {
237
+ if (prop.decorators?.isTransient) {
238
+ return false;
239
+ }
240
+ if (prop.type.kind === __1.PropertyKind.UNKNOWN) {
241
+ __1.Logger.warn(`属性 ${prop.name} 类型为 UNKNOWN,已自动跳过序列化生成`);
242
+ return false;
243
+ }
244
+ return true;
245
+ }).map((prop) => {
246
+ const handler = this.registry.getHandlerForKind(prop.type.kind);
247
+ const serializer = handler.getSerializerMetadata(prop.type, prop.decorators?.with);
248
+ return { analysis: prop, serializer };
249
+ });
250
+ }
251
+ ;
252
+ generateSerialNameConstant(result, context) {
253
+ const relativePath = context.calculateSourceRootToModuleRoot(result.sourceFilePath);
254
+ const serialName = SerializationPathUtil_1.default.join(context.getPackageName(), relativePath, result.className + '.class')
255
+ .replaceAll(SerializationPathUtil_1.default.sep, '/');
256
+ return result.decorators?.serialName || serialName;
257
+ }
258
+ }
259
+ exports.SerializerGenerator = SerializerGenerator;
@@ -0,0 +1,19 @@
1
+ import { ITaskContext, ClassAnalysis, InterfaceAnalysis } from '../../..';
2
+ export declare class TempSerializerGenerator {
3
+ private static INSTANCE;
4
+ private readonly TEMP_SERIALIZER_DIR_NAME;
5
+ private context;
6
+ private serializerFiles;
7
+ private constructor();
8
+ static getInstance(): TempSerializerGenerator;
9
+ init(context: ITaskContext): void;
10
+ getTempSerializerDir(): string;
11
+ generateSerializer(classAnalysis: ClassAnalysis | InterfaceAnalysis): void;
12
+ private registerImports;
13
+ saveFile(): void;
14
+ private generateIndexFile;
15
+ private generateExportAlias;
16
+ private generateUniqueFileName;
17
+ private extractPathPrefix;
18
+ private getUniqueKey;
19
+ }