@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.
- package/LICENSE +177 -0
- package/README.md +253 -0
- package/dist/core/Types.d.ts +196 -0
- package/dist/core/Types.js +47 -0
- package/dist/core/analyzers/ClassAnalyzer.d.ts +23 -0
- package/dist/core/analyzers/ClassAnalyzer.js +480 -0
- package/dist/core/analyzers/CustomTypeAnalyzer.d.ts +21 -0
- package/dist/core/analyzers/CustomTypeAnalyzer.js +243 -0
- package/dist/core/analyzers/SendableMergeChecker.d.ts +9 -0
- package/dist/core/analyzers/SendableMergeChecker.js +100 -0
- package/dist/core/analyzers/SendableMergeabilityRegistry.d.ts +7 -0
- package/dist/core/analyzers/SendableMergeabilityRegistry.js +23 -0
- package/dist/core/constants/DecoratorConstants.d.ts +7 -0
- package/dist/core/constants/DecoratorConstants.js +13 -0
- package/dist/core/constants/PathConstants.d.ts +6 -0
- package/dist/core/constants/PathConstants.js +10 -0
- package/dist/core/constants/StringConstants.d.ts +83 -0
- package/dist/core/constants/StringConstants.js +87 -0
- package/dist/core/constants/index.d.ts +3 -0
- package/dist/core/constants/index.js +19 -0
- package/dist/core/handlers/BaseTypeHandler.d.ts +23 -0
- package/dist/core/handlers/BaseTypeHandler.js +57 -0
- package/dist/core/handlers/CustomClassHandler.d.ts +21 -0
- package/dist/core/handlers/CustomClassHandler.js +191 -0
- package/dist/core/handlers/DateHandler.d.ts +2 -0
- package/dist/core/handlers/DateHandler.js +60 -0
- package/dist/core/handlers/DecimalHandler.d.ts +2 -0
- package/dist/core/handlers/DecimalHandler.js +60 -0
- package/dist/core/handlers/EnumHandler.d.ts +2 -0
- package/dist/core/handlers/EnumHandler.js +89 -0
- package/dist/core/handlers/GenericContainerHandler.d.ts +2 -0
- package/dist/core/handlers/GenericContainerHandler.js +440 -0
- package/dist/core/handlers/GenericHandler.d.ts +18 -0
- package/dist/core/handlers/GenericHandler.js +92 -0
- package/dist/core/handlers/HandlerBootstrap.d.ts +2 -0
- package/dist/core/handlers/HandlerBootstrap.js +28 -0
- package/dist/core/handlers/ITypeHandler.d.ts +23 -0
- package/dist/core/handlers/ITypeHandler.js +8 -0
- package/dist/core/handlers/PrimitiveHandler.d.ts +2 -0
- package/dist/core/handlers/PrimitiveHandler.js +127 -0
- package/dist/core/handlers/TupleHandler.d.ts +2 -0
- package/dist/core/handlers/TupleHandler.js +98 -0
- package/dist/core/handlers/TypeHandlerRegistry.d.ts +20 -0
- package/dist/core/handlers/TypeHandlerRegistry.js +113 -0
- package/dist/core/handlers/UnionTypeHandler.d.ts +2 -0
- package/dist/core/handlers/UnionTypeHandler.js +263 -0
- package/dist/core/handlers/index.d.ts +2 -0
- package/dist/core/handlers/index.js +5 -0
- package/dist/core/import-rewrite/services/BuildProfileUpdater.d.ts +8 -0
- package/dist/core/import-rewrite/services/BuildProfileUpdater.js +92 -0
- package/dist/core/import-rewrite/services/ImportRewriteService.d.ts +9 -0
- package/dist/core/import-rewrite/services/ImportRewriteService.js +61 -0
- package/dist/core/import-rewrite/services/ImportTransformService.d.ts +15 -0
- package/dist/core/import-rewrite/services/ImportTransformService.js +109 -0
- package/dist/core/import-rewrite/strategies/ImportScanStrategy.d.ts +17 -0
- package/dist/core/import-rewrite/strategies/ImportScanStrategy.js +137 -0
- package/dist/core/import-rewrite/types/ImportRewriteTypes.d.ts +17 -0
- package/dist/core/import-rewrite/types/ImportRewriteTypes.js +2 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.js +27 -0
- package/dist/core/interfaces/ITask.d.ts +7 -0
- package/dist/core/interfaces/ITask.js +2 -0
- package/dist/core/interfaces/ITaskContext.d.ts +11 -0
- package/dist/core/interfaces/ITaskContext.js +2 -0
- package/dist/core/interfaces/index.d.ts +2 -0
- package/dist/core/interfaces/index.js +2 -0
- package/dist/core/logger/Logger.d.ts +13 -0
- package/dist/core/logger/Logger.js +78 -0
- package/dist/core/services/CodeAnalysisService.d.ts +7 -0
- package/dist/core/services/CodeAnalysisService.js +43 -0
- package/dist/core/services/CodeGenerationEngine.d.ts +12 -0
- package/dist/core/services/CodeGenerationEngine.js +102 -0
- package/dist/core/services/CodeGenerationService/CodeGenerationService.d.ts +13 -0
- package/dist/core/services/CodeGenerationService/CodeGenerationService.js +110 -0
- package/dist/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.d.ts +13 -0
- package/dist/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.js +119 -0
- package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.d.ts +21 -0
- package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.js +224 -0
- package/dist/core/services/CodeGenerationService/generators/SendableClassGenerator.d.ts +24 -0
- package/dist/core/services/CodeGenerationService/generators/SendableClassGenerator.js +307 -0
- package/dist/core/services/CodeGenerationService/generators/SerializerGenerator.d.ts +28 -0
- package/dist/core/services/CodeGenerationService/generators/SerializerGenerator.js +259 -0
- package/dist/core/services/CodeGenerationService/generators/TempSerializerGenerator.d.ts +19 -0
- package/dist/core/services/CodeGenerationService/generators/TempSerializerGenerator.js +178 -0
- package/dist/core/services/CodeGenerationService/index.d.ts +1 -0
- package/dist/core/services/CodeGenerationService/index.js +5 -0
- package/dist/core/services/CodeGenerationService/shared/ImportManager.d.ts +27 -0
- package/dist/core/services/CodeGenerationService/shared/ImportManager.js +127 -0
- package/dist/core/template/HandlebarsTemplateEngine.d.ts +26 -0
- package/dist/core/template/HandlebarsTemplateEngine.js +226 -0
- package/dist/core/utils/ConfigManager.d.ts +10 -0
- package/dist/core/utils/ConfigManager.js +32 -0
- package/dist/core/utils/CustomError.d.ts +30 -0
- package/dist/core/utils/CustomError.js +37 -0
- package/dist/core/utils/DeepCopyUtil.d.ts +15 -0
- package/dist/core/utils/DeepCopyUtil.js +138 -0
- package/dist/core/utils/GenericTypeSubstitutionUtil.d.ts +9 -0
- package/dist/core/utils/GenericTypeSubstitutionUtil.js +68 -0
- package/dist/core/utils/SerializationPathUtil.d.ts +18 -0
- package/dist/core/utils/SerializationPathUtil.js +107 -0
- package/dist/core/utils/TsMorphUtil.d.ts +8 -0
- package/dist/core/utils/TsMorphUtil.js +34 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +57 -0
- package/dist/json-plugin/JSONExecuteController.d.ts +13 -0
- package/dist/json-plugin/JSONExecuteController.js +103 -0
- package/dist/json-plugin/constants/TaskConstants.d.ts +7 -0
- package/dist/json-plugin/constants/TaskConstants.js +11 -0
- package/dist/json-plugin/interfaces/IModuleContext.d.ts +10 -0
- package/dist/json-plugin/interfaces/IModuleContext.js +2 -0
- package/dist/json-plugin/interfaces/ITargetContext.d.ts +8 -0
- package/dist/json-plugin/interfaces/ITargetContext.js +2 -0
- package/dist/json-plugin/interfaces/impl/ModuleContext.d.ts +12 -0
- package/dist/json-plugin/interfaces/impl/ModuleContext.js +24 -0
- package/dist/json-plugin/interfaces/impl/TargetContext.d.ts +23 -0
- package/dist/json-plugin/interfaces/impl/TargetContext.js +113 -0
- package/dist/json-plugin/tasks/BaseTask.d.ts +14 -0
- package/dist/json-plugin/tasks/BaseTask.js +53 -0
- package/dist/json-plugin/tasks/CleanTask.d.ts +8 -0
- package/dist/json-plugin/tasks/CleanTask.js +25 -0
- package/dist/json-plugin/tasks/CodeProcessingTask.d.ts +8 -0
- package/dist/json-plugin/tasks/CodeProcessingTask.js +26 -0
- package/dist/json-plugin/tasks/SyncTask.d.ts +8 -0
- package/dist/json-plugin/tasks/SyncTask.js +21 -0
- package/dist/json-plugin/tasks/WatchTask.d.ts +11 -0
- package/dist/json-plugin/tasks/WatchTask.js +102 -0
- package/package.json +46 -0
- package/src/core/Types.ts +356 -0
- package/src/core/analyzers/ClassAnalyzer.ts +824 -0
- package/src/core/analyzers/CustomTypeAnalyzer.ts +337 -0
- package/src/core/analyzers/SendableMergeChecker.ts +195 -0
- package/src/core/analyzers/SendableMergeabilityRegistry.ts +72 -0
- package/src/core/constants/DecoratorConstants.ts +27 -0
- package/src/core/constants/PathConstants.ts +31 -0
- package/src/core/constants/StringConstants.ts +152 -0
- package/src/core/constants/index.ts +21 -0
- package/src/core/handlers/BaseTypeHandler.ts +121 -0
- package/src/core/handlers/CustomClassHandler.ts +278 -0
- package/src/core/handlers/DateHandler.ts +75 -0
- package/src/core/handlers/DecimalHandler.ts +75 -0
- package/src/core/handlers/EnumHandler.ts +142 -0
- package/src/core/handlers/GenericContainerHandler.ts +621 -0
- package/src/core/handlers/GenericHandler.ts +130 -0
- package/src/core/handlers/HandlerBootstrap.ts +64 -0
- package/src/core/handlers/ITypeHandler.ts +133 -0
- package/src/core/handlers/PrimitiveHandler.ts +159 -0
- package/src/core/handlers/TupleHandler.ts +145 -0
- package/src/core/handlers/TypeHandlerRegistry.ts +236 -0
- package/src/core/handlers/UnionTypeHandler.ts +400 -0
- package/src/core/handlers/index.ts +18 -0
- package/src/core/import-rewrite/services/BuildProfileUpdater.ts +145 -0
- package/src/core/import-rewrite/services/ImportRewriteService.ts +129 -0
- package/src/core/import-rewrite/services/ImportTransformService.ts +200 -0
- package/src/core/import-rewrite/strategies/ImportScanStrategy.ts +303 -0
- package/src/core/import-rewrite/types/ImportRewriteTypes.ts +100 -0
- package/src/core/index.ts +31 -0
- package/src/core/interfaces/ITask.ts +23 -0
- package/src/core/interfaces/ITaskContext.ts +94 -0
- package/src/core/interfaces/index.ts +17 -0
- package/src/core/logger/Logger.ts +149 -0
- package/src/core/services/CodeAnalysisService.ts +67 -0
- package/src/core/services/CodeGenerationEngine.ts +181 -0
- package/src/core/services/CodeGenerationService/CodeGenerationService.ts +159 -0
- package/src/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.ts +189 -0
- package/src/core/services/CodeGenerationService/generators/OriginalClassGenerator.ts +314 -0
- package/src/core/services/CodeGenerationService/generators/SendableClassGenerator.ts +421 -0
- package/src/core/services/CodeGenerationService/generators/SerializerGenerator.ts +392 -0
- package/src/core/services/CodeGenerationService/generators/TempSerializerGenerator.ts +277 -0
- package/src/core/services/CodeGenerationService/index.ts +16 -0
- package/src/core/services/CodeGenerationService/shared/ImportManager.ts +191 -0
- package/src/core/template/HandlebarsTemplateEngine.ts +282 -0
- package/src/core/utils/ConfigManager.ts +49 -0
- package/src/core/utils/CustomError.ts +51 -0
- package/src/core/utils/DeepCopyUtil.ts +185 -0
- package/src/core/utils/GenericTypeSubstitutionUtil.ts +136 -0
- package/src/core/utils/SerializationPathUtil.ts +142 -0
- package/src/core/utils/TsMorphUtil.ts +50 -0
- package/src/index.ts +81 -0
- package/src/json-plugin/JSONExecuteController.ts +134 -0
- package/src/json-plugin/constants/TaskConstants.ts +22 -0
- package/src/json-plugin/interfaces/IModuleContext.ts +27 -0
- package/src/json-plugin/interfaces/ITargetContext.ts +25 -0
- package/src/json-plugin/interfaces/impl/ModuleContext.ts +45 -0
- package/src/json-plugin/interfaces/impl/TargetContext.ts +196 -0
- package/src/json-plugin/tasks/BaseTask.ts +94 -0
- package/src/json-plugin/tasks/CleanTask.ts +36 -0
- package/src/json-plugin/tasks/CodeProcessingTask.ts +41 -0
- package/src/json-plugin/tasks/SyncTask.ts +33 -0
- package/src/json-plugin/tasks/WatchTask.ts +99 -0
- package/template/SerializerPerformanceTemplate.hbs +35 -0
- package/template/SerializerRegisterTemplate.hbs +10 -0
- package/template/SerializerStrictTemplate.hbs +89 -0
- package/template/SerializerTemplate.hbs +176 -0
- package/tsconfig.json +17 -0
- package/tslint.json +3 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { ClassDeclaration, SourceFile } from 'ts-morph';
|
|
17
|
+
import { ClassAnalysis, ClassDetails, Logger, PropertyAnalysis, PropertyKind, TypeKind, TypeStructure } from '../../..';
|
|
18
|
+
import { ImportManager } from '../shared/ImportManager';
|
|
19
|
+
import { ClassAnalyzer } from '../../../analyzers/ClassAnalyzer';
|
|
20
|
+
import { TypeHandlerRegistry } from '../../../handlers';
|
|
21
|
+
import { ConversionDirection } from '../../../handlers/ITypeHandler';
|
|
22
|
+
import { TsMorphUtil } from '../../../utils/TsMorphUtil';
|
|
23
|
+
import SerializationPathUtil from '../../../utils/SerializationPathUtil';
|
|
24
|
+
|
|
25
|
+
export class SendableClassGenerator {
|
|
26
|
+
canHandle(result: ClassAnalysis): boolean {
|
|
27
|
+
return !!result.decorators.serializable?.generateSendable;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
generate(sourceFile: SourceFile, result: ClassAnalysis, importManager: ImportManager): void {
|
|
31
|
+
// 1. 复制原始类结构
|
|
32
|
+
const sendableClass = this.getOriginClassDeclaration(result);
|
|
33
|
+
|
|
34
|
+
// 2. 修改类名
|
|
35
|
+
this.renameSendableClass(sendableClass, result);
|
|
36
|
+
|
|
37
|
+
// 3. 修改继承的类名
|
|
38
|
+
this.updateInheritanceToSendable(sendableClass, result);
|
|
39
|
+
|
|
40
|
+
// 4.移除实现关系,否则会出现属性类型变化,但是接口定义类型未修改情况
|
|
41
|
+
this.removeImplements(sendableClass);
|
|
42
|
+
|
|
43
|
+
// 4. 剔除所有装饰器
|
|
44
|
+
this.removeAllDecorators(sendableClass);
|
|
45
|
+
|
|
46
|
+
// 5. 转换属性类型
|
|
47
|
+
this.convertPropertyTypesToSendable(sendableClass, result);
|
|
48
|
+
|
|
49
|
+
// 6. 转换构造函数参数类型
|
|
50
|
+
this.convertConstructorParameterTypes(sendableClass, result);
|
|
51
|
+
|
|
52
|
+
// 7. 添加@Sendable装饰器和lang.ISendable接口
|
|
53
|
+
this.addSendableConstraints(sendableClass);
|
|
54
|
+
|
|
55
|
+
// 8. 添加toOrigin方法
|
|
56
|
+
this.addToOriginMethod(sendableClass, result, importManager);
|
|
57
|
+
|
|
58
|
+
// 9. 添加必要地导入语句
|
|
59
|
+
this.addNecessaryImports(result, importManager);
|
|
60
|
+
|
|
61
|
+
// 10. 将处理后的类添加到目标文件
|
|
62
|
+
sourceFile.addClasses([sendableClass.getStructure()]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private getOriginClassDeclaration(result: ClassAnalysis): ClassDeclaration {
|
|
66
|
+
const originalContent = result.originalClass?.getFullText();
|
|
67
|
+
const copiedSourceFile = TsMorphUtil.getProject().createSourceFile('copied-file.ts', originalContent, { overwrite: true });
|
|
68
|
+
return copiedSourceFile.getClassOrThrow(result.className);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private renameSendableClass(classDecl: ClassDeclaration, result: ClassAnalysis): void {
|
|
72
|
+
const sendableClassName = this.getSendableClassName(result);
|
|
73
|
+
classDecl.set({ name: sendableClassName });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private updateInheritanceToSendable(classDecl: ClassDeclaration, result: ClassAnalysis): void {
|
|
77
|
+
if (!result.inheritance.isInherited) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const extendsClause = classDecl.getExtendsOrThrow();
|
|
81
|
+
const sendableBaseClassName = `Sendable${result.inheritance.baseClassAnalysis?.className}`;
|
|
82
|
+
extendsClause.setExpression(sendableBaseClassName);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private removeImplements(classDecl: ClassDeclaration): void {
|
|
86
|
+
const implementsClauses = classDecl.getImplements();
|
|
87
|
+
implementsClauses.forEach(imple => {
|
|
88
|
+
classDecl.removeImplements(imple);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private removeAllDecorators(classDecl: ClassDeclaration): void {
|
|
93
|
+
// 剔除类级别装饰器
|
|
94
|
+
classDecl.getDecorators().forEach((decorator) => {
|
|
95
|
+
Logger.warn(
|
|
96
|
+
`Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`
|
|
97
|
+
);
|
|
98
|
+
decorator.remove();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// 剔除属性装饰器,@Sendable无法与其他装饰器共存
|
|
102
|
+
classDecl.getProperties().forEach((property) => {
|
|
103
|
+
property.getDecorators().forEach((decorator) => {
|
|
104
|
+
Logger.warn(
|
|
105
|
+
`Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`
|
|
106
|
+
);
|
|
107
|
+
decorator.remove();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// 剔除方法装饰器,@Sendable无法与其他装饰器共存
|
|
112
|
+
classDecl.getMethods().forEach((method) => {
|
|
113
|
+
method.getDecorators().forEach((decorator) => {
|
|
114
|
+
Logger.warn(
|
|
115
|
+
`Remove the decorator ${decorator.getName()}, because @Sendable cannot coexist with other decorators`
|
|
116
|
+
);
|
|
117
|
+
decorator.remove();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private convertPropertyTypesToSendable(classDecl: ClassDeclaration, result: ClassAnalysis): void {
|
|
123
|
+
const properties = classDecl.getProperties();
|
|
124
|
+
|
|
125
|
+
properties.forEach((property) => {
|
|
126
|
+
const propertyName = property.getName();
|
|
127
|
+
|
|
128
|
+
Logger.debug(`Converting property ${propertyName} to sendable`);
|
|
129
|
+
|
|
130
|
+
// 从分析结果中找到对应的属性信息
|
|
131
|
+
const propertyAnalysis = result.properties.find((p) => p.name === propertyName);
|
|
132
|
+
if (!propertyAnalysis) {
|
|
133
|
+
Logger.warn(`未找到属性 ${propertyName} 的分析信息`);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
Logger.debug(
|
|
138
|
+
`Found property ${propertyName} analysis info: ${propertyAnalysis.name} ${propertyAnalysis.type.sourceText}`
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
// 转换类型为Sendable兼容类型
|
|
142
|
+
const sendableType = this.convertToSendableType(propertyAnalysis.type);
|
|
143
|
+
|
|
144
|
+
Logger.debug(`Converted type ${propertyAnalysis.type.sourceText} to ${sendableType}`);
|
|
145
|
+
|
|
146
|
+
if (sendableType !== propertyAnalysis.type.sourceText) {
|
|
147
|
+
property.setType(sendableType);
|
|
148
|
+
Logger.debug(`属性 ${propertyName} 类型从 ${propertyAnalysis.type.sourceText} 转换为 ${sendableType}`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 处理默认值中的构造函数调用
|
|
152
|
+
const initializer = property.getInitializer();
|
|
153
|
+
if (initializer) {
|
|
154
|
+
const initializerText = initializer.getText();
|
|
155
|
+
const convertedInitializer = this.convertInitializerToSendable(initializerText);
|
|
156
|
+
if (convertedInitializer !== initializerText) {
|
|
157
|
+
property.setInitializer(convertedInitializer);
|
|
158
|
+
Logger.debug(`属性 ${propertyName} 默认值从 ${initializerText} 转换为 ${convertedInitializer}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private addSendableConstraints(classDecl: ClassDeclaration): void {
|
|
165
|
+
// 添加@Sendable装饰器
|
|
166
|
+
classDecl.addDecorator({ name: 'Sendable' });
|
|
167
|
+
|
|
168
|
+
// 实现lang.ISendable接口
|
|
169
|
+
classDecl.addImplements('lang.ISendable');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private addToOriginMethod(classDecl: ClassDeclaration, result: ClassAnalysis, importManger: ImportManager): void {
|
|
173
|
+
let returnType = result.className;
|
|
174
|
+
if (result.generics.isGeneric) {
|
|
175
|
+
returnType += `<${result.generics.parameters.join(', ')}>`;
|
|
176
|
+
}
|
|
177
|
+
const methodBody = this.generatedToOriginMethodBody(result, returnType);
|
|
178
|
+
classDecl.addMethod({
|
|
179
|
+
name: 'toOrigin',
|
|
180
|
+
returnType,
|
|
181
|
+
statements: [methodBody]
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// 导入原始类
|
|
185
|
+
importManger.registerCustomTypeImport(result.sourceFilePath, result.className);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private generatedToOriginMethodBody(result: ClassAnalysis, returnType: string): string {
|
|
189
|
+
const statements: string[] = [];
|
|
190
|
+
let constructorCall;
|
|
191
|
+
if (result.constructorParams.length > 0) {
|
|
192
|
+
const constructorProps: PropertyAnalysis[] = [];
|
|
193
|
+
result.properties.forEach((p) => {
|
|
194
|
+
const isConstructorProp = result.constructorParams.find((cp) => cp.name === p.name);
|
|
195
|
+
if (isConstructorProp) {
|
|
196
|
+
constructorProps.push({
|
|
197
|
+
...p,
|
|
198
|
+
type: {
|
|
199
|
+
...p.type,
|
|
200
|
+
isOptional: isConstructorProp.isOptional
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const args = constructorProps
|
|
207
|
+
.map((prop) => {
|
|
208
|
+
return this.generatePropertyConversion(prop, 'this.');
|
|
209
|
+
})
|
|
210
|
+
.join(', ');
|
|
211
|
+
|
|
212
|
+
constructorCall = `new ${returnType}(${args})`;
|
|
213
|
+
} else {
|
|
214
|
+
constructorCall = `new ${returnType}()`;
|
|
215
|
+
}
|
|
216
|
+
statements.push(`const origin = ${constructorCall};`);
|
|
217
|
+
|
|
218
|
+
const assignmentProps = result.properties.filter((p) => {
|
|
219
|
+
return result.constructorParams.every((cp) => cp.name !== p.name);
|
|
220
|
+
});
|
|
221
|
+
// 生成属性赋值语句
|
|
222
|
+
if (assignmentProps.length > 0) {
|
|
223
|
+
statements.push('');
|
|
224
|
+
statements.push('// 非构造函数属性赋值');
|
|
225
|
+
assignmentProps.forEach((prop) => {
|
|
226
|
+
const assignment = this.generatePropertyConversion(prop, 'this.');
|
|
227
|
+
statements.push(`origin.${prop.name} = ${assignment};`);
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
statements.push('');
|
|
232
|
+
statements.push('return origin;');
|
|
233
|
+
|
|
234
|
+
return statements.join('\n');
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private generatePropertyConversion(prop: PropertyAnalysis, prefix: string): string {
|
|
238
|
+
const sourceValue = `${prefix}${prop.name}`;
|
|
239
|
+
if (prop.type.kind === PropertyKind.UNKNOWN) {
|
|
240
|
+
// UNKNOWN只接跳过
|
|
241
|
+
return sourceValue;
|
|
242
|
+
}
|
|
243
|
+
const registry = TypeHandlerRegistry.getInstance();
|
|
244
|
+
const handler = registry.getHandlerForKind(prop.type.kind);
|
|
245
|
+
|
|
246
|
+
try {
|
|
247
|
+
// TO_ORIGIN: Sendable对象 -> 普通对象
|
|
248
|
+
return handler.generatePropertyConversion(prop.type, sourceValue, ConversionDirection.TO_ORIGIN);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
Logger.error(`生成属性转换代码失败: ${error}`);
|
|
251
|
+
return sourceValue;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
private getSendableClassName(result: ClassAnalysis): string {
|
|
256
|
+
return `Sendable${result.className}`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
private addNecessaryImports(result: ClassAnalysis, importManager: ImportManager): void {
|
|
260
|
+
// 1. 处理类导入
|
|
261
|
+
result.properties.forEach((property) => {
|
|
262
|
+
property.type.dependencies.forEach((dependency) => {
|
|
263
|
+
if (dependency.typeKind === TypeKind.CLASS) {
|
|
264
|
+
const classAnalysis = ClassAnalyzer.analyzeClass((dependency.details as ClassDetails).classDecl);
|
|
265
|
+
if (classAnalysis.decorators.serializable?.generateSendable) {
|
|
266
|
+
importManager.registerCustomImport('./Sendable' + dependency.typeName, 'Sendable' + dependency.typeName);
|
|
267
|
+
} else {
|
|
268
|
+
importManager.registerCustomTypeImport(dependency.source.sourceFilePath!, dependency.typeName);
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
importManager.registerCustomTypeImport(dependency.source.sourceFilePath!, dependency.typeName);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
const baseClass = result.inheritance.baseClassAnalysis;
|
|
277
|
+
if (baseClass) {
|
|
278
|
+
importManager.registerCustomImport('./Sendable' + baseClass.className, 'Sendable' + baseClass.className);
|
|
279
|
+
}
|
|
280
|
+
// 2. 检查是否需要collections导入
|
|
281
|
+
const needsCollections = this.needsCollectionsImport(result);
|
|
282
|
+
if (needsCollections) {
|
|
283
|
+
importManager.registerArkTSImports(['collections']);
|
|
284
|
+
}
|
|
285
|
+
// 3. 拷贝源文件导入
|
|
286
|
+
result.originalClass?.getSourceFile().getImportDeclarations().forEach(importDecl => {
|
|
287
|
+
const specifier = importDecl.getModuleSpecifierValue();
|
|
288
|
+
const names = importDecl.getNamedImports().map((names) => names.getName());
|
|
289
|
+
const defaultImport = importDecl.getDefaultImport();
|
|
290
|
+
const originalDir = SerializationPathUtil.dirname(result.sourceFilePath);
|
|
291
|
+
|
|
292
|
+
const importOriginAbs = SerializationPathUtil.pathResolve(originalDir, specifier);
|
|
293
|
+
if (SerializationPathUtil.exist(importOriginAbs + '.ets')) {
|
|
294
|
+
// 路径存在,使用模块化路径计算
|
|
295
|
+
const importOriginAbsWithExt = importOriginAbs + '.ets';
|
|
296
|
+
names.forEach((name) => {
|
|
297
|
+
importManager.registerCustomTypeImport(importOriginAbsWithExt, name);
|
|
298
|
+
});
|
|
299
|
+
if (defaultImport) {
|
|
300
|
+
importManager.registerDefaultImport(importOriginAbsWithExt, defaultImport.getText());
|
|
301
|
+
}
|
|
302
|
+
} else {
|
|
303
|
+
// 不存在该路径,说明可能为包名,暂时不动
|
|
304
|
+
names.forEach((name) => {
|
|
305
|
+
importManager.registerCustomImport(specifier, name);
|
|
306
|
+
});
|
|
307
|
+
if (defaultImport) {
|
|
308
|
+
importManager.registerDefaultImport(specifier, defaultImport.getText());
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
private convertConstructorParameterTypes(classDecl: ClassDeclaration, result: ClassAnalysis): void {
|
|
315
|
+
const constructors = classDecl.getConstructors();
|
|
316
|
+
|
|
317
|
+
constructors.forEach((constructor) => {
|
|
318
|
+
const parameters = constructor.getParameters();
|
|
319
|
+
|
|
320
|
+
parameters.forEach((parameter) => {
|
|
321
|
+
const paramName = parameter.getName();
|
|
322
|
+
|
|
323
|
+
// 从分析结果中找到对应的属性信息
|
|
324
|
+
const propertyAnalysis = result.properties.find((p) => p.name === paramName);
|
|
325
|
+
if (!propertyAnalysis) {
|
|
326
|
+
Logger.warn(`未找到构造函数参数 ${paramName} 的分析信息`);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// 转换参数类型为Sendable兼容类型
|
|
331
|
+
const sendableType = this.convertToSendableType(propertyAnalysis.type);
|
|
332
|
+
if (sendableType !== propertyAnalysis.type.sourceText) {
|
|
333
|
+
parameter.setType(sendableType);
|
|
334
|
+
Logger.debug(`构造函数参数 ${paramName} 类型从 ${propertyAnalysis.type.sourceText} 转换为 ${sendableType}`);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
private isObjectType(typeName: string): boolean {
|
|
341
|
+
// 基础类型不需要转换
|
|
342
|
+
const primitiveTypes = ['string', 'number', 'boolean', 'bigint', 'null', 'undefined'];
|
|
343
|
+
if (primitiveTypes.includes(typeName)) {
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// 集合类型不需要转换(已经处理过)
|
|
348
|
+
if (
|
|
349
|
+
typeName.startsWith('collections.') ||
|
|
350
|
+
typeName.startsWith('Array<') ||
|
|
351
|
+
typeName.startsWith('Map<') ||
|
|
352
|
+
typeName.startsWith('Set<')
|
|
353
|
+
) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// 已经是Sendable类型的不需要再转换
|
|
358
|
+
if (typeName.startsWith('Sendable')) {
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// 其他情况认为是对象类型,需要转换
|
|
363
|
+
return true;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
public needsCollectionsImport(result: ClassAnalysis): boolean {
|
|
367
|
+
return result.properties.some((prop) => {
|
|
368
|
+
const typeText = this.convertToSendableType(prop.type);
|
|
369
|
+
return typeText.includes('collections');
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
private convertInitializerToSendable(initializerText: string): string {
|
|
374
|
+
let convertedText = initializerText;
|
|
375
|
+
|
|
376
|
+
// 1. 处理数组字面量(最优先)
|
|
377
|
+
if (convertedText === '[]') {
|
|
378
|
+
convertedText = 'new collections.Array()';
|
|
379
|
+
} else if (convertedText.startsWith('[') && convertedText.endsWith(']')) {
|
|
380
|
+
// 处理 [1, 2, 3] 这种情况
|
|
381
|
+
const arrayContent = convertedText.slice(1, -1);
|
|
382
|
+
if (arrayContent.trim()) {
|
|
383
|
+
convertedText = `new collections.Array(${arrayContent})`;
|
|
384
|
+
} else {
|
|
385
|
+
convertedText = 'new collections.Array()';
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// 2. 处理集合类型构造函数(优先于对象类型)
|
|
390
|
+
convertedText = convertedText.replace(/new\s+Set\s*\(/g, 'new collections.Set(');
|
|
391
|
+
convertedText = convertedText.replace(/new\s+Map\s*\(/g, 'new collections.Map(');
|
|
392
|
+
convertedText = convertedText.replace(/new\s+Array\s*\(/g, 'new collections.Array(');
|
|
393
|
+
|
|
394
|
+
// 3. 处理对象构造函数:new Person(...) -> new SendablePerson(...)
|
|
395
|
+
const objectConstructorPattern = /new\s+(\w+)\s*\(/g;
|
|
396
|
+
convertedText = convertedText.replace(objectConstructorPattern, (match, className) => {
|
|
397
|
+
// 跳过已经转换的集合类型
|
|
398
|
+
if (className === 'collections' || match.includes('collections.')) {
|
|
399
|
+
return match;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (this.isObjectType(className)) {
|
|
403
|
+
return match.replace(className, `Sendable${className}`);
|
|
404
|
+
}
|
|
405
|
+
return match;
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
Logger.debug(`初始化器转换: ${initializerText} -> ${convertedText}`);
|
|
409
|
+
return convertedText;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
private convertToSendableType(structure: TypeStructure): string {
|
|
413
|
+
if (structure.kind === PropertyKind.UNKNOWN) {
|
|
414
|
+
// UNKNOWN只接跳过
|
|
415
|
+
return structure.sourceText;
|
|
416
|
+
}
|
|
417
|
+
const registry = TypeHandlerRegistry.getInstance();
|
|
418
|
+
const handler = registry.getHandlerForKind(structure.kind);
|
|
419
|
+
return handler.generateSendableTypeDeclaration(structure);
|
|
420
|
+
}
|
|
421
|
+
}
|