@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,23 @@
1
+ import { ClassDeclaration, InterfaceDeclaration } from 'ts-morph';
2
+ import { ClassAnalysis, InterfaceAnalysis } from '../Types';
3
+ export declare class ClassAnalyzer {
4
+ static analyzeClass(classDecl: ClassDeclaration): ClassAnalysis;
5
+ static analyzeInterface(interfaceDecl: InterfaceDeclaration): InterfaceAnalysis;
6
+ private static analyzeInheritanceInfo;
7
+ private static analyzeConstructorParameters;
8
+ private static parseSerializableOptions;
9
+ private static parseSerialNameOptions;
10
+ private static analyzeOwnProperties;
11
+ private static classifyProperties;
12
+ private static collectAllAncestorProperties;
13
+ private static extractConstructorParams;
14
+ private static createPropertyAnalysis;
15
+ private static analyzePropertyType;
16
+ private static simplifyImportType;
17
+ private static getTypeFromInitializer;
18
+ private static isOptional;
19
+ private static analyzeDefaultValue;
20
+ private static hasUndefinedInUnion;
21
+ private static splitUnionType;
22
+ private static analyzePropertyDecorators;
23
+ }
@@ -0,0 +1,480 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClassAnalyzer = void 0;
4
+ const ts_morph_1 = require("ts-morph");
5
+ const Types_1 = require("../Types");
6
+ const constants_1 = require("../constants");
7
+ const GenericTypeSubstitutionUtil_1 = require("../utils/GenericTypeSubstitutionUtil");
8
+ const handlers_1 = require("../handlers");
9
+ const CustomTypeAnalyzer_1 = require("./CustomTypeAnalyzer");
10
+ const CustomError_1 = require("../utils/CustomError");
11
+ const Logger_1 = require("../logger/Logger");
12
+ const TsMorphUtil_1 = require("../utils/TsMorphUtil");
13
+ class ClassAnalyzer {
14
+ static analyzeClass(classDecl) {
15
+ Logger_1.Logger.debug(`Analyzing class ${classDecl.wasForgotten()}`);
16
+ const className = classDecl.getNameOrThrow(`Class name is undefined in ${classDecl.getSourceFile().getFilePath()}`);
17
+ const sourceFilePath = classDecl.getSourceFile().getFilePath();
18
+ Logger_1.Logger.warn(`Analyzing class ${className} ${sourceFilePath}`);
19
+ const generics = {
20
+ isGeneric: classDecl.getTypeParameters().length > 0,
21
+ parameters: classDecl.getTypeParameters().map((p) => p.getName())
22
+ };
23
+ const inheritance = this.analyzeInheritanceInfo(classDecl);
24
+ const constructorParams = this.analyzeConstructorParameters(classDecl, inheritance);
25
+ const decorators = {
26
+ serializable: this.parseSerializableOptions(classDecl.getDecorator(constants_1.DecoratorConstants.SERIALIZABLE)),
27
+ serialName: this.parseSerialNameOptions(classDecl.getDecorator(constants_1.DecoratorConstants.SERIAL_NAME))
28
+ };
29
+ const ownProperties = this.analyzeOwnProperties(classDecl, constructorParams, generics.parameters);
30
+ const propertyClassification = this.classifyProperties(ownProperties, inheritance, generics.parameters);
31
+ return {
32
+ className,
33
+ sourceFilePath,
34
+ originalClass: classDecl,
35
+ generics,
36
+ inheritance,
37
+ decorators,
38
+ ownProperties,
39
+ inheritedProperties: propertyClassification.inheritedProperties,
40
+ overriddenProperties: propertyClassification.overriddenProperties,
41
+ properties: propertyClassification.properties,
42
+ constructorParams
43
+ };
44
+ }
45
+ static analyzeInterface(interfaceDecl) {
46
+ const interfaceName = interfaceDecl.getName();
47
+ if (!interfaceName) {
48
+ throw new CustomError_1.CustomError(`Interface name is undefined in ${interfaceDecl.getSourceFile().getFilePath()}`, CustomError_1.ErrorCodes.CLASS_DECLARATION_NOT_FOUND);
49
+ }
50
+ const sourceFilePath = interfaceDecl.getSourceFile().getFilePath();
51
+ const generics = {
52
+ isGeneric: interfaceDecl.getTypeParameters().length > 0,
53
+ parameters: interfaceDecl.getTypeParameters().map((p) => p.getName())
54
+ };
55
+ const inheritance = this.analyzeInheritanceInfo(interfaceDecl);
56
+ const ownProperties = this.analyzeOwnProperties(interfaceDecl, [], generics.parameters);
57
+ const propertyClassification = this.classifyProperties(ownProperties, inheritance, generics.parameters);
58
+ return {
59
+ className: interfaceName,
60
+ sourceFilePath,
61
+ originalInterface: interfaceDecl,
62
+ generics,
63
+ inheritance,
64
+ ownProperties,
65
+ inheritedProperties: propertyClassification.inheritedProperties,
66
+ overriddenProperties: propertyClassification.overriddenProperties,
67
+ properties: propertyClassification.properties,
68
+ };
69
+ }
70
+ static analyzeInheritanceInfo(cls) {
71
+ const heritageClaus = cls.getHeritageClauses();
72
+ Logger_1.Logger.debug(`分析类的继承信息: ${cls.getName()} ${heritageClaus.length} ${heritageClaus.map(c => c.getText()).join(',')}`);
73
+ for (const clause of heritageClaus) {
74
+ const token = clause.getToken();
75
+ if (token !== ts_morph_1.SyntaxKind.ExtendsKeyword) {
76
+ continue;
77
+ }
78
+ const typeNode = clause.getTypeNodes()[0];
79
+ const className = typeNode.getExpression().getText();
80
+ const args = typeNode.getTypeArguments();
81
+ Logger_1.Logger.debug(`继承信息: text: ${className} getTypeArguments: ${args.map(type => type.getText()).join(', ')}`);
82
+ const classDecl = CustomTypeAnalyzer_1.CustomTypeAnalyzer.getInstance().findClassDeclFromClassName(className, cls.getSourceFile());
83
+ if (!classDecl) {
84
+ throw new CustomError_1.CustomError(`class ${className} decl does not exist ${cls.getName} implement ${className}`, CustomError_1.ErrorCodes.CLASS_DECLARATION_NOT_FOUND);
85
+ }
86
+ if (classDecl instanceof ts_morph_1.InterfaceDeclaration) {
87
+ const baseClassAnalysis = this.analyzeInterface(classDecl);
88
+ return {
89
+ isInherited: true,
90
+ baseClassAnalysis,
91
+ genericTypeArguments: args
92
+ };
93
+ }
94
+ else {
95
+ const baseClassAnalysis = this.analyzeClass(classDecl);
96
+ return {
97
+ isInherited: true,
98
+ baseClassAnalysis,
99
+ genericTypeArguments: args
100
+ };
101
+ }
102
+ }
103
+ return { isInherited: false };
104
+ }
105
+ static analyzeConstructorParameters(classDecl, inheritanceInfo) {
106
+ const constructors = classDecl.getConstructors();
107
+ if (constructors.length > 0) {
108
+ return this.extractConstructorParams(constructors[0]);
109
+ }
110
+ if (inheritanceInfo && inheritanceInfo.isInherited) {
111
+ const baseClassAnalysis = inheritanceInfo.baseClassAnalysis;
112
+ return this.analyzeConstructorParameters(baseClassAnalysis.originalClass, baseClassAnalysis.inheritance);
113
+ }
114
+ return [];
115
+ }
116
+ static parseSerializableOptions(decorator) {
117
+ if (!decorator) {
118
+ return undefined;
119
+ }
120
+ const args = decorator.getArguments();
121
+ let generateSendable;
122
+ let _with;
123
+ let deserializationMode;
124
+ const firstArg = args[0];
125
+ if (!firstArg) {
126
+ return {};
127
+ }
128
+ if (firstArg.getKind() === ts_morph_1.SyntaxKind.ObjectLiteralExpression) {
129
+ const properties = firstArg.asKindOrThrow(ts_morph_1.SyntaxKind.ObjectLiteralExpression).getProperties();
130
+ for (const prop of properties) {
131
+ if (prop.getKind() === ts_morph_1.SyntaxKind.PropertyAssignment) {
132
+ const propAssignment = prop.asKindOrThrow(ts_morph_1.SyntaxKind.PropertyAssignment);
133
+ const propertyName = propAssignment.getName();
134
+ const initializer = propAssignment.getInitializer();
135
+ if (propertyName === 'generateSendable' && initializer) {
136
+ if (initializer.getKind() === ts_morph_1.SyntaxKind.TrueKeyword) {
137
+ generateSendable = true;
138
+ }
139
+ else if (initializer.getKind() === ts_morph_1.SyntaxKind.FalseKeyword) {
140
+ generateSendable = false;
141
+ }
142
+ }
143
+ else if (propertyName === 'with' && initializer) {
144
+ _with = initializer.getText();
145
+ }
146
+ else if (propertyName === 'deserializationMode' && initializer) {
147
+ const modeText = initializer.getText().replace(/['"]/g, '');
148
+ if (modeText === Types_1.DeserializationMode.PERFORMANCE || modeText === Types_1.DeserializationMode.STRICT) {
149
+ deserializationMode = modeText;
150
+ }
151
+ }
152
+ }
153
+ }
154
+ }
155
+ return { with: _with, generateSendable, deserializationMode };
156
+ }
157
+ static parseSerialNameOptions(decorator) {
158
+ if (!decorator) {
159
+ return undefined;
160
+ }
161
+ const args = decorator.getArguments();
162
+ if (args.length === 0) {
163
+ return undefined;
164
+ }
165
+ const firstArg = args[0];
166
+ if (firstArg.getKind() === ts_morph_1.SyntaxKind.ObjectLiteralExpression) {
167
+ const properties = firstArg.asKindOrThrow(ts_morph_1.SyntaxKind.ObjectLiteralExpression).getProperties();
168
+ for (const prop of properties) {
169
+ if (prop.getKind() === ts_morph_1.SyntaxKind.PropertyAssignment) {
170
+ const propAssignment = prop.asKindOrThrow(ts_morph_1.SyntaxKind.PropertyAssignment);
171
+ const name = propAssignment.getName();
172
+ if (name === 'name') {
173
+ const initializer = propAssignment.getInitializer();
174
+ if (initializer && initializer.getKind() === ts_morph_1.SyntaxKind.StringLiteral) {
175
+ const stringLiteral = initializer.asKindOrThrow(ts_morph_1.SyntaxKind.StringLiteral);
176
+ return stringLiteral.getLiteralValue();
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+ return undefined;
183
+ }
184
+ static analyzeOwnProperties(cls, constructorParams, genericParameters) {
185
+ const ownProperties = [];
186
+ const props = cls.getProperties();
187
+ for (const prop of props) {
188
+ const propertyAnalysis = this.createPropertyAnalysis(prop, constructorParams, genericParameters);
189
+ if (propertyAnalysis.type.kind === Types_1.PropertyKind.UNKNOWN) {
190
+ const hasTransient = propertyAnalysis.decorators?.isTransient;
191
+ const hasCustomSerializer = !!propertyAnalysis.decorators?.with;
192
+ if (!hasTransient && !hasCustomSerializer) {
193
+ if (prop instanceof ts_morph_1.PropertyDeclaration) {
194
+ throw new CustomError_1.CustomError(`不支持的类型 '${propertyAnalysis.type.sourceText}' 用于属性 '${propertyAnalysis.name}' (类: ${cls.getName()})。\n` +
195
+ `请选择以下任一解决方案:\n` +
196
+ ` 1. 添加 @Transient() 跳过序列化(属性仍会参与 Sendable 转换和对象拷贝):\n` +
197
+ ` @Transient()\n` +
198
+ ` ${propertyAnalysis.name}: ${propertyAnalysis.type.sourceText};\n\n` +
199
+ ` 2. 添加 @Serializable({with: CustomSerializer}) 指定自定义序列化器:\n` +
200
+ ` @Serializable({with: DateSerializer.INSTANCE})\n` +
201
+ ` ${propertyAnalysis.name}: ${propertyAnalysis.type.sourceText};`, CustomError_1.ErrorCodes.TYPE_NOT_SUPPORT);
202
+ }
203
+ else {
204
+ throw new CustomError_1.CustomError(`不支持的类型 '${propertyAnalysis.type.sourceText}' 用于属性 '${propertyAnalysis.name}' (接口: ${cls.getName()})`, CustomError_1.ErrorCodes.TYPE_NOT_SUPPORT);
205
+ }
206
+ }
207
+ }
208
+ ownProperties.push(propertyAnalysis);
209
+ }
210
+ return ownProperties;
211
+ }
212
+ static classifyProperties(ownProperties, inheritance, currentClassGenericParams = []) {
213
+ if (!inheritance.isInherited || !inheritance.baseClassAnalysis) {
214
+ return {
215
+ inheritedProperties: [],
216
+ overriddenProperties: [],
217
+ properties: [...ownProperties]
218
+ };
219
+ }
220
+ const allAncestorProperties = this.collectAllAncestorProperties(inheritance.baseClassAnalysis, inheritance.genericTypeArguments || [], currentClassGenericParams);
221
+ const ownPropertyNames = new Set(ownProperties.map((prop) => prop.name));
222
+ const inheritedProperties = [];
223
+ for (const ancestorProp of allAncestorProperties) {
224
+ if (!ownPropertyNames.has(ancestorProp.name)) {
225
+ inheritedProperties.push(ancestorProp);
226
+ }
227
+ }
228
+ const overriddenProperties = ownProperties.filter((prop) => allAncestorProperties.some((ancestorProp) => ancestorProp.name === prop.name));
229
+ const properties = [...inheritedProperties, ...ownProperties];
230
+ return {
231
+ inheritedProperties,
232
+ overriddenProperties,
233
+ properties
234
+ };
235
+ }
236
+ static collectAllAncestorProperties(classAnalysis, childGenericArguments = [], currentClassGenericParams = []) {
237
+ const allProperties = [];
238
+ const parentGenericParams = classAnalysis.generics.parameters || [];
239
+ const genericMapping = GenericTypeSubstitutionUtil_1.GenericTypeSubstitutionUtil.buildGenericMapping(parentGenericParams, childGenericArguments);
240
+ const substitutedProperties = classAnalysis.ownProperties.map((property) => GenericTypeSubstitutionUtil_1.GenericTypeSubstitutionUtil.substitutePropertyType(property, genericMapping, currentClassGenericParams));
241
+ allProperties.push(...substitutedProperties);
242
+ if (classAnalysis.inheritance.isInherited && classAnalysis.inheritance.baseClassAnalysis) {
243
+ const ancestorProperties = this.collectAllAncestorProperties(classAnalysis.inheritance.baseClassAnalysis, classAnalysis.inheritance.genericTypeArguments || [], currentClassGenericParams);
244
+ allProperties.push(...ancestorProperties);
245
+ }
246
+ return allProperties;
247
+ }
248
+ static extractConstructorParams(constructor) {
249
+ const parameters = [];
250
+ for (const param of constructor.getParameters()) {
251
+ parameters.push({
252
+ name: param.getName(),
253
+ type: param.getTypeNodeOrThrow().getText(),
254
+ isOptional: param.hasQuestionToken(),
255
+ defaultValue: param.hasInitializer() ? param.getInitializerOrThrow().getText() : undefined
256
+ });
257
+ }
258
+ return parameters;
259
+ }
260
+ static createPropertyAnalysis(prop, constructorParams, genericParameters) {
261
+ const name = prop.getName();
262
+ let typeNode = prop.getTypeNode();
263
+ if (!typeNode) {
264
+ typeNode = this.analyzePropertyType(prop);
265
+ }
266
+ if (!typeNode) {
267
+ throw new CustomError_1.CustomError(`无法分析属性 '${name}' 的类型。请检查属性声明。`, CustomError_1.ErrorCodes.TYPE_NOT_SUPPORT);
268
+ }
269
+ const defaultValue = prop instanceof ts_morph_1.PropertyDeclaration ? this.analyzeDefaultValue(prop, constructorParams) : undefined;
270
+ const decorators = prop instanceof ts_morph_1.PropertyDeclaration ? this.analyzePropertyDecorators(prop) : undefined;
271
+ const type = handlers_1.TypeHandlerRegistry.getInstance().parseType(typeNode, { genericParams: genericParameters, depth: 0 });
272
+ type.isOptional = prop.hasQuestionToken();
273
+ const constructorParam = constructorParams.find((param) => param.name === name);
274
+ const isParamOptional = constructorParam
275
+ ? constructorParam.isOptional ||
276
+ constructorParam.defaultValue !== undefined ||
277
+ this.hasUndefinedInUnion(constructorParam.type)
278
+ : true;
279
+ let isMust;
280
+ if (constructorParam) {
281
+ isMust = !isParamOptional;
282
+ }
283
+ else {
284
+ isMust = decorators?.isRequired || !this.isOptional(prop, defaultValue, type);
285
+ }
286
+ if (decorators?.isTransient && constructorParam && !isParamOptional) {
287
+ throw new CustomError_1.CustomError(`@Transient 属性 '${name}' 的构造函数参数必须是可选的或有默认值。\n` +
288
+ `因为 @Transient 属性不参与序列化,反序列化时无法从外部数据获取值。\n` +
289
+ `请修改构造函数参数为以下任一形式:\n` +
290
+ ` 1. 可选参数: constructor(..., ${name}?: ${constructorParam.type})\n` +
291
+ ` 2. 带默认值: constructor(..., ${name}: ${constructorParam.type} = defaultValue)`, CustomError_1.ErrorCodes.TRANSIENT_ATTR_OPTIONAL);
292
+ }
293
+ return {
294
+ name,
295
+ defaultValue,
296
+ decorators,
297
+ type,
298
+ isMust
299
+ };
300
+ }
301
+ static analyzePropertyType(prop) {
302
+ const name = prop.getName();
303
+ let typeNode = prop.getTypeNode();
304
+ if (typeNode) {
305
+ return typeNode;
306
+ }
307
+ Logger_1.Logger.warn(`无法获取属性${name}的类型,使用typeChecker方式获取类型`);
308
+ let type = TsMorphUtil_1.TsMorphUtil.getTypeChecker().getTypeAtLocation(prop);
309
+ let typeText = type.getText();
310
+ Logger_1.Logger.warn(`typeChecker方式获取类型: ${typeText} `);
311
+ typeText = this.simplifyImportType(typeText);
312
+ if (typeText === 'any') {
313
+ const result = this.getTypeFromInitializer(prop, name);
314
+ if (result) {
315
+ return result;
316
+ }
317
+ }
318
+ if (typeText === 'any') {
319
+ throw new CustomError_1.CustomError(`无法获取属性${name}的类型,需要显示声明`, CustomError_1.ErrorCodes.TYPE_NOT_SUPPORT);
320
+ }
321
+ Logger_1.Logger.info(`使用typeChecker方式获取类型成功: ${typeText}`);
322
+ prop.setType(typeText);
323
+ return prop.getTypeNode();
324
+ }
325
+ static simplifyImportType(typeText) {
326
+ const importPattern = /import\s*\(\s*['"][^'"]*['"]\s*\)\.(.+)/;
327
+ const match = typeText.match(importPattern);
328
+ if (match) {
329
+ return match[1];
330
+ }
331
+ return typeText;
332
+ }
333
+ static getTypeFromInitializer(prop, propName) {
334
+ const initializer = prop.getInitializer();
335
+ if (!initializer) {
336
+ return undefined;
337
+ }
338
+ Logger_1.Logger.warn(`无法获取属性${propName}的类型,使用初始化器获取类型: ${initializer.getText()}`);
339
+ const initializerType = TsMorphUtil_1.TsMorphUtil.getTypeChecker().getTypeAtLocation(initializer);
340
+ let typeText = initializerType.getText();
341
+ Logger_1.Logger.warn(`使用初始化器获取类型: ${typeText}`);
342
+ if (typeText !== 'any') {
343
+ prop.setType(typeText);
344
+ return prop.getTypeNode();
345
+ }
346
+ if (initializer.getKind() !== ts_morph_1.SyntaxKind.NewExpression) {
347
+ return undefined;
348
+ }
349
+ const newExpression = initializer;
350
+ const expression = newExpression.getExpression();
351
+ if (!expression) {
352
+ return undefined;
353
+ }
354
+ const exprText = expression.getText();
355
+ const supportedTypes = ['Map', 'Set', 'WeakMap', 'WeakSet', 'Array', 'Object', 'ArrayList', 'HashMap', 'HashSet', 'LinkedList', 'Decimal', 'List'];
356
+ if (!supportedTypes.includes(exprText)) {
357
+ return undefined;
358
+ }
359
+ const typeArgs = newExpression.getTypeArguments();
360
+ if (typeArgs.length > 0) {
361
+ typeText = `${exprText}<${typeArgs.map(arg => arg.getText()).join(', ')}>`;
362
+ }
363
+ else {
364
+ typeText = exprText;
365
+ }
366
+ prop.setType(typeText);
367
+ return prop.getTypeNode();
368
+ }
369
+ static isOptional(node, defaultValue, type) {
370
+ if (node.hasQuestionToken()) {
371
+ return true;
372
+ }
373
+ if (defaultValue !== undefined) {
374
+ return true;
375
+ }
376
+ if (type.kind === Types_1.PropertyKind.UNDEFINED || type.kind === Types_1.PropertyKind.OPTIONAL) {
377
+ return true;
378
+ }
379
+ if (type.kind === Types_1.PropertyKind.UNION &&
380
+ type.unionDetails &&
381
+ type.unionDetails.some((member) => member.kind === Types_1.PropertyKind.UNDEFINED)) {
382
+ return true;
383
+ }
384
+ return false;
385
+ }
386
+ static analyzeDefaultValue(prop, constructorParams) {
387
+ const param = constructorParams.find((item) => item.name === prop.getName());
388
+ if (param && param.defaultValue) {
389
+ return param.defaultValue;
390
+ }
391
+ if (prop.hasInitializer()) {
392
+ return prop.getInitializerOrThrow().getText();
393
+ }
394
+ return undefined;
395
+ }
396
+ static hasUndefinedInUnion(typeText) {
397
+ const normalized = typeText.replace(/\s/g, '');
398
+ if (normalized === 'undefined') {
399
+ return true;
400
+ }
401
+ const parts = this.splitUnionType(normalized);
402
+ return parts.some(part => part === 'undefined');
403
+ }
404
+ static splitUnionType(typeText) {
405
+ const parts = [];
406
+ let current = '';
407
+ let depth = 0;
408
+ for (let i = 0; i < typeText.length; i++) {
409
+ const char = typeText[i];
410
+ if (char === '<' || char === '[' || char === '(') {
411
+ depth++;
412
+ current += char;
413
+ }
414
+ else if (char === '>' || char === ']' || char === ')') {
415
+ depth--;
416
+ current += char;
417
+ }
418
+ else if (char === '|' && depth === 0) {
419
+ if (current) {
420
+ parts.push(current);
421
+ current = '';
422
+ }
423
+ }
424
+ else {
425
+ current += char;
426
+ }
427
+ }
428
+ if (current) {
429
+ parts.push(current);
430
+ }
431
+ return parts;
432
+ }
433
+ static analyzePropertyDecorators(prop) {
434
+ const decorators = prop.getDecorators();
435
+ let isRequired = false;
436
+ let isTransient = false;
437
+ let serialName;
438
+ let _with;
439
+ decorators.forEach((decorator) => {
440
+ const name = decorator.getName();
441
+ switch (name) {
442
+ case constants_1.DecoratorConstants.SERIAL_NAME:
443
+ serialName = this.parseSerialNameOptions(decorator);
444
+ break;
445
+ case constants_1.DecoratorConstants.REQUIRED:
446
+ isRequired = true;
447
+ break;
448
+ case constants_1.DecoratorConstants.TRANSIENT:
449
+ isTransient = true;
450
+ break;
451
+ case constants_1.DecoratorConstants.SERIALIZABLE:
452
+ _with = this.parseSerializableOptions(decorator).with;
453
+ }
454
+ });
455
+ if (isTransient) {
456
+ const conflictingDecorators = [];
457
+ if (isRequired) {
458
+ conflictingDecorators.push('@Required');
459
+ }
460
+ if (serialName) {
461
+ conflictingDecorators.push('@SerialName');
462
+ }
463
+ if (_with) {
464
+ conflictingDecorators.push('@Serializable');
465
+ }
466
+ if (conflictingDecorators.length > 0) {
467
+ throw new CustomError_1.CustomError(`属性 '${prop.getName()}' 的注解冲突:@Transient 与 ${conflictingDecorators.join(', ')} 不能同时使用。\n` +
468
+ `@Transient 表示跳过序列化,与其他序列化配置注解互斥。\n` +
469
+ `请移除 @Transient 或移除其他序列化注解。`, CustomError_1.ErrorCodes.ANNOTATION_CONFLICT);
470
+ }
471
+ }
472
+ return {
473
+ isRequired,
474
+ isTransient,
475
+ serialName,
476
+ with: _with
477
+ };
478
+ }
479
+ }
480
+ exports.ClassAnalyzer = ClassAnalyzer;
@@ -0,0 +1,21 @@
1
+ import { ClassDeclaration, InterfaceDeclaration, SourceFile } from 'ts-morph';
2
+ import { TypeDependency } from '..';
3
+ export declare class CustomTypeAnalyzer {
4
+ private static readonly INSTANCE;
5
+ private searchCache;
6
+ private constructor();
7
+ static getInstance(): CustomTypeAnalyzer;
8
+ findDefinition(targetName: string, sourceFile: SourceFile): TypeDependency | null;
9
+ findClassDeclFromClassName(className: string, sourceFile: SourceFile): ClassDeclaration | InterfaceDeclaration | null;
10
+ clearCache(): void;
11
+ private findInCurrentFile;
12
+ private findInImports;
13
+ private findInCrossModule;
14
+ private searchInSourceFile;
15
+ private parseEnumDetails;
16
+ private parseClassDetails;
17
+ private parseInterfaceDetails;
18
+ private parseTypeAliasDetails;
19
+ private resolveImportPath;
20
+ private getOrLoadSourceFile;
21
+ }