@hadss/turbo-trans-json-plugin 1.0.0-rc.1 → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/analyzers/ClassAnalyzer.d.ts +15 -0
- package/dist/core/analyzers/ClassAnalyzer.js +193 -144
- package/dist/core/analyzers/CustomTypeAnalyzer.d.ts +3 -0
- package/dist/core/analyzers/CustomTypeAnalyzer.js +65 -60
- package/dist/core/constants/DecoratorConstants.js +2 -1
- package/dist/core/import-rewrite/services/BuildProfileUpdater.js +1 -1
- package/dist/core/import-rewrite/services/ImportRewriteService.js +1 -1
- package/dist/core/interfaces/index.d.ts +2 -2
- package/dist/core/services/CodeAnalysisService.js +2 -1
- package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.d.ts +2 -0
- package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.js +22 -15
- package/dist/core/services/CodeGenerationService/generators/SendableClassGenerator.d.ts +22 -0
- package/dist/core/services/CodeGenerationService/generators/SendableClassGenerator.js +194 -129
- package/dist/core/services/CodeGenerationService/generators/SerializerGenerator.js +1 -1
- package/dist/core/services/CodeGenerationService/generators/TempSerializerGenerator.js +2 -1
- package/dist/core/services/CodeGenerationService/shared/ImportManager.d.ts +2 -2
- package/dist/core/template/HandlebarsTemplateEngine.d.ts +2 -0
- package/dist/core/template/HandlebarsTemplateEngine.js +21 -2
- package/dist/core/utils/DeepCopyUtil.js +1 -1
- package/dist/core/utils/SerializationPathUtil.d.ts +1 -1
- package/dist/core/utils/TsMorphUtil.js +2 -1
- package/dist/json-plugin/JSONExecuteController.d.ts +4 -0
- package/dist/json-plugin/JSONExecuteController.js +46 -36
- package/dist/json-plugin/interfaces/impl/TargetContext.js +4 -2
- package/dist/json-plugin/tasks/BaseTask.d.ts +2 -2
- package/dist/json-plugin/tasks/WatchTask.js +2 -1
- package/package.json +1 -1
- package/src/core/Types.ts +90 -90
- package/src/core/analyzers/ClassAnalyzer.ts +335 -230
- package/src/core/analyzers/CustomTypeAnalyzer.ts +145 -73
- package/src/core/constants/DecoratorConstants.ts +7 -6
- package/src/core/constants/PathConstants.ts +7 -7
- package/src/core/constants/StringConstants.ts +95 -95
- package/src/core/handlers/BaseTypeHandler.ts +11 -2
- package/src/core/handlers/CustomClassHandler.ts +4 -4
- package/src/core/handlers/DateHandler.ts +54 -46
- package/src/core/handlers/DecimalHandler.ts +53 -45
- package/src/core/handlers/EnumHandler.ts +2 -1
- package/src/core/handlers/GenericContainerHandler.ts +3 -1
- package/src/core/handlers/TupleHandler.ts +2 -1
- package/src/core/handlers/TypeHandlerRegistry.ts +2 -1
- package/src/core/handlers/UnionTypeHandler.ts +8 -7
- package/src/core/import-rewrite/services/BuildProfileUpdater.ts +6 -4
- package/src/core/import-rewrite/services/ImportRewriteService.ts +1 -1
- package/src/core/import-rewrite/services/ImportTransformService.ts +2 -2
- package/src/core/import-rewrite/types/ImportRewriteTypes.ts +3 -3
- package/src/core/index.ts +4 -4
- package/src/core/interfaces/ITask.ts +6 -5
- package/src/core/interfaces/ITaskContext.ts +9 -9
- package/src/core/interfaces/index.ts +2 -2
- package/src/core/logger/Logger.ts +28 -28
- package/src/core/services/CodeAnalysisService.ts +2 -1
- package/src/core/services/CodeGenerationEngine.ts +42 -42
- package/src/core/services/CodeGenerationService/generators/OriginalClassGenerator.ts +25 -22
- package/src/core/services/CodeGenerationService/generators/SendableClassGenerator.ts +261 -170
- package/src/core/services/CodeGenerationService/generators/SerializerGenerator.ts +1 -1
- package/src/core/services/CodeGenerationService/generators/TempSerializerGenerator.ts +5 -3
- package/src/core/services/CodeGenerationService/shared/ImportManager.ts +8 -8
- package/src/core/template/HandlebarsTemplateEngine.ts +39 -11
- package/src/core/utils/ConfigManager.ts +2 -1
- package/src/core/utils/DeepCopyUtil.ts +1 -1
- package/src/core/utils/GenericTypeSubstitutionUtil.ts +1 -8
- package/src/core/utils/SerializationPathUtil.ts +7 -6
- package/src/core/utils/TsMorphUtil.ts +4 -1
- package/src/index.ts +2 -2
- package/src/json-plugin/JSONExecuteController.ts +51 -38
- package/src/json-plugin/interfaces/IModuleContext.ts +8 -8
- package/src/json-plugin/interfaces/ITargetContext.ts +6 -6
- package/src/json-plugin/interfaces/impl/ModuleContext.ts +10 -10
- package/src/json-plugin/interfaces/impl/TargetContext.ts +63 -58
- package/src/json-plugin/tasks/BaseTask.ts +5 -3
- package/src/json-plugin/tasks/CleanTask.ts +7 -7
- package/src/json-plugin/tasks/WatchTask.ts +20 -18
- package/template/SerializerPerformanceTemplate.hbs +5 -5
- package/template/SerializerStrictTemplate.hbs +1 -1
- package/template/SerializerTemplate.hbs +59 -42
|
@@ -5,7 +5,8 @@ const __1 = require("..");
|
|
|
5
5
|
const ClassAnalyzer_1 = require("../analyzers/ClassAnalyzer");
|
|
6
6
|
const TsMorphUtil_1 = require("../utils/TsMorphUtil");
|
|
7
7
|
class CodeAnalysisService {
|
|
8
|
-
constructor() {
|
|
8
|
+
constructor() {
|
|
9
|
+
}
|
|
9
10
|
analyzeFile(filePath) {
|
|
10
11
|
__1.Logger.debug(`开始分析文件: ${filePath}`);
|
|
11
12
|
const sourceFile = TsMorphUtil_1.TsMorphUtil.getProject().addSourceFileAtPath(filePath);
|
|
@@ -13,6 +13,8 @@ export declare class OriginalClassGenerator {
|
|
|
13
13
|
private generateToJsonMethod;
|
|
14
14
|
private registerImports;
|
|
15
15
|
private generateConvertToSendableMethodBody;
|
|
16
|
+
private getConstructorProperties;
|
|
17
|
+
private getAssignmentProperties;
|
|
16
18
|
private generateConstructorCall;
|
|
17
19
|
private generatePropertyAssignment;
|
|
18
20
|
private generatePropertyConversion;
|
|
@@ -142,6 +142,24 @@ class OriginalClassGenerator {
|
|
|
142
142
|
this.importManager.registerCoreImports(['TypeKey', 'Serializable', 'Encoder', 'SerialDescriptor']);
|
|
143
143
|
}
|
|
144
144
|
generateConvertToSendableMethodBody(classAnalysis, returnType) {
|
|
145
|
+
const constructorProps = this.getConstructorProperties(classAnalysis);
|
|
146
|
+
const assignmentProps = this.getAssignmentProperties(classAnalysis);
|
|
147
|
+
const statements = [];
|
|
148
|
+
const constructorCall = this.generateConstructorCall(constructorProps, returnType);
|
|
149
|
+
statements.push(`const sendable = ${constructorCall};`);
|
|
150
|
+
if (assignmentProps.length > 0) {
|
|
151
|
+
statements.push('');
|
|
152
|
+
statements.push('// 非构造函数属性赋值');
|
|
153
|
+
assignmentProps.forEach((prop) => {
|
|
154
|
+
const assignment = this.generatePropertyAssignment(prop);
|
|
155
|
+
statements.push(`sendable.${prop.name} = ${assignment};`);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
statements.push('');
|
|
159
|
+
statements.push('return sendable;');
|
|
160
|
+
return statements.join('\n');
|
|
161
|
+
}
|
|
162
|
+
getConstructorProperties(classAnalysis) {
|
|
145
163
|
const constructorProps = [];
|
|
146
164
|
classAnalysis.constructorParams.forEach((cp) => {
|
|
147
165
|
const matchingProperty = classAnalysis.properties.find((p) => p.name === cp.name);
|
|
@@ -155,23 +173,12 @@ class OriginalClassGenerator {
|
|
|
155
173
|
});
|
|
156
174
|
}
|
|
157
175
|
});
|
|
158
|
-
|
|
176
|
+
return constructorProps;
|
|
177
|
+
}
|
|
178
|
+
getAssignmentProperties(classAnalysis) {
|
|
179
|
+
return classAnalysis.properties.filter((p) => {
|
|
159
180
|
return classAnalysis.constructorParams.every((cp) => cp.name !== p.name);
|
|
160
181
|
});
|
|
161
|
-
const statements = [];
|
|
162
|
-
const constructorCall = this.generateConstructorCall(constructorProps, returnType);
|
|
163
|
-
statements.push(`const sendable = ${constructorCall};`);
|
|
164
|
-
if (assignmentProps.length > 0) {
|
|
165
|
-
statements.push('');
|
|
166
|
-
statements.push('// 非构造函数属性赋值');
|
|
167
|
-
assignmentProps.forEach((prop) => {
|
|
168
|
-
const assignment = this.generatePropertyAssignment(prop);
|
|
169
|
-
statements.push(`sendable.${prop.name} = ${assignment};`);
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
statements.push('');
|
|
173
|
-
statements.push('return sendable;');
|
|
174
|
-
return statements.join('\n');
|
|
175
182
|
}
|
|
176
183
|
generateConstructorCall(constructorProps, returnType) {
|
|
177
184
|
if (constructorProps.length === 0) {
|
|
@@ -9,16 +9,38 @@ export declare class SendableClassGenerator {
|
|
|
9
9
|
private updateInheritanceToSendable;
|
|
10
10
|
private removeImplements;
|
|
11
11
|
private removeAllDecorators;
|
|
12
|
+
private removeClassDecorators;
|
|
13
|
+
private removePropertyDecorators;
|
|
14
|
+
private removeMethodDecorators;
|
|
15
|
+
private logAndRemoveDecorator;
|
|
12
16
|
private convertPropertyTypesToSendable;
|
|
17
|
+
private convertSinglePropertyToSendable;
|
|
18
|
+
private updatePropertyType;
|
|
19
|
+
private updatePropertyInitializer;
|
|
13
20
|
private addSendableConstraints;
|
|
14
21
|
private addToOriginMethod;
|
|
15
22
|
private generatedToOriginMethodBody;
|
|
23
|
+
private getConstructorCall;
|
|
16
24
|
private generatePropertyConversion;
|
|
17
25
|
private getSendableClassName;
|
|
18
26
|
private addNecessaryImports;
|
|
27
|
+
private processPropertyDependencyImports;
|
|
28
|
+
private registerDependencyImport;
|
|
29
|
+
private processBaseClassImport;
|
|
30
|
+
private processCollectionsImport;
|
|
31
|
+
private copySourceFileImports;
|
|
32
|
+
private processSingleImportDeclaration;
|
|
33
|
+
private registerModuleImports;
|
|
34
|
+
private registerPackageImports;
|
|
19
35
|
private convertConstructorParameterTypes;
|
|
36
|
+
private convertSingleConstructorParameters;
|
|
37
|
+
private convertSingleParameter;
|
|
20
38
|
private isObjectType;
|
|
21
39
|
needsCollectionsImport(result: ClassAnalysis): boolean;
|
|
22
40
|
private convertInitializerToSendable;
|
|
41
|
+
private convertArrayLiteralToSendable;
|
|
42
|
+
private replaceObjectConstructors;
|
|
43
|
+
private replaceObjectConstructorMatch;
|
|
44
|
+
private replaceCollectionTypes;
|
|
23
45
|
private convertToSendableType;
|
|
24
46
|
}
|
|
@@ -29,7 +29,8 @@ class SendableClassGenerator {
|
|
|
29
29
|
}
|
|
30
30
|
getOriginClassDeclaration(result) {
|
|
31
31
|
const originalContent = result.originalClass?.getFullText();
|
|
32
|
-
const copiedSourceFile = TsMorphUtil_1.TsMorphUtil.getProject()
|
|
32
|
+
const copiedSourceFile = TsMorphUtil_1.TsMorphUtil.getProject()
|
|
33
|
+
.createSourceFile('copied-file.ts', originalContent, { overwrite: true });
|
|
33
34
|
return copiedSourceFile.getClassOrThrow(result.className);
|
|
34
35
|
}
|
|
35
36
|
renameSendableClass(classDecl, result) {
|
|
@@ -51,51 +52,67 @@ class SendableClassGenerator {
|
|
|
51
52
|
});
|
|
52
53
|
}
|
|
53
54
|
removeAllDecorators(classDecl) {
|
|
55
|
+
this.removeClassDecorators(classDecl);
|
|
56
|
+
this.removePropertyDecorators(classDecl);
|
|
57
|
+
this.removeMethodDecorators(classDecl);
|
|
58
|
+
}
|
|
59
|
+
removeClassDecorators(classDecl) {
|
|
54
60
|
classDecl.getDecorators().forEach((decorator) => {
|
|
55
|
-
|
|
56
|
-
decorator.remove();
|
|
61
|
+
this.logAndRemoveDecorator(decorator);
|
|
57
62
|
});
|
|
63
|
+
}
|
|
64
|
+
removePropertyDecorators(classDecl) {
|
|
58
65
|
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
|
-
});
|
|
66
|
+
property.getDecorators().forEach((decorator) => this.logAndRemoveDecorator(decorator));
|
|
63
67
|
});
|
|
68
|
+
}
|
|
69
|
+
removeMethodDecorators(classDecl) {
|
|
64
70
|
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
|
-
});
|
|
71
|
+
method.getDecorators().forEach((decorator) => this.logAndRemoveDecorator(decorator));
|
|
69
72
|
});
|
|
70
73
|
}
|
|
74
|
+
logAndRemoveDecorator(decorator) {
|
|
75
|
+
__1.Logger.warn(`Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`);
|
|
76
|
+
decorator.remove();
|
|
77
|
+
}
|
|
71
78
|
convertPropertyTypesToSendable(classDecl, result) {
|
|
72
79
|
const properties = classDecl.getProperties();
|
|
73
80
|
properties.forEach((property) => {
|
|
74
|
-
|
|
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
|
-
}
|
|
81
|
+
this.convertSinglePropertyToSendable(property, result);
|
|
97
82
|
});
|
|
98
83
|
}
|
|
84
|
+
convertSinglePropertyToSendable(property, result) {
|
|
85
|
+
const propertyName = property.getName();
|
|
86
|
+
__1.Logger.debug(`Converting property ${propertyName} to sendable`);
|
|
87
|
+
const propertyAnalysis = result.properties.find((p) => p.name === propertyName);
|
|
88
|
+
if (!propertyAnalysis) {
|
|
89
|
+
__1.Logger.warn(`未找到属性 ${propertyName} 的分析信息`);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
__1.Logger.debug(`Found property ${propertyName} analysis info: ${propertyAnalysis.name} ${propertyAnalysis.type.sourceText}`);
|
|
93
|
+
this.updatePropertyType(property, propertyAnalysis);
|
|
94
|
+
this.updatePropertyInitializer(property, propertyAnalysis.name);
|
|
95
|
+
}
|
|
96
|
+
updatePropertyType(property, propertyAnalysis) {
|
|
97
|
+
const sendableType = this.convertToSendableType(propertyAnalysis.type);
|
|
98
|
+
__1.Logger.debug(`Converted type ${propertyAnalysis.type.sourceText} to ${sendableType}`);
|
|
99
|
+
if (sendableType !== propertyAnalysis.type.sourceText) {
|
|
100
|
+
property.setType(sendableType);
|
|
101
|
+
__1.Logger.debug(`属性 ${propertyAnalysis.name} 类型从 ${propertyAnalysis.type.sourceText} 转换为 ${sendableType}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
updatePropertyInitializer(property, propertyName) {
|
|
105
|
+
const initializer = property.getInitializer();
|
|
106
|
+
if (!initializer) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const initializerText = initializer.getText();
|
|
110
|
+
const convertedInitializer = this.convertInitializerToSendable(initializerText);
|
|
111
|
+
if (convertedInitializer !== initializerText) {
|
|
112
|
+
property.setInitializer(convertedInitializer);
|
|
113
|
+
__1.Logger.debug(`属性 ${propertyName} 默认值从 ${initializerText} 转换为 ${convertedInitializer}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
99
116
|
addSendableConstraints(classDecl) {
|
|
100
117
|
classDecl.addDecorator({ name: 'Sendable' });
|
|
101
118
|
classDecl.addImplements('lang.ISendable');
|
|
@@ -115,7 +132,24 @@ class SendableClassGenerator {
|
|
|
115
132
|
}
|
|
116
133
|
generatedToOriginMethodBody(result, returnType) {
|
|
117
134
|
const statements = [];
|
|
118
|
-
|
|
135
|
+
const constructorCall = this.getConstructorCall(result, returnType);
|
|
136
|
+
statements.push(`const origin = ${constructorCall};`);
|
|
137
|
+
const assignmentProps = result.properties.filter((p) => {
|
|
138
|
+
return result.constructorParams.every((cp) => cp.name !== p.name);
|
|
139
|
+
});
|
|
140
|
+
if (assignmentProps.length > 0) {
|
|
141
|
+
statements.push('');
|
|
142
|
+
statements.push('// 非构造函数属性赋值');
|
|
143
|
+
assignmentProps.forEach((prop) => {
|
|
144
|
+
const assignment = this.generatePropertyConversion(prop, 'this.');
|
|
145
|
+
statements.push(`origin.${prop.name} = ${assignment};`);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
statements.push('');
|
|
149
|
+
statements.push('return origin;');
|
|
150
|
+
return statements.join('\n');
|
|
151
|
+
}
|
|
152
|
+
getConstructorCall(result, returnType) {
|
|
119
153
|
if (result.constructorParams.length > 0) {
|
|
120
154
|
const constructorProps = [];
|
|
121
155
|
result.properties.forEach((p) => {
|
|
@@ -135,26 +169,11 @@ class SendableClassGenerator {
|
|
|
135
169
|
return this.generatePropertyConversion(prop, 'this.');
|
|
136
170
|
})
|
|
137
171
|
.join(', ');
|
|
138
|
-
|
|
172
|
+
return `new ${returnType}(${args})`;
|
|
139
173
|
}
|
|
140
174
|
else {
|
|
141
|
-
|
|
175
|
+
return `new ${returnType}()`;
|
|
142
176
|
}
|
|
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
177
|
}
|
|
159
178
|
generatePropertyConversion(prop, prefix) {
|
|
160
179
|
const sourceValue = `${prefix}${prop.name}`;
|
|
@@ -175,74 +194,108 @@ class SendableClassGenerator {
|
|
|
175
194
|
return `Sendable${result.className}`;
|
|
176
195
|
}
|
|
177
196
|
addNecessaryImports(result, importManager) {
|
|
197
|
+
this.processPropertyDependencyImports(result, importManager);
|
|
198
|
+
this.processBaseClassImport(result, importManager);
|
|
199
|
+
this.processCollectionsImport(result, importManager);
|
|
200
|
+
this.copySourceFileImports(result, importManager);
|
|
201
|
+
}
|
|
202
|
+
processPropertyDependencyImports(result, importManager) {
|
|
178
203
|
result.properties.forEach((property) => {
|
|
179
204
|
property.type.dependencies.forEach((dependency) => {
|
|
180
|
-
|
|
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
|
-
}
|
|
205
|
+
this.registerDependencyImport(dependency, importManager);
|
|
192
206
|
});
|
|
193
207
|
});
|
|
208
|
+
}
|
|
209
|
+
registerDependencyImport(dependency, importManager) {
|
|
210
|
+
if (dependency.typeKind !== __1.TypeKind.CLASS) {
|
|
211
|
+
importManager.registerCustomTypeImport(dependency.source.sourceFilePath, dependency.typeName);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const classAnalysis = ClassAnalyzer_1.ClassAnalyzer.analyzeClass(dependency.details.classDecl);
|
|
215
|
+
if (classAnalysis.decorators.serializable?.generateSendable) {
|
|
216
|
+
importManager.registerCustomImport('./Sendable' + dependency.typeName, 'Sendable' + dependency.typeName);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
importManager.registerCustomTypeImport(dependency.source.sourceFilePath, dependency.typeName);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
processBaseClassImport(result, importManager) {
|
|
194
223
|
const baseClass = result.inheritance.baseClassAnalysis;
|
|
195
|
-
if (baseClass) {
|
|
196
|
-
|
|
224
|
+
if (!baseClass) {
|
|
225
|
+
return;
|
|
197
226
|
}
|
|
227
|
+
importManager.registerCustomImport('./Sendable' + baseClass.className, 'Sendable' + baseClass.className);
|
|
228
|
+
}
|
|
229
|
+
processCollectionsImport(result, importManager) {
|
|
198
230
|
const needsCollections = this.needsCollectionsImport(result);
|
|
199
|
-
if (needsCollections) {
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
}
|
|
231
|
+
if (!needsCollections) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
importManager.registerArkTSImports(['collections']);
|
|
235
|
+
}
|
|
236
|
+
copySourceFileImports(result, importManager) {
|
|
237
|
+
const importDeclarations = result.originalClass?.getSourceFile().getImportDeclarations();
|
|
238
|
+
if (!importDeclarations) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
importDeclarations.forEach((importDecl) => {
|
|
242
|
+
this.processSingleImportDeclaration(importDecl, result, importManager);
|
|
225
243
|
});
|
|
226
244
|
}
|
|
245
|
+
processSingleImportDeclaration(importDecl, result, importManager) {
|
|
246
|
+
const specifier = importDecl.getModuleSpecifierValue();
|
|
247
|
+
const names = importDecl.getNamedImports().map((n) => n.getName());
|
|
248
|
+
const defaultImport = importDecl.getDefaultImport();
|
|
249
|
+
const originalDir = SerializationPathUtil_1.default.dirname(result.sourceFilePath);
|
|
250
|
+
const importOriginAbs = SerializationPathUtil_1.default.pathResolve(originalDir, specifier);
|
|
251
|
+
if (SerializationPathUtil_1.default.exist(importOriginAbs + '.ets')) {
|
|
252
|
+
this.registerModuleImports(importOriginAbs + '.ets', names, defaultImport, importManager);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this.registerPackageImports(specifier, names, defaultImport, importManager);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
registerModuleImports(absPath, names, defaultImport, importManager) {
|
|
259
|
+
names.forEach((name) => {
|
|
260
|
+
importManager.registerCustomTypeImport(absPath, name);
|
|
261
|
+
});
|
|
262
|
+
if (defaultImport) {
|
|
263
|
+
importManager.registerDefaultImport(absPath, defaultImport.getText());
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
registerPackageImports(specifier, names, defaultImport, importManager) {
|
|
267
|
+
names.forEach((name) => {
|
|
268
|
+
importManager.registerCustomImport(specifier, name);
|
|
269
|
+
});
|
|
270
|
+
if (defaultImport) {
|
|
271
|
+
importManager.registerDefaultImport(specifier, defaultImport.getText());
|
|
272
|
+
}
|
|
273
|
+
}
|
|
227
274
|
convertConstructorParameterTypes(classDecl, result) {
|
|
228
275
|
const constructors = classDecl.getConstructors();
|
|
229
276
|
constructors.forEach((constructor) => {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
-
});
|
|
277
|
+
this.convertSingleConstructorParameters(constructor, result);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
convertSingleConstructorParameters(constructor, result) {
|
|
281
|
+
const parameters = constructor.getParameters();
|
|
282
|
+
parameters.forEach((parameter) => {
|
|
283
|
+
this.convertSingleParameter(parameter, result);
|
|
244
284
|
});
|
|
245
285
|
}
|
|
286
|
+
convertSingleParameter(parameter, result) {
|
|
287
|
+
const paramName = parameter.getName();
|
|
288
|
+
const propertyAnalysis = result.properties.find((p) => p.name === paramName);
|
|
289
|
+
if (!propertyAnalysis) {
|
|
290
|
+
__1.Logger.warn(`未找到构造函数参数 ${paramName} 的分析信息`);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const sendableType = this.convertToSendableType(propertyAnalysis.type);
|
|
294
|
+
if (sendableType !== propertyAnalysis.type.sourceText) {
|
|
295
|
+
parameter.setType(sendableType);
|
|
296
|
+
__1.Logger.debug(`构造函数参数 ${paramName} 类型从 ${propertyAnalysis.type.sourceText} 转换为 ${sendableType}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
246
299
|
isObjectType(typeName) {
|
|
247
300
|
const primitiveTypes = ['string', 'number', 'boolean', 'bigint', 'null', 'undefined'];
|
|
248
301
|
if (primitiveTypes.includes(typeName)) {
|
|
@@ -266,33 +319,45 @@ class SendableClassGenerator {
|
|
|
266
319
|
});
|
|
267
320
|
}
|
|
268
321
|
convertInitializerToSendable(initializerText) {
|
|
269
|
-
let convertedText = initializerText;
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
322
|
+
let convertedText = this.convertArrayLiteralToSendable(initializerText);
|
|
323
|
+
convertedText = this.replaceCollectionTypes(convertedText);
|
|
324
|
+
convertedText = this.replaceObjectConstructors(convertedText);
|
|
325
|
+
__1.Logger.debug(`初始化器转换: ${initializerText} -> ${convertedText}`);
|
|
326
|
+
return convertedText;
|
|
327
|
+
}
|
|
328
|
+
convertArrayLiteralToSendable(text) {
|
|
329
|
+
if (text === '[]') {
|
|
330
|
+
return 'new collections.Array()';
|
|
331
|
+
}
|
|
332
|
+
if (!text.startsWith('[') || !text.endsWith(']')) {
|
|
333
|
+
return text;
|
|
334
|
+
}
|
|
335
|
+
const arrayContent = text.slice(1, -1);
|
|
336
|
+
if (arrayContent.trim()) {
|
|
337
|
+
return `new collections.Array(${arrayContent})`;
|
|
281
338
|
}
|
|
339
|
+
return 'new collections.Array()';
|
|
340
|
+
}
|
|
341
|
+
replaceObjectConstructors(text) {
|
|
342
|
+
const objectConstructorPattern = /new\s+(\w+)\s*\(/g;
|
|
343
|
+
return text.replace(objectConstructorPattern, (match, className) => {
|
|
344
|
+
return this.replaceObjectConstructorMatch(match, className);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
replaceObjectConstructorMatch(match, className) {
|
|
348
|
+
if (className === 'collections' || match.includes('collections.')) {
|
|
349
|
+
return match;
|
|
350
|
+
}
|
|
351
|
+
if (this.isObjectType(className)) {
|
|
352
|
+
return match.replace(className, `Sendable${className}`);
|
|
353
|
+
}
|
|
354
|
+
return match;
|
|
355
|
+
}
|
|
356
|
+
replaceCollectionTypes(text) {
|
|
357
|
+
let convertedText = text;
|
|
282
358
|
convertedText = convertedText.replace(/new\s+Set\s*\(/g, 'new collections.Set(');
|
|
283
359
|
convertedText = convertedText.replace(/new\s+Map\s*\(/g, 'new collections.Map(');
|
|
284
360
|
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
361
|
return convertedText;
|
|
297
362
|
}
|
|
298
363
|
convertToSendableType(structure) {
|
|
@@ -50,7 +50,7 @@ class SerializerGenerator {
|
|
|
50
50
|
this.importManager.registerCoreImports([
|
|
51
51
|
'Serializer', 'SerialDescriptor', 'buildClassSerialDescriptor',
|
|
52
52
|
'Encoder', 'Decoder', 'registerAutoGeneratedSerializerEntry', 'ObjectUtils',
|
|
53
|
-
'registerAutoGeneratedSerializerEntryProviderForSupplementary',
|
|
53
|
+
'registerAutoGeneratedSerializerEntryProviderForSupplementary', 'lazy',
|
|
54
54
|
...requiredBuiltinSerializers
|
|
55
55
|
]);
|
|
56
56
|
this.registerDecoratorsImports(result);
|
|
@@ -111,7 +111,8 @@ class TempSerializerGenerator {
|
|
|
111
111
|
const indexSourceFile = TsMorphUtil_1.TsMorphUtil.getProject().createSourceFile(indexFilePath, '', { overwrite: true });
|
|
112
112
|
const classNameMap = new Map();
|
|
113
113
|
for (const [_, fileInfo] of this.serializerFiles) {
|
|
114
|
-
const serializerName = `${fileInfo.className}${fileInfo.isGeneric ? __1.StringConstants.SERIALIZER_FACTORY :
|
|
114
|
+
const serializerName = `${fileInfo.className}${fileInfo.isGeneric ? __1.StringConstants.SERIALIZER_FACTORY :
|
|
115
|
+
__1.StringConstants.SERIALIZER}`;
|
|
115
116
|
if (!classNameMap.has(serializerName)) {
|
|
116
117
|
classNameMap.set(serializerName, []);
|
|
117
118
|
}
|
|
@@ -12,10 +12,10 @@ export declare class ImportManager {
|
|
|
12
12
|
private isModularPath;
|
|
13
13
|
private isRelativePath;
|
|
14
14
|
private removeImportFromModule;
|
|
15
|
-
getImportDeclarations(): {
|
|
15
|
+
getImportDeclarations(): Array<{
|
|
16
16
|
specifier: string;
|
|
17
17
|
names: string[];
|
|
18
|
-
}
|
|
18
|
+
}>;
|
|
19
19
|
getDefaultImport(): Array<{
|
|
20
20
|
specifier: string;
|
|
21
21
|
name: string;
|
|
@@ -14,6 +14,8 @@ export declare class HandlebarsTemplateEngine {
|
|
|
14
14
|
registerHelper(name: string, helper: Handlebars.HelperDelegate): void;
|
|
15
15
|
loadTemplateFromString(template: string): HandlebarsTemplateDelegate;
|
|
16
16
|
private registerBuiltinHelpers;
|
|
17
|
+
private isPrimitiveType;
|
|
18
|
+
private toUpperCase;
|
|
17
19
|
private registerComparisonHelpers;
|
|
18
20
|
private registerTypeCheckHelpers;
|
|
19
21
|
private hasNonSerializableClassDecorator;
|
|
@@ -93,13 +93,21 @@ class HandlebarsTemplateEngine {
|
|
|
93
93
|
this.registerConstructorHelpers();
|
|
94
94
|
this.registerLogicHelpers();
|
|
95
95
|
}
|
|
96
|
+
isPrimitiveType(kind) {
|
|
97
|
+
return ['string', 'number', 'boolean', 'bigint', 'undefined', 'null'].includes(kind);
|
|
98
|
+
}
|
|
99
|
+
toUpperCase(name) {
|
|
100
|
+
if (!name) {
|
|
101
|
+
return '';
|
|
102
|
+
}
|
|
103
|
+
return name.charAt(0).toUpperCase() + name.substring(1);
|
|
104
|
+
}
|
|
96
105
|
registerComparisonHelpers() {
|
|
97
106
|
this.registerHelper('eq', (arg1, arg2) => {
|
|
98
107
|
return (arg1 === arg2);
|
|
99
108
|
});
|
|
100
109
|
this.registerHelper('eqPrimitiveType', (kind) => {
|
|
101
|
-
|
|
102
|
-
return primitives.includes(kind);
|
|
110
|
+
return this.isPrimitiveType(kind);
|
|
103
111
|
});
|
|
104
112
|
this.registerHelper('eqEmptyType', (kind) => {
|
|
105
113
|
return ['null', 'undefined'].includes(kind);
|
|
@@ -182,6 +190,17 @@ class HandlebarsTemplateEngine {
|
|
|
182
190
|
this.registerHelper('toLowerCase', (str) => {
|
|
183
191
|
return str.toLowerCase();
|
|
184
192
|
});
|
|
193
|
+
this.registerHelper('toUpperCase', (str) => {
|
|
194
|
+
return this.toUpperCase(str);
|
|
195
|
+
});
|
|
196
|
+
this.registerHelper('getSerializer', (analysis) => {
|
|
197
|
+
if (this.isPrimitiveType(analysis.type.kind)) {
|
|
198
|
+
return `${analysis.name}Serializer`;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
return `get${this.toUpperCase(analysis.name)}Serializer()`;
|
|
202
|
+
}
|
|
203
|
+
});
|
|
185
204
|
this.registerHelper('genericParametersString', (parameters) => {
|
|
186
205
|
return parameters.join(', ');
|
|
187
206
|
});
|
|
@@ -4,7 +4,8 @@ exports.TsMorphUtil = void 0;
|
|
|
4
4
|
const ts_morph_1 = require("ts-morph");
|
|
5
5
|
const Logger_1 = require("../logger/Logger");
|
|
6
6
|
class TsMorphUtil {
|
|
7
|
-
constructor() {
|
|
7
|
+
constructor() {
|
|
8
|
+
}
|
|
8
9
|
static getProject(options) {
|
|
9
10
|
if (!this.project) {
|
|
10
11
|
Logger_1.Logger.info('创建ts-morph项目');
|