@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,130 @@
|
|
|
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 { TypeNode, SyntaxKind, TypeReferenceNode } from 'ts-morph';
|
|
17
|
+
import { PropertyKind, TypeStructure, SerializerMetadata } from '../Types';
|
|
18
|
+
import { ITypeHandler, TypeContext, ConversionDirection } from './ITypeHandler';
|
|
19
|
+
import { BaseTypeHandler } from './BaseTypeHandler';
|
|
20
|
+
|
|
21
|
+
export class GenericHandler extends BaseTypeHandler implements ITypeHandler {
|
|
22
|
+
readonly name = 'GenericHandler';
|
|
23
|
+
readonly kind = PropertyKind.GENERIC;
|
|
24
|
+
readonly priority = 95; // 高优先级,在CustomClassHandler之前
|
|
25
|
+
|
|
26
|
+
// ==================== 阶段1: 类型识别 ====================
|
|
27
|
+
|
|
28
|
+
matches(typeNode: TypeNode, context: TypeContext): boolean {
|
|
29
|
+
// 必须是TypeReference且不能有泛型参数
|
|
30
|
+
if (typeNode.getKind() !== SyntaxKind.TypeReference) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const typeRef = typeNode as TypeReferenceNode;
|
|
35
|
+
const typeName = typeRef.getTypeName().getText();
|
|
36
|
+
|
|
37
|
+
// 没有泛型参数(如果有泛型参数说明是泛型类,不是泛型参数)
|
|
38
|
+
if (typeRef.getTypeArguments().length > 0) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return context.genericParams.includes(typeName);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ==================== 阶段2: 类型解析 ====================
|
|
46
|
+
|
|
47
|
+
parse(typeNode: TypeNode): TypeStructure {
|
|
48
|
+
const typeRef = typeNode as TypeReferenceNode;
|
|
49
|
+
const typeName = typeRef.getTypeName().getText();
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
kind: this.kind,
|
|
53
|
+
depth: 0,
|
|
54
|
+
sourceText: typeName,
|
|
55
|
+
args: [],
|
|
56
|
+
dependencies: []
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ==================== 阶段3: 序列化器配置 ====================
|
|
61
|
+
|
|
62
|
+
getSerializerMetadata(structure: TypeStructure, withParam?: string): SerializerMetadata {
|
|
63
|
+
const defaultInstantiation = this.generateInstantiation(structure);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
name: 'Serializer',
|
|
67
|
+
typeDeclaration: this.generateTypeDeclaration(structure),
|
|
68
|
+
instantiationTemplate: this.applyWithParam(withParam, defaultInstantiation, structure),
|
|
69
|
+
encodeMethod: 'encodeSerializableElement',
|
|
70
|
+
decodeMethod: 'deserialize',
|
|
71
|
+
decoderType: `${structure.sourceText} | undefined`,
|
|
72
|
+
needsTypeAssertion: false
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ==================== 阶段4: 代码生成 ====================
|
|
77
|
+
|
|
78
|
+
generateInstantiation(structure: TypeStructure): string {
|
|
79
|
+
const typeName = structure.sourceText;
|
|
80
|
+
const lowerName = typeName.toLowerCase();
|
|
81
|
+
return `${lowerName}Serializer`; // 如 tSerializer
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
generateTypeDeclaration(structure: TypeStructure): string {
|
|
85
|
+
const typeName = structure.sourceText;
|
|
86
|
+
return `Serializer<${typeName}>`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
generateTypeKey(structure: TypeStructure): string {
|
|
90
|
+
const typeName = structure.sourceText;
|
|
91
|
+
return `'${typeName}'`; // 泛型参数的typeKey就是参数名
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ==================== Sendable转换 ====================
|
|
95
|
+
|
|
96
|
+
generateSendableTypeDeclaration(structure: TypeStructure): string {
|
|
97
|
+
// 泛型参数类型保持不变(泛型参数本身没有Sendable/非Sendable之分)
|
|
98
|
+
return structure.sourceText;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
generatePropertyConversion(structure: TypeStructure, sourceValue: string, direction: ConversionDirection): string {
|
|
102
|
+
|
|
103
|
+
if (direction === ConversionDirection.TO_SENDABLE) {
|
|
104
|
+
return `((): ${structure.sourceText}${structure.isOptional ? ' | undefined' : ''} => {
|
|
105
|
+
const sendable: ESObject = ${sourceValue};
|
|
106
|
+
if (sendable.toSendable) {
|
|
107
|
+
return sendable.toSendable();
|
|
108
|
+
} else {
|
|
109
|
+
return ${sourceValue}${structure.isOptional ? '' : '!'};
|
|
110
|
+
}
|
|
111
|
+
})()`;
|
|
112
|
+
} else {
|
|
113
|
+
return `((): ${structure.sourceText}${structure.isOptional ? ' | undefined' : ''} => {
|
|
114
|
+
const origin: ESObject = ${sourceValue};
|
|
115
|
+
if (origin.toOrigin) {
|
|
116
|
+
return origin.toOrigin();
|
|
117
|
+
} else {
|
|
118
|
+
return ${sourceValue}${structure.isOptional ? '' : '!'};
|
|
119
|
+
}
|
|
120
|
+
})()`;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 工厂函数
|
|
127
|
+
*/
|
|
128
|
+
export function createGenericHandler(): ITypeHandler {
|
|
129
|
+
return new GenericHandler();
|
|
130
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
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 { TypeHandlerRegistry } from './TypeHandlerRegistry';
|
|
17
|
+
import { createPrimitiveHandlers } from './PrimitiveHandler';
|
|
18
|
+
import { createGenericContainerHandlers } from './GenericContainerHandler';
|
|
19
|
+
import { createUnionTypeHandlers } from './UnionTypeHandler';
|
|
20
|
+
import { createEnumHandler } from './EnumHandler';
|
|
21
|
+
import { createGenericHandler } from './GenericHandler';
|
|
22
|
+
import { createCustomClassHandler } from './CustomClassHandler';
|
|
23
|
+
import { createTupleTypeHandlers } from './TupleHandler';
|
|
24
|
+
import { createDateHandler } from './DateHandler';
|
|
25
|
+
import { createDecimalHandler } from './DecimalHandler';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 初始化类型处理器注册表
|
|
29
|
+
* 注册所有内置的类型处理器
|
|
30
|
+
*/
|
|
31
|
+
export function initializeTypeHandlers(): TypeHandlerRegistry {
|
|
32
|
+
const registry = TypeHandlerRegistry.getInstance();
|
|
33
|
+
|
|
34
|
+
// 1. 注册基础类型处理器(6个Handler)
|
|
35
|
+
registry.registerAll(createPrimitiveHandlers());
|
|
36
|
+
|
|
37
|
+
// 2. 注册泛型容器处理器(7个Handler)
|
|
38
|
+
registry.registerAll(createGenericContainerHandlers());
|
|
39
|
+
|
|
40
|
+
// 3. 注册联合类型处理器(3个Handler)
|
|
41
|
+
registry.registerAll(createUnionTypeHandlers());
|
|
42
|
+
|
|
43
|
+
// 4. 注册枚举类型处理器(1个Handler)
|
|
44
|
+
registry.register(createEnumHandler());
|
|
45
|
+
|
|
46
|
+
// 5. 注册泛型参数处理器(1个Handler,优先级95,高于CustomClass)
|
|
47
|
+
registry.register(createGenericHandler());
|
|
48
|
+
|
|
49
|
+
// 6. 注册自定义类处理器(1个Handler,fallback,优先级最低)
|
|
50
|
+
registry.register(createCustomClassHandler());
|
|
51
|
+
|
|
52
|
+
// 7. 注册元组处理器(1个Handler)
|
|
53
|
+
registry.register(createTupleTypeHandlers());
|
|
54
|
+
|
|
55
|
+
// 8. 注册日期处理器(1个Handler)
|
|
56
|
+
registry.register(createDateHandler());
|
|
57
|
+
|
|
58
|
+
// 9. 注册其他处理器(如DecimalHandler)
|
|
59
|
+
registry.registerAll([
|
|
60
|
+
createDecimalHandler()
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
return registry;
|
|
64
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
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 { TypeNode } from 'ts-morph';
|
|
17
|
+
import { PropertyKind, SerializerMetadata, TypeStructure } from '..';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 类型处理器接口
|
|
21
|
+
* 包含类型从识别到代码生成的完整生命周期
|
|
22
|
+
*
|
|
23
|
+
* 设计原则:
|
|
24
|
+
* - 一个Handler只处理一个PropertyKind
|
|
25
|
+
* - Handler包含完整生命周期:识别→解析→配置→生成→验证
|
|
26
|
+
*/
|
|
27
|
+
export interface ITypeHandler {
|
|
28
|
+
/** 处理器名称(用于日志和调试) */
|
|
29
|
+
readonly name: string;
|
|
30
|
+
|
|
31
|
+
/** 处理的类型种类(一个Handler只处理一个Kind) */
|
|
32
|
+
readonly kind: PropertyKind;
|
|
33
|
+
|
|
34
|
+
/** 优先级(用于类型匹配冲突解决,数值越大优先级越高) */
|
|
35
|
+
readonly priority: number;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 判断是否能处理当前类型
|
|
39
|
+
* @param typeNode AST节点
|
|
40
|
+
* @param context 上下文
|
|
41
|
+
*/
|
|
42
|
+
matches(typeNode: TypeNode, context: TypeContext): boolean;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 解析类型节点为类型结构
|
|
46
|
+
* @param typeNode AST节点
|
|
47
|
+
* @param context 上下文
|
|
48
|
+
*/
|
|
49
|
+
parse(typeNode: TypeNode, context: TypeContext): TypeStructure;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 获取序列化器元数据
|
|
53
|
+
* @param structure 类型结构(parse阶段的输出)
|
|
54
|
+
* @param withParam 是否有with参数
|
|
55
|
+
*/
|
|
56
|
+
getSerializerMetadata(structure: TypeStructure, withParam?: string): SerializerMetadata;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 生成序列化器实例化代码
|
|
60
|
+
* @param structure 类型结构
|
|
61
|
+
*/
|
|
62
|
+
generateInstantiation(structure: TypeStructure): string;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 生成类型声明
|
|
66
|
+
* @param structure 类型结构
|
|
67
|
+
*/
|
|
68
|
+
generateTypeDeclaration(structure: TypeStructure): string;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 生成类型键表达式(用于with序列化器)
|
|
72
|
+
* @param structure 类型结构
|
|
73
|
+
*/
|
|
74
|
+
generateTypeKey(structure: TypeStructure): string;
|
|
75
|
+
|
|
76
|
+
// ==================== Sendable转换相关 ====================
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 生成Sendable类型声明
|
|
80
|
+
* 将普通类型转换为Sendable兼容的类型声明
|
|
81
|
+
*
|
|
82
|
+
* @param structure 类型结构
|
|
83
|
+
* @returns Sendable类型声明字符串
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* // 基础类型:string -> string
|
|
87
|
+
* // 数组:Array<User> -> collections.Array<SendableUser>
|
|
88
|
+
* // 自定义类:User -> SendableUser(如果启用了generateSendable)
|
|
89
|
+
*/
|
|
90
|
+
generateSendableTypeDeclaration(structure: TypeStructure): string;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 生成属性转换代码
|
|
94
|
+
* 用于生成toSendable/toOrigin方法中的属性转换逻辑
|
|
95
|
+
*
|
|
96
|
+
* @param structure 类型结构
|
|
97
|
+
* @param sourceValue 源值表达式(如"this.name")
|
|
98
|
+
* @param direction 转换方向
|
|
99
|
+
* @returns 转换后的代码表达式
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* // 数组转换(toSendable):
|
|
103
|
+
* // sourceValue="this.users" -> "new collections.Array(...this.users)"
|
|
104
|
+
* // 数组转换(toOrigin):
|
|
105
|
+
* // sourceValue="this.users" -> "new Array(...this.users)"
|
|
106
|
+
* // 基础类型:
|
|
107
|
+
* // sourceValue="this.name" -> "this.name"(直接传递)
|
|
108
|
+
*/
|
|
109
|
+
generatePropertyConversion(structure: TypeStructure, sourceValue: string, direction: ConversionDirection): string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 类型上下文
|
|
114
|
+
* 贯穿整个处理流程
|
|
115
|
+
*/
|
|
116
|
+
export interface TypeContext {
|
|
117
|
+
/** 当前泛型参数 */
|
|
118
|
+
genericParams: string[];
|
|
119
|
+
|
|
120
|
+
/** 递归深度 */
|
|
121
|
+
depth: number;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 转换方向枚举
|
|
126
|
+
*/
|
|
127
|
+
export enum ConversionDirection {
|
|
128
|
+
/** 普通类型 -> Sendable类型 (toSendable) */
|
|
129
|
+
TO_SENDABLE = 'TO_SENDABLE',
|
|
130
|
+
|
|
131
|
+
/** Sendable类型 -> 普通类型 (toOrigin) */
|
|
132
|
+
TO_ORIGIN = 'TO_ORIGIN'
|
|
133
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
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 { TypeNode, SyntaxKind } from 'ts-morph';
|
|
17
|
+
import { PropertyKind, TypeStructure, SerializerMetadata } from '../Types';
|
|
18
|
+
import { BaseTypeHandler } from './BaseTypeHandler';
|
|
19
|
+
import { ITypeHandler } from './ITypeHandler';
|
|
20
|
+
|
|
21
|
+
abstract class PrimitiveHandler extends BaseTypeHandler implements ITypeHandler {
|
|
22
|
+
abstract readonly name: string;
|
|
23
|
+
abstract readonly kind: PropertyKind;
|
|
24
|
+
abstract readonly syntaxKind: SyntaxKind;
|
|
25
|
+
|
|
26
|
+
readonly priority = 100; // 基础类型高优先级
|
|
27
|
+
|
|
28
|
+
// ==================== 阶段1: 类型识别 ====================
|
|
29
|
+
|
|
30
|
+
matches(typeNode: TypeNode): boolean {
|
|
31
|
+
return typeNode.getKind() === this.syntaxKind;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ==================== 阶段2: 类型解析 ====================
|
|
35
|
+
|
|
36
|
+
parse(typeNode: TypeNode): TypeStructure {
|
|
37
|
+
return {
|
|
38
|
+
kind: this.kind,
|
|
39
|
+
depth: 0,
|
|
40
|
+
sourceText: typeNode.getText(),
|
|
41
|
+
args: [], // 基础类型没有泛型参数
|
|
42
|
+
dependencies: [] // 基础类型不需要依赖其他类型
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getSerializerMetadata(structure: TypeStructure, withParam?: string): SerializerMetadata {
|
|
47
|
+
const serializerName = this.getSerializerName();
|
|
48
|
+
const defaultInstantiation = this.generateInstantiation(); // 基础类型使用单例
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
name: serializerName,
|
|
52
|
+
typeDeclaration: serializerName,
|
|
53
|
+
instantiationTemplate: this.applyWithParam(withParam, defaultInstantiation, structure),
|
|
54
|
+
encodeMethod: `encode${this.getTypeName()}Element`,
|
|
55
|
+
decodeMethod: `decode${this.getTypeName()}`,
|
|
56
|
+
decoderType: `${structure.sourceText} | undefined`,
|
|
57
|
+
needsTypeAssertion: false
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ==================== 阶段4: 代码生成 ====================
|
|
62
|
+
|
|
63
|
+
generateInstantiation(): string {
|
|
64
|
+
const serializerName = this.getSerializerName();
|
|
65
|
+
return `${serializerName}.INSTANCE`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
generateTypeDeclaration(): string {
|
|
69
|
+
return this.getSerializerName();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
generateTypeKey(structure: TypeStructure): string {
|
|
73
|
+
// 类型键为字符串形式
|
|
74
|
+
return `'${structure.sourceText}'`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ==================== Sendable转换 ====================
|
|
78
|
+
|
|
79
|
+
generateSendableTypeDeclaration(structure: TypeStructure): string {
|
|
80
|
+
// 基础类型在Sendable中不需要转换,直接返回原类型
|
|
81
|
+
return structure.sourceText;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
generatePropertyConversion(_structure: TypeStructure, sourceValue: string): string {
|
|
85
|
+
// 基础类型在两个方向都直接传递,不需要转换
|
|
86
|
+
return sourceValue;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
class StringHandler extends PrimitiveHandler {
|
|
91
|
+
readonly name = 'StringHandler';
|
|
92
|
+
readonly kind = PropertyKind.STRING;
|
|
93
|
+
readonly syntaxKind = SyntaxKind.StringKeyword;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
class NumberHandler extends PrimitiveHandler {
|
|
97
|
+
readonly name = 'NumberHandler';
|
|
98
|
+
readonly kind = PropertyKind.NUMBER;
|
|
99
|
+
readonly syntaxKind = SyntaxKind.NumberKeyword;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
class BooleanHandler extends PrimitiveHandler {
|
|
103
|
+
readonly name = 'BooleanHandler';
|
|
104
|
+
readonly kind = PropertyKind.BOOLEAN;
|
|
105
|
+
readonly syntaxKind = SyntaxKind.BooleanKeyword;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
class BigintHandler extends PrimitiveHandler {
|
|
109
|
+
readonly name = 'BigintHandler';
|
|
110
|
+
readonly kind = PropertyKind.BIGINT;
|
|
111
|
+
readonly syntaxKind = SyntaxKind.BigIntKeyword;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
class NullHandler extends PrimitiveHandler {
|
|
115
|
+
readonly name = 'NullHandler';
|
|
116
|
+
readonly kind = PropertyKind.NULL;
|
|
117
|
+
readonly syntaxKind = SyntaxKind.NullKeyword;
|
|
118
|
+
|
|
119
|
+
// Override matches: null类型的节点是LiteralType
|
|
120
|
+
matches(typeNode: TypeNode): boolean {
|
|
121
|
+
// 检查是否是字面量类型节点
|
|
122
|
+
if (typeNode.getKind() === SyntaxKind.LiteralType) {
|
|
123
|
+
const literal = typeNode.asKindOrThrow(SyntaxKind.LiteralType);
|
|
124
|
+
const literalValue = literal.getLiteral();
|
|
125
|
+
return literalValue.getKind() === SyntaxKind.NullKeyword;
|
|
126
|
+
}
|
|
127
|
+
// 兼容直接的NullKeyword节点
|
|
128
|
+
return typeNode.getKind() === SyntaxKind.NullKeyword;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
class UndefinedHandler extends PrimitiveHandler {
|
|
133
|
+
readonly name = 'UndefinedHandler';
|
|
134
|
+
readonly kind = PropertyKind.UNDEFINED;
|
|
135
|
+
readonly syntaxKind = SyntaxKind.UndefinedKeyword;
|
|
136
|
+
|
|
137
|
+
// Override matches: undefined也可能以字面量形式出现
|
|
138
|
+
matches(typeNode: TypeNode): boolean {
|
|
139
|
+
// 检查是否是字面量类型节点
|
|
140
|
+
if (typeNode.getKind() === SyntaxKind.LiteralType) {
|
|
141
|
+
const literal = typeNode.asKindOrThrow(SyntaxKind.LiteralType);
|
|
142
|
+
const literalValue = literal.getLiteral();
|
|
143
|
+
return literalValue.getKind() === SyntaxKind.UndefinedKeyword;
|
|
144
|
+
}
|
|
145
|
+
// 兼容直接的UndefinedKeyword节点
|
|
146
|
+
return typeNode.getKind() === SyntaxKind.UndefinedKeyword;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function createPrimitiveHandlers(): ITypeHandler[] {
|
|
151
|
+
return [
|
|
152
|
+
new StringHandler(),
|
|
153
|
+
new NumberHandler(),
|
|
154
|
+
new BooleanHandler(),
|
|
155
|
+
new BigintHandler(),
|
|
156
|
+
new NullHandler(),
|
|
157
|
+
new UndefinedHandler()
|
|
158
|
+
];
|
|
159
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
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 { TypeNode, SyntaxKind, TupleTypeNode } from 'ts-morph';
|
|
17
|
+
import { PropertyKind, TypeStructure, SerializerMetadata, TypeDependency } from '../Types';
|
|
18
|
+
import { ConversionDirection, ITypeHandler, TypeContext } from './ITypeHandler';
|
|
19
|
+
import { BaseTypeHandler } from './BaseTypeHandler';
|
|
20
|
+
import { CustomError, ErrorCodes } from '../utils/CustomError';
|
|
21
|
+
import { Logger } from '../logger/Logger';
|
|
22
|
+
|
|
23
|
+
class TupleHandler extends BaseTypeHandler implements ITypeHandler {
|
|
24
|
+
readonly name = 'TupleHandler';
|
|
25
|
+
readonly kind = PropertyKind.TUPLE;
|
|
26
|
+
readonly priority = 95;
|
|
27
|
+
|
|
28
|
+
// ==================== 阶段1: 类型识别 ====================
|
|
29
|
+
|
|
30
|
+
matches(typeNode: TypeNode): boolean {
|
|
31
|
+
return typeNode.getKind() === SyntaxKind.TupleType;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ==================== 阶段2: 类型解析 ====================
|
|
35
|
+
|
|
36
|
+
parse(typeNode: TypeNode, context: TypeContext): TypeStructure {
|
|
37
|
+
const tupleType = typeNode as TupleTypeNode;
|
|
38
|
+
const elementTypes = tupleType.getElements();
|
|
39
|
+
|
|
40
|
+
// 解析所有元素类型
|
|
41
|
+
const elements: TypeStructure[] = [];
|
|
42
|
+
const allDependencies: TypeDependency[] = [];
|
|
43
|
+
let maxDepth = 0;
|
|
44
|
+
|
|
45
|
+
for (const elementType of elementTypes) {
|
|
46
|
+
const { TypeHandlerRegistry } = require('./TypeHandlerRegistry');
|
|
47
|
+
const elementStructure = TypeHandlerRegistry.getInstance().parseType(elementType, {
|
|
48
|
+
...context,
|
|
49
|
+
depth: context.depth + 1
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
Logger.info(`tuple element type: ${elementType.getText()}, ${elementStructure.kind}`);
|
|
53
|
+
elements.push(elementStructure);
|
|
54
|
+
allDependencies.push(...elementStructure.dependencies);
|
|
55
|
+
maxDepth = Math.max(maxDepth, elementStructure.depth);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
kind: this.kind,
|
|
60
|
+
depth: maxDepth + 1,
|
|
61
|
+
sourceText: typeNode.getText(),
|
|
62
|
+
args: elements,
|
|
63
|
+
dependencies: allDependencies
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ==================== 阶段3: 序列化器配置 ====================
|
|
68
|
+
|
|
69
|
+
getSerializerMetadata(structure: TypeStructure, withParam?: string): SerializerMetadata {
|
|
70
|
+
const serializerName = this.getSerializerName();
|
|
71
|
+
const defaultInstantiation = this.generateInstantiation(structure);
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
name: serializerName,
|
|
75
|
+
typeDeclaration: this.generateTypeDeclaration(structure),
|
|
76
|
+
instantiationTemplate: this.applyWithParam(withParam, defaultInstantiation, structure),
|
|
77
|
+
encodeMethod: 'encodeSerializableElement',
|
|
78
|
+
decodeMethod: 'deserialize',
|
|
79
|
+
decoderType: `${structure.sourceText} | undefined`,
|
|
80
|
+
needsTypeAssertion: false
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ==================== 阶段4: 代码生成 ====================
|
|
85
|
+
|
|
86
|
+
generateInstantiation(structure: TypeStructure): string {
|
|
87
|
+
|
|
88
|
+
const serializerName = this.getSerializerName();
|
|
89
|
+
|
|
90
|
+
// 为每个元组元素生成序列化器
|
|
91
|
+
const elementSerializers = structure.args.map(element => {
|
|
92
|
+
const { TypeHandlerRegistry } = require('./TypeHandlerRegistry');
|
|
93
|
+
const handler = TypeHandlerRegistry.getInstance().getHandlerForKind(element.kind);
|
|
94
|
+
return handler.generateInstantiation(element);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return `new ${serializerName}([${elementSerializers.join(', ')}])`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
generateTypeDeclaration(structure: TypeStructure): string {
|
|
101
|
+
const serializerName = this.getSerializerName();
|
|
102
|
+
return `${serializerName}<${structure.sourceText}>`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
generateTypeKey(structure: TypeStructure): string {
|
|
106
|
+
|
|
107
|
+
const elementKeys = structure.args.map(element => {
|
|
108
|
+
const { TypeHandlerRegistry } = require('./TypeHandlerRegistry');
|
|
109
|
+
const handler = TypeHandlerRegistry.getInstance().getHandlerForKind(element.kind);
|
|
110
|
+
return handler.generateTypeKey(element);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return `[${elementKeys.join(', ')}]`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
protected getSerializerName(): string {
|
|
117
|
+
return 'TupleSerializer';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ==================== Sendable转换 ====================
|
|
121
|
+
|
|
122
|
+
generateSendableTypeDeclaration(structure: TypeStructure): string {
|
|
123
|
+
|
|
124
|
+
const registry = require('./TypeHandlerRegistry').TypeHandlerRegistry.getInstance();
|
|
125
|
+
const sendableElementTypes = structure.args.map(element => {
|
|
126
|
+
const handler = registry.getHandlerForKind(element.kind);
|
|
127
|
+
if (!handler) {
|
|
128
|
+
throw new CustomError(`TupleHandler: no handler for element type: ${element.kind}`, ErrorCodes.HANDLER_NOT_FOUND);
|
|
129
|
+
}
|
|
130
|
+
return handler.generateSendableTypeDeclaration(element);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return `[${sendableElementTypes.join(', ')}]`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
generatePropertyConversion(structure: TypeStructure, sourceValue: string, direction: ConversionDirection): string {
|
|
137
|
+
// 元组类型的转换无法在编译时确定具体类型,直接传递
|
|
138
|
+
// 实际转换由运行时的具体类型决定
|
|
139
|
+
return sourceValue;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function createTupleTypeHandlers(): ITypeHandler {
|
|
144
|
+
return new TupleHandler();
|
|
145
|
+
}
|