@hadss/turbo-trans-json-plugin 1.0.0-rc.0 → 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/README.md +1 -1
- package/dist/core/Types.d.ts +7 -0
- package/dist/core/Types.js +7 -1
- package/dist/core/analyzers/ClassAnalyzer.d.ts +15 -0
- package/dist/core/analyzers/ClassAnalyzer.js +200 -120
- package/dist/core/analyzers/CustomTypeAnalyzer.d.ts +3 -0
- package/dist/core/analyzers/CustomTypeAnalyzer.js +65 -60
- package/dist/core/constants/DecoratorConstants.d.ts +1 -0
- package/dist/core/constants/DecoratorConstants.js +3 -1
- package/dist/core/handlers/CustomClassHandler.js +0 -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/CodeGenerationService.js +1 -1
- package/dist/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.d.ts +0 -1
- package/dist/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.js +0 -20
- package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.d.ts +4 -4
- package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.js +26 -45
- 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 +20 -15
- 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 +24 -2
- package/dist/core/utils/DeepCopyUtil.js +4 -2
- package/dist/core/utils/GenericTypeSubstitutionUtil.d.ts +1 -0
- package/dist/core/utils/GenericTypeSubstitutionUtil.js +27 -1
- package/dist/core/utils/SerializationPathUtil.d.ts +1 -1
- package/dist/core/utils/TsMorphUtil.js +6 -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 +97 -89
- package/src/core/analyzers/ClassAnalyzer.ts +358 -197
- package/src/core/analyzers/CustomTypeAnalyzer.ts +145 -74
- package/src/core/constants/DecoratorConstants.ts +7 -5
- package/src/core/constants/PathConstants.ts +7 -7
- package/src/core/constants/StringConstants.ts +95 -97
- package/src/core/handlers/BaseTypeHandler.ts +11 -2
- package/src/core/handlers/CustomClassHandler.ts +4 -7
- 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 +3 -2
- package/src/core/handlers/UnionTypeHandler.ts +8 -7
- package/src/core/import-rewrite/services/BuildProfileUpdater.ts +7 -5
- package/src/core/import-rewrite/services/ImportRewriteService.ts +1 -3
- 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 +3 -2
- package/src/core/services/CodeGenerationEngine.ts +42 -42
- package/src/core/services/CodeGenerationService/CodeGenerationService.ts +1 -2
- package/src/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.ts +0 -29
- package/src/core/services/CodeGenerationService/generators/OriginalClassGenerator.ts +31 -64
- package/src/core/services/CodeGenerationService/generators/SendableClassGenerator.ts +261 -170
- package/src/core/services/CodeGenerationService/generators/SerializerGenerator.ts +26 -19
- 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 +43 -10
- package/src/core/utils/ConfigManager.ts +2 -1
- package/src/core/utils/DeepCopyUtil.ts +4 -2
- package/src/core/utils/GenericTypeSubstitutionUtil.ts +45 -2
- package/src/core/utils/SerializationPathUtil.ts +7 -6
- package/src/core/utils/TsMorphUtil.ts +9 -2
- 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 -4
- package/src/json-plugin/tasks/CleanTask.ts +7 -7
- package/src/json-plugin/tasks/WatchTask.ts +20 -18
- package/template/SerializerPerformanceTemplate.hbs +14 -4
- package/template/SerializerStrictTemplate.hbs +9 -1
- package/template/SerializerTemplate.hbs +71 -46
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
import {
|
|
17
17
|
ClassDeclaration,
|
|
18
18
|
EnumDeclaration,
|
|
19
|
+
EnumMember,
|
|
20
|
+
ImportDeclaration,
|
|
19
21
|
InterfaceDeclaration,
|
|
20
|
-
Project,
|
|
21
22
|
SourceFile,
|
|
22
23
|
TypeAliasDeclaration
|
|
23
24
|
} from 'ts-morph';
|
|
@@ -39,7 +40,8 @@ export class CustomTypeAnalyzer {
|
|
|
39
40
|
/** 类型查找缓存 <名称+路径,依赖地址> */
|
|
40
41
|
private searchCache = new Map<string, TypeDependency | null>();
|
|
41
42
|
|
|
42
|
-
private constructor() {
|
|
43
|
+
private constructor() {
|
|
44
|
+
}
|
|
43
45
|
|
|
44
46
|
public static getInstance(): CustomTypeAnalyzer {
|
|
45
47
|
return this.INSTANCE;
|
|
@@ -97,7 +99,8 @@ export class CustomTypeAnalyzer {
|
|
|
97
99
|
return null;
|
|
98
100
|
}
|
|
99
101
|
|
|
100
|
-
public findClassDeclFromClassName(className: string,
|
|
102
|
+
public findClassDeclFromClassName(className: string,
|
|
103
|
+
sourceFile: SourceFile): ClassDeclaration | InterfaceDeclaration | null {
|
|
101
104
|
const res = this.findDefinition(className, sourceFile);
|
|
102
105
|
if (res && res.typeKind === TypeKind.CLASS) {
|
|
103
106
|
return (res.details as ClassDetails).classDecl;
|
|
@@ -135,43 +138,72 @@ export class CustomTypeAnalyzer {
|
|
|
135
138
|
for (const importDecl of imports) {
|
|
136
139
|
// TODO:当前实现只处理命名导入,default导入和命名空间导入暂未支持
|
|
137
140
|
const namedImports = importDecl.getNamedImports();
|
|
141
|
+
const matchedImport = namedImports.find(ni => ni.getName() === targetName);
|
|
142
|
+
|
|
143
|
+
if (!matchedImport) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
|
|
138
147
|
const specifierValue = importDecl.getModuleSpecifierValue();
|
|
148
|
+
const result = this.processImportMatch(importDecl, targetName, sourceFile, specifierValue);
|
|
139
149
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const importName = namedImport.getName();
|
|
143
|
-
if (importName === targetName) {
|
|
144
|
-
// 找到了导入的类型,现在需要解析文件路径
|
|
145
|
-
const moduleSpecifier = importDecl.getModuleSpecifierValue();
|
|
146
|
-
const resolvedPath = this.resolveImportPath(moduleSpecifier, sourceFile);
|
|
147
|
-
|
|
148
|
-
if (resolvedPath && SerializationPathUtil.exist(resolvedPath)) {
|
|
149
|
-
// 加载外部文件并查找类型定义
|
|
150
|
-
const externalSourceFile = this.getOrLoadSourceFile(resolvedPath);
|
|
151
|
-
if (externalSourceFile) {
|
|
152
|
-
const typeDetail = this.searchInSourceFile(targetName, externalSourceFile);
|
|
153
|
-
if (typeDetail) {
|
|
154
|
-
return {
|
|
155
|
-
typeName: targetName,
|
|
156
|
-
typeKind: typeDetail.kind,
|
|
157
|
-
importPath: specifierValue,
|
|
158
|
-
source: {
|
|
159
|
-
type: 'imported',
|
|
160
|
-
sourceFilePath: externalSourceFile.getFilePath(),
|
|
161
|
-
originalImport: specifierValue
|
|
162
|
-
},
|
|
163
|
-
details: typeDetail
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
150
|
+
if (result) {
|
|
151
|
+
return result;
|
|
169
152
|
}
|
|
170
153
|
}
|
|
171
154
|
|
|
172
155
|
return null;
|
|
173
156
|
}
|
|
174
157
|
|
|
158
|
+
/**
|
|
159
|
+
* 处理导入匹配,解析外部文件中的类型定义
|
|
160
|
+
*
|
|
161
|
+
* 处理流程:
|
|
162
|
+
* 1. 解析模块路径 → 路径无效则返回 null
|
|
163
|
+
* 2. 加载外部源文件 → 加载失败则返回 null
|
|
164
|
+
* 3. 在外部文件中查找类型 → 未找到则返回 null
|
|
165
|
+
* 4. 构建并返回类型依赖信息
|
|
166
|
+
*/
|
|
167
|
+
private processImportMatch(
|
|
168
|
+
importDecl: ImportDeclaration,
|
|
169
|
+
targetName: string,
|
|
170
|
+
sourceFile: SourceFile,
|
|
171
|
+
specifierValue: string
|
|
172
|
+
): TypeDependency | null {
|
|
173
|
+
const moduleSpecifier = importDecl.getModuleSpecifierValue();
|
|
174
|
+
const resolvedPath = this.resolveImportPath(moduleSpecifier, sourceFile);
|
|
175
|
+
|
|
176
|
+
// 条件1:路径解析失败或文件不存在,无法继续处理
|
|
177
|
+
if (!resolvedPath || !SerializationPathUtil.exist(resolvedPath)) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// 条件2:无法加载外部源文件(文件损坏或格式不支持)
|
|
182
|
+
const externalSourceFile = this.getOrLoadSourceFile(resolvedPath);
|
|
183
|
+
if (!externalSourceFile) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// 条件3:在外部文件中未找到目标类型定义
|
|
188
|
+
const typeDetail = this.searchInSourceFile(targetName, externalSourceFile);
|
|
189
|
+
if (!typeDetail) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// 所有条件通过,构建类型依赖结果
|
|
194
|
+
return {
|
|
195
|
+
typeName: targetName,
|
|
196
|
+
typeKind: typeDetail.kind,
|
|
197
|
+
importPath: specifierValue,
|
|
198
|
+
source: {
|
|
199
|
+
type: 'imported',
|
|
200
|
+
sourceFilePath: externalSourceFile.getFilePath(),
|
|
201
|
+
originalImport: specifierValue
|
|
202
|
+
},
|
|
203
|
+
details: typeDetail
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
175
207
|
private findInCrossModule(targetName: string, sourceFile: SourceFile): TypeDependency | null {
|
|
176
208
|
// TODO: 跨模块暂未实现
|
|
177
209
|
return null;
|
|
@@ -215,53 +247,25 @@ export class CustomTypeAnalyzer {
|
|
|
215
247
|
|
|
216
248
|
private parseEnumDetails(enumDecl: EnumDeclaration): EnumDetails {
|
|
217
249
|
const members: EnumMemberInfo[] = [];
|
|
218
|
-
let valueType: 'string' | 'number' = 'number';
|
|
219
|
-
let numericValue = 0;
|
|
250
|
+
let valueType: 'string' | 'number' = 'number';
|
|
251
|
+
let numericValue = 0;
|
|
220
252
|
|
|
221
253
|
const enumMembers = enumDecl.getMembers();
|
|
222
254
|
for (const member of enumMembers) {
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (initText.startsWith('"') && initText.endsWith('"')) {
|
|
234
|
-
// 字符串枚举
|
|
235
|
-
memberValue = initText.slice(1, -1); // 去掉引号
|
|
236
|
-
literalValue = initText; // 保留引号
|
|
237
|
-
valueType = 'string';
|
|
238
|
-
} else if (initText.startsWith("'") && initText.endsWith("'")) {
|
|
239
|
-
// 字符串枚举(单引号)
|
|
240
|
-
memberValue = initText.slice(1, -1); // 去掉引号
|
|
241
|
-
literalValue = `"${memberValue}"`; // 统一使用双引号
|
|
242
|
-
valueType = 'string';
|
|
243
|
-
} else {
|
|
244
|
-
// 数值枚举
|
|
245
|
-
const numValue = parseInt(initText, 10);
|
|
246
|
-
if (!isNaN(numValue)) {
|
|
247
|
-
memberValue = numValue;
|
|
248
|
-
literalValue = numValue.toString();
|
|
249
|
-
numericValue = numValue + 1; // 更新下一个自动值
|
|
250
|
-
} else {
|
|
251
|
-
// 复杂表达式,暂时当作字符串处理
|
|
252
|
-
memberValue = initText;
|
|
253
|
-
literalValue = `"${initText}"`;
|
|
254
|
-
valueType = 'string';
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
} else {
|
|
258
|
-
// 没有显式初始值,使用自动递增的数值
|
|
259
|
-
memberValue = numericValue;
|
|
260
|
-
literalValue = numericValue.toString();
|
|
261
|
-
numericValue++;
|
|
255
|
+
const {
|
|
256
|
+
memberValue,
|
|
257
|
+
literalValue,
|
|
258
|
+
type,
|
|
259
|
+
nextValue
|
|
260
|
+
} = this.parseEnumMember(member, numericValue);
|
|
261
|
+
numericValue = nextValue;
|
|
262
|
+
|
|
263
|
+
if (type === 'string') {
|
|
264
|
+
valueType = 'string';
|
|
262
265
|
}
|
|
266
|
+
|
|
263
267
|
members.push({
|
|
264
|
-
name:
|
|
268
|
+
name: member.getName(),
|
|
265
269
|
value: memberValue,
|
|
266
270
|
literalValue
|
|
267
271
|
});
|
|
@@ -269,6 +273,73 @@ export class CustomTypeAnalyzer {
|
|
|
269
273
|
return { kind: TypeKind.ENUM, valueType, members };
|
|
270
274
|
}
|
|
271
275
|
|
|
276
|
+
/**
|
|
277
|
+
* 解析枚举成员的值信息
|
|
278
|
+
*
|
|
279
|
+
* 处理四种情况(互斥,按优先级顺序判断):
|
|
280
|
+
* 1. 无初始化器 → 使用自增数字值
|
|
281
|
+
* 2. 双引号字符串 "value" → 字符串类型
|
|
282
|
+
* 3. 单引号字符串 'value' → 字符串类型(转换为双引号)
|
|
283
|
+
* 4. 数字字面量 → 数字类型,后续成员从此值+1继续自增
|
|
284
|
+
* 5. 其他表达式 → 作为字符串处理(兜底情况)
|
|
285
|
+
*
|
|
286
|
+
* @param member 枚举成员节点
|
|
287
|
+
* @param numericValue 当前自增数字值
|
|
288
|
+
* @returns 成员值信息,包含实际值、字面量表示、类型和下一个自增值
|
|
289
|
+
*/
|
|
290
|
+
private parseEnumMember(member: EnumMember, numericValue: number): {
|
|
291
|
+
memberValue: string | number;
|
|
292
|
+
literalValue: string;
|
|
293
|
+
type: 'string' | 'number';
|
|
294
|
+
nextValue: number
|
|
295
|
+
} {
|
|
296
|
+
const initializer = member.getInitializer();
|
|
297
|
+
|
|
298
|
+
// 情况1:无初始化器,使用自增数字值(如 enum { A, B, C } 中的 A=0, B=1, C=2)
|
|
299
|
+
if (!initializer) {
|
|
300
|
+
return {
|
|
301
|
+
memberValue: numericValue,
|
|
302
|
+
literalValue: numericValue.toString(),
|
|
303
|
+
type: 'number',
|
|
304
|
+
nextValue: numericValue + 1
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const initText = initializer.getText().trim();
|
|
309
|
+
|
|
310
|
+
// 情况2:双引号字符串(如 enum { A = "hello" })
|
|
311
|
+
if (initText.startsWith('"') && initText.endsWith('"')) {
|
|
312
|
+
return this.createStringEnumResult(initText.slice(1, -1), initText, numericValue);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// 情况3:单引号字符串(如 enum { A = 'hello' }),转换为双引号格式
|
|
316
|
+
if (initText.startsWith("'") && initText.endsWith("'")) {
|
|
317
|
+
const val = initText.slice(1, -1);
|
|
318
|
+
return this.createStringEnumResult(val, `"${val}"`, numericValue);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// 情况4:数字字面量(如 enum { A = 10 }),后续成员从 11 开始自增
|
|
322
|
+
const numValue = parseInt(initText, 10);
|
|
323
|
+
if (!isNaN(numValue)) {
|
|
324
|
+
return { memberValue: numValue, literalValue: numValue.toString(), type: 'number', nextValue: numValue + 1 };
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// 情况5:其他表达式(如常量引用),作为字符串处理
|
|
328
|
+
return this.createStringEnumResult(initText, `"${initText}"`, numericValue);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* 创建字符串类型枚举成员结果
|
|
333
|
+
* 注意:字符串枚举不影响自增值,nextValue 保持不变
|
|
334
|
+
*/
|
|
335
|
+
private createStringEnumResult(
|
|
336
|
+
memberValue: string,
|
|
337
|
+
literalValue: string,
|
|
338
|
+
numericValue: number
|
|
339
|
+
): { memberValue: string; literalValue: string; type: 'string'; nextValue: number } {
|
|
340
|
+
return { memberValue, literalValue, type: 'string', nextValue: numericValue };
|
|
341
|
+
}
|
|
342
|
+
|
|
272
343
|
private parseClassDetails(classDecl: ClassDeclaration): ClassDetails {
|
|
273
344
|
return {
|
|
274
345
|
kind: TypeKind.CLASS,
|
|
@@ -18,10 +18,12 @@
|
|
|
18
18
|
*/
|
|
19
19
|
export class DecoratorConstants {
|
|
20
20
|
// TSerialization装饰器
|
|
21
|
-
static readonly SERIALIZABLE = 'Serializable'
|
|
22
|
-
static readonly SERIAL_NAME = 'SerialName'
|
|
23
|
-
static readonly REQUIRED = 'Required'
|
|
24
|
-
static readonly TRANSIENT = 'Transient'
|
|
21
|
+
static readonly SERIALIZABLE = 'Serializable';
|
|
22
|
+
static readonly SERIAL_NAME = 'SerialName';
|
|
23
|
+
static readonly REQUIRED = 'Required';
|
|
24
|
+
static readonly TRANSIENT = 'Transient';
|
|
25
|
+
static readonly PLAIN_VALUE = 'PlainValue';
|
|
25
26
|
|
|
26
|
-
static readonly SERIAL_DECORATORS = [this.SERIALIZABLE, this.SERIAL_NAME, this.REQUIRED, this.TRANSIENT
|
|
27
|
+
static readonly SERIAL_DECORATORS = [this.SERIALIZABLE, this.SERIAL_NAME, this.REQUIRED, this.TRANSIENT,
|
|
28
|
+
this.PLAIN_VALUE];
|
|
27
29
|
}
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
*/
|
|
19
19
|
export class PathConstants {
|
|
20
20
|
/** 默认源代码根目录 */
|
|
21
|
-
static readonly DEFAULT_SOURCE_ROOT = './src/main'
|
|
22
|
-
|
|
21
|
+
static readonly DEFAULT_SOURCE_ROOT = './src/main';
|
|
22
|
+
|
|
23
23
|
/** 生成代码根目录 */
|
|
24
|
-
static readonly GENERATED_ROOT = './src/generated'
|
|
25
|
-
|
|
24
|
+
static readonly GENERATED_ROOT = './src/generated';
|
|
25
|
+
|
|
26
26
|
/** 支持的文件扩展名 */
|
|
27
|
-
static readonly ETS_EXTENSIONS = '.ets'
|
|
28
|
-
|
|
27
|
+
static readonly ETS_EXTENSIONS = '.ets';
|
|
28
|
+
|
|
29
29
|
/** 默认扫描目录 */
|
|
30
|
-
static readonly DEFAULT_SCAN_DIRS = ['src/main/ets']
|
|
30
|
+
static readonly DEFAULT_SCAN_DIRS = ['src/main/ets'];
|
|
31
31
|
}
|
|
@@ -13,140 +13,138 @@
|
|
|
13
13
|
* limitations under the License.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import { PropertyKind } from '../Types';
|
|
17
|
-
|
|
18
16
|
/**
|
|
19
17
|
* 字符串常量统一管理
|
|
20
18
|
* 避免硬编码字符串散布在代码中
|
|
21
19
|
*/
|
|
22
20
|
export class StringConstants {
|
|
23
|
-
|
|
21
|
+
|
|
24
22
|
// ========== 基础类型字符串 ==========
|
|
25
|
-
static readonly TYPE_BOOLEAN = 'boolean'
|
|
26
|
-
static readonly TYPE_NUMBER = 'number'
|
|
27
|
-
static readonly TYPE_STRING = 'string'
|
|
28
|
-
static readonly TYPE_BIGINT = 'bigint'
|
|
29
|
-
static readonly TYPE_NULL = 'null'
|
|
30
|
-
static readonly TYPE_UNDEFINED = 'undefined'
|
|
31
|
-
static readonly TYPE_ARRAY = 'array'
|
|
32
|
-
static readonly TYPE_SET = 'set'
|
|
33
|
-
static readonly TYPE_MAP = 'map'
|
|
34
|
-
static readonly TYPE_UNION = 'union'
|
|
35
|
-
static readonly TYPE_ENUM = 'enum'
|
|
23
|
+
static readonly TYPE_BOOLEAN = 'boolean';
|
|
24
|
+
static readonly TYPE_NUMBER = 'number';
|
|
25
|
+
static readonly TYPE_STRING = 'string';
|
|
26
|
+
static readonly TYPE_BIGINT = 'bigint';
|
|
27
|
+
static readonly TYPE_NULL = 'null';
|
|
28
|
+
static readonly TYPE_UNDEFINED = 'undefined';
|
|
29
|
+
static readonly TYPE_ARRAY = 'array';
|
|
30
|
+
static readonly TYPE_SET = 'set';
|
|
31
|
+
static readonly TYPE_MAP = 'map';
|
|
32
|
+
static readonly TYPE_UNION = 'union';
|
|
33
|
+
static readonly TYPE_ENUM = 'enum';
|
|
36
34
|
|
|
37
35
|
// ========== 序列化器名称 ==========
|
|
38
36
|
// 基础类型序列化器(单例INSTANCE模式)
|
|
39
|
-
static readonly BOOLEAN_SERIALIZER = 'BooleanSerializer'
|
|
40
|
-
static readonly NUMBER_SERIALIZER = 'NumberSerializer'
|
|
41
|
-
static readonly STRING_SERIALIZER = 'StringSerializer'
|
|
42
|
-
static readonly BIGINT_SERIALIZER = 'BigintSerializer'
|
|
43
|
-
|
|
37
|
+
static readonly BOOLEAN_SERIALIZER = 'BooleanSerializer';
|
|
38
|
+
static readonly NUMBER_SERIALIZER = 'NumberSerializer';
|
|
39
|
+
static readonly STRING_SERIALIZER = 'StringSerializer';
|
|
40
|
+
static readonly BIGINT_SERIALIZER = 'BigintSerializer';
|
|
41
|
+
|
|
44
42
|
// 特殊原始类型序列化器(单例INSTANCE模式)
|
|
45
|
-
static readonly NULL_SERIALIZER = 'NullSerializer'
|
|
46
|
-
static readonly UNDEFINED_SERIALIZER = 'UndefinedSerializer'
|
|
47
|
-
|
|
43
|
+
static readonly NULL_SERIALIZER = 'NullSerializer';
|
|
44
|
+
static readonly UNDEFINED_SERIALIZER = 'UndefinedSerializer';
|
|
45
|
+
|
|
48
46
|
// 集合类型序列化器(泛型构造器模式)
|
|
49
|
-
static readonly ARRAY_SERIALIZER = 'ArraySerializer'
|
|
50
|
-
static readonly COLLECTIONS_ARRAY_SERIALIZER = 'CollectionsArraySerializer'
|
|
51
|
-
static readonly MAP_SERIALIZER = 'MapSerializer'
|
|
52
|
-
static readonly COLLECTIONS_MAP_SERIALIZER = 'CollectionsMapSerializer'
|
|
53
|
-
static readonly SET_SERIALIZER = 'SetSerializer'
|
|
54
|
-
static readonly COLLECTIONS_SET_SERIALIZER = 'CollectionsSetSerializer'
|
|
55
|
-
static readonly RECORD_SERIALIZER = 'RecordSerializer'
|
|
47
|
+
static readonly ARRAY_SERIALIZER = 'ArraySerializer';
|
|
48
|
+
static readonly COLLECTIONS_ARRAY_SERIALIZER = 'CollectionsArraySerializer';
|
|
49
|
+
static readonly MAP_SERIALIZER = 'MapSerializer';
|
|
50
|
+
static readonly COLLECTIONS_MAP_SERIALIZER = 'CollectionsMapSerializer';
|
|
51
|
+
static readonly SET_SERIALIZER = 'SetSerializer';
|
|
52
|
+
static readonly COLLECTIONS_SET_SERIALIZER = 'CollectionsSetSerializer';
|
|
53
|
+
static readonly RECORD_SERIALIZER = 'RecordSerializer';
|
|
56
54
|
|
|
57
55
|
// 高级类型序列化器(特殊构造器模式)
|
|
58
|
-
static readonly UNION_TYPE_SERIALIZER = 'UnionTypeSerializer'
|
|
59
|
-
static readonly OPTIONAL_SERIALIZER = 'OptionalSerializer'
|
|
60
|
-
static readonly NULLABLE_SERIALIZER = 'NullableSerializer'
|
|
61
|
-
static readonly ENUM_SERIALIZER = 'EnumSerializer'
|
|
62
|
-
|
|
56
|
+
static readonly UNION_TYPE_SERIALIZER = 'UnionTypeSerializer';
|
|
57
|
+
static readonly OPTIONAL_SERIALIZER = 'OptionalSerializer';
|
|
58
|
+
static readonly NULLABLE_SERIALIZER = 'NullableSerializer';
|
|
59
|
+
static readonly ENUM_SERIALIZER = 'EnumSerializer';
|
|
60
|
+
|
|
63
61
|
// 通用序列化器
|
|
64
|
-
static readonly SERIALIZER = 'Serializer'
|
|
65
|
-
static readonly SERIALIZER_FACTORY = 'SerializerFactory'
|
|
62
|
+
static readonly SERIALIZER = 'Serializer';
|
|
63
|
+
static readonly SERIALIZER_FACTORY = 'SerializerFactory';
|
|
66
64
|
|
|
67
65
|
// ========== 编码/解码方法名 ==========
|
|
68
66
|
// 基础类型专用编码方法
|
|
69
|
-
static readonly ENCODE_BOOLEAN_ELEMENT = 'encodeBooleanElement'
|
|
70
|
-
static readonly ENCODE_NUMBER_ELEMENT = 'encodeNumberElement'
|
|
71
|
-
static readonly ENCODE_STRING_ELEMENT = 'encodeStringElement'
|
|
72
|
-
static readonly ENCODE_BIGINT_ELEMENT = 'encodeBigintElement'
|
|
73
|
-
|
|
67
|
+
static readonly ENCODE_BOOLEAN_ELEMENT = 'encodeBooleanElement';
|
|
68
|
+
static readonly ENCODE_NUMBER_ELEMENT = 'encodeNumberElement';
|
|
69
|
+
static readonly ENCODE_STRING_ELEMENT = 'encodeStringElement';
|
|
70
|
+
static readonly ENCODE_BIGINT_ELEMENT = 'encodeBigintElement';
|
|
71
|
+
|
|
74
72
|
// 特殊原始类型专用编码方法
|
|
75
|
-
static readonly ENCODE_NULL_ELEMENT = 'encodeNullElement'
|
|
76
|
-
static readonly ENCODE_UNDEFINED_ELEMENT = 'encodeUndefinedElement'
|
|
77
|
-
|
|
73
|
+
static readonly ENCODE_NULL_ELEMENT = 'encodeNullElement';
|
|
74
|
+
static readonly ENCODE_UNDEFINED_ELEMENT = 'encodeUndefinedElement';
|
|
75
|
+
|
|
78
76
|
// 通用编码方法
|
|
79
|
-
static readonly ENCODE_SERIALIZABLE_ELEMENT = 'encodeSerializableElement'
|
|
77
|
+
static readonly ENCODE_SERIALIZABLE_ELEMENT = 'encodeSerializableElement';
|
|
80
78
|
|
|
81
79
|
// 基础类型专用解码方法
|
|
82
|
-
static readonly DECODE_BOOLEAN = 'decodeBoolean'
|
|
83
|
-
static readonly DECODE_NUMBER = 'decodeNumber'
|
|
84
|
-
static readonly DECODE_STRING = 'decodeString'
|
|
85
|
-
static readonly DECODE_BIGINT = 'decodeBigint'
|
|
86
|
-
|
|
80
|
+
static readonly DECODE_BOOLEAN = 'decodeBoolean';
|
|
81
|
+
static readonly DECODE_NUMBER = 'decodeNumber';
|
|
82
|
+
static readonly DECODE_STRING = 'decodeString';
|
|
83
|
+
static readonly DECODE_BIGINT = 'decodeBigint';
|
|
84
|
+
|
|
87
85
|
// 特殊原始类型专用解码方法
|
|
88
|
-
static readonly DECODE_NULL = 'decodeNull'
|
|
89
|
-
static readonly DECODE_UNDEFINED = 'decodeUndefined'
|
|
90
|
-
|
|
86
|
+
static readonly DECODE_NULL = 'decodeNull';
|
|
87
|
+
static readonly DECODE_UNDEFINED = 'decodeUndefined';
|
|
88
|
+
|
|
91
89
|
// 通用解码方法
|
|
92
|
-
static readonly DESERIALIZABLE = 'deserialize'
|
|
90
|
+
static readonly DESERIALIZABLE = 'deserialize';
|
|
93
91
|
|
|
94
92
|
// ========== 导入模块相关 ==========
|
|
95
|
-
static readonly IMPORT_BUILD_CLASS_SERIAL_DESCRIPTOR = 'buildClassSerialDescriptor'
|
|
96
|
-
static readonly IMPORT_DECODER = 'Decoder'
|
|
97
|
-
static readonly IMPORT_ENCODER = 'Encoder'
|
|
98
|
-
static readonly IMPORT_SERIAL_DESCRIPTOR = 'SerialDescriptor'
|
|
99
|
-
static readonly IMPORT_SERIALIZER = 'Serializer'
|
|
93
|
+
static readonly IMPORT_BUILD_CLASS_SERIAL_DESCRIPTOR = 'buildClassSerialDescriptor';
|
|
94
|
+
static readonly IMPORT_DECODER = 'Decoder';
|
|
95
|
+
static readonly IMPORT_ENCODER = 'Encoder';
|
|
96
|
+
static readonly IMPORT_SERIAL_DESCRIPTOR = 'SerialDescriptor';
|
|
97
|
+
static readonly IMPORT_SERIALIZER = 'Serializer';
|
|
100
98
|
|
|
101
|
-
static readonly IMPORT_TJSON = 'TJSON'
|
|
102
|
-
static readonly IMPORT_IT_SERIALIZABLE = 'ITSerializable'
|
|
103
|
-
static readonly IMPORT_LANG = 'lang'
|
|
99
|
+
static readonly IMPORT_TJSON = 'TJSON';
|
|
100
|
+
static readonly IMPORT_IT_SERIALIZABLE = 'ITSerializable';
|
|
101
|
+
static readonly IMPORT_LANG = 'lang';
|
|
104
102
|
|
|
105
103
|
// ========== 类型推断相关 ==========
|
|
106
|
-
static readonly BOOLEAN_WRAPPER = 'Boolean'
|
|
107
|
-
static readonly NUMBER_WRAPPER = 'Number'
|
|
108
|
-
static readonly STRING_WRAPPER = 'String'
|
|
104
|
+
static readonly BOOLEAN_WRAPPER = 'Boolean';
|
|
105
|
+
static readonly NUMBER_WRAPPER = 'Number';
|
|
106
|
+
static readonly STRING_WRAPPER = 'String';
|
|
109
107
|
|
|
110
|
-
static readonly ARRAY_SUFFIX = '[]'
|
|
111
|
-
static readonly ARRAY_PREFIX = 'array<'
|
|
108
|
+
static readonly ARRAY_SUFFIX = '[]';
|
|
109
|
+
static readonly ARRAY_PREFIX = 'array<';
|
|
112
110
|
|
|
113
111
|
// ========== 默认值相关 ==========
|
|
114
|
-
static readonly DEFAULT_VALUE_FALSE = 'false'
|
|
115
|
-
static readonly DEFAULT_VALUE_ZERO = '0'
|
|
116
|
-
static readonly DEFAULT_VALUE_EMPTY_STRING = "''"
|
|
117
|
-
static readonly DEFAULT_VALUE_ZERO_BIGINT = '0n'
|
|
118
|
-
static readonly DEFAULT_VALUE_UNDEFINED = 'undefined'
|
|
112
|
+
static readonly DEFAULT_VALUE_FALSE = 'false';
|
|
113
|
+
static readonly DEFAULT_VALUE_ZERO = '0';
|
|
114
|
+
static readonly DEFAULT_VALUE_EMPTY_STRING = "''";
|
|
115
|
+
static readonly DEFAULT_VALUE_ZERO_BIGINT = '0n';
|
|
116
|
+
static readonly DEFAULT_VALUE_UNDEFINED = 'undefined';
|
|
119
117
|
|
|
120
118
|
// ========== 模板字符串片段 ==========
|
|
121
|
-
static readonly TEMPLATE_ELEMENT_NAME = 'element'
|
|
122
|
-
static readonly TEMPLATE_SENDABLE_ERROR_PREFIX = 'Sendable support not enabled for'
|
|
123
|
-
|
|
119
|
+
static readonly TEMPLATE_ELEMENT_NAME = 'element';
|
|
120
|
+
static readonly TEMPLATE_SENDABLE_ERROR_PREFIX = 'Sendable support not enabled for';
|
|
121
|
+
|
|
124
122
|
// ========== 文件操作相关 ==========
|
|
125
|
-
static readonly FILE_OPERATION_EMPTY_STRING = ''
|
|
126
|
-
static readonly REGEX_IMPORT_STATEMENT = /import\s+({[^}]+}|\w+)\s+from\s+'([^']+)'
|
|
127
|
-
static readonly REGEX_SRC_MAIN_ETS = /\/src\/main\/ets\/(.*)\.ets
|
|
128
|
-
|
|
123
|
+
static readonly FILE_OPERATION_EMPTY_STRING = '';
|
|
124
|
+
static readonly REGEX_IMPORT_STATEMENT = /import\s+({[^}]+}|\w+)\s+from\s+'([^']+)'/;
|
|
125
|
+
static readonly REGEX_SRC_MAIN_ETS = /\/src\/main\/ets\/(.*)\.ets$/;
|
|
126
|
+
|
|
129
127
|
// ========== 分隔符和连接符 ==========
|
|
130
|
-
static readonly SEPARATOR_COMMA = ','
|
|
131
|
-
static readonly SEPARATOR_COMMA_NEWLINE = ',\n'
|
|
132
|
-
static readonly SEPARATOR_NEWLINE = '\n'
|
|
133
|
-
static readonly SEPARATOR_COMMA_SPACE = ', '
|
|
134
|
-
static readonly JOIN_ELEMENT_PREFIX = ',\n '
|
|
135
|
-
|
|
128
|
+
static readonly SEPARATOR_COMMA = ',';
|
|
129
|
+
static readonly SEPARATOR_COMMA_NEWLINE = ',\n';
|
|
130
|
+
static readonly SEPARATOR_NEWLINE = '\n';
|
|
131
|
+
static readonly SEPARATOR_COMMA_SPACE = ', ';
|
|
132
|
+
static readonly JOIN_ELEMENT_PREFIX = ',\n ';
|
|
133
|
+
|
|
136
134
|
// ========== 正则表达式字符串 ==========
|
|
137
|
-
static readonly CURLY_BRACE_START = '{'
|
|
138
|
-
static readonly PATH_RELATIVE_PREFIX = './'
|
|
139
|
-
static readonly INSTANCE_SUFFIX = '.INSTANCE'
|
|
140
|
-
static readonly SERIALIZER_SUFFIX = 'Serializer'
|
|
141
|
-
|
|
135
|
+
static readonly CURLY_BRACE_START = '{';
|
|
136
|
+
static readonly PATH_RELATIVE_PREFIX = './';
|
|
137
|
+
static readonly INSTANCE_SUFFIX = '.INSTANCE';
|
|
138
|
+
static readonly SERIALIZER_SUFFIX = 'Serializer';
|
|
139
|
+
|
|
142
140
|
// ========== 日志前缀 ==========
|
|
143
|
-
static readonly LOG_PREFIX_T_SERIALIZATION = '[TSerialization]'
|
|
144
|
-
static readonly LOG_MODULE_PREFIX_TEMPLATE = '[${module}]'
|
|
145
|
-
|
|
141
|
+
static readonly LOG_PREFIX_T_SERIALIZATION = '[TSerialization]';
|
|
142
|
+
static readonly LOG_MODULE_PREFIX_TEMPLATE = '[${module}]';
|
|
143
|
+
|
|
146
144
|
// ========== 插件标识 ==========
|
|
147
|
-
static readonly PLUGIN_ID = 'turboTransJsonPlugin'
|
|
148
|
-
|
|
145
|
+
static readonly PLUGIN_ID = 'turboTransJsonPlugin';
|
|
146
|
+
|
|
149
147
|
// ========== 模块标识符 ==========
|
|
150
|
-
static readonly JSON_MODULE_SPECIFIER = '@hadss/hmserialization-json'
|
|
151
|
-
static readonly ARKTS_MODULE_SPECIFIER = '@kit.ArkTS'
|
|
148
|
+
static readonly JSON_MODULE_SPECIFIER = '@hadss/hmserialization-json';
|
|
149
|
+
static readonly ARKTS_MODULE_SPECIFIER = '@kit.ArkTS';
|
|
152
150
|
}
|
|
@@ -24,13 +24,21 @@ export abstract class BaseTypeHandler implements ITypeHandler {
|
|
|
24
24
|
|
|
25
25
|
// 子类必须实现的所有核心方法
|
|
26
26
|
abstract matches(typeNode: TypeNode, context: TypeContext): boolean;
|
|
27
|
+
|
|
27
28
|
abstract parse(typeNode: TypeNode, context: TypeContext): TypeStructure;
|
|
29
|
+
|
|
28
30
|
abstract getSerializerMetadata(structure: TypeStructure, withParam?: string): SerializerMetadata;
|
|
31
|
+
|
|
29
32
|
abstract generateInstantiation(structure: TypeStructure): string;
|
|
33
|
+
|
|
30
34
|
abstract generateTypeDeclaration(structure: TypeStructure): string;
|
|
35
|
+
|
|
31
36
|
abstract generateTypeKey(structure: TypeStructure): string;
|
|
37
|
+
|
|
32
38
|
abstract generateSendableTypeDeclaration(structure: TypeStructure): string;
|
|
33
|
-
|
|
39
|
+
|
|
40
|
+
abstract generatePropertyConversion(structure: TypeStructure, sourceValue: string,
|
|
41
|
+
direction: ConversionDirection): string;
|
|
34
42
|
|
|
35
43
|
/** 获取序列化器名称(约定:TypeName + Serializer)*/
|
|
36
44
|
protected getSerializerName(): string {
|
|
@@ -55,7 +63,8 @@ export abstract class BaseTypeHandler implements ITypeHandler {
|
|
|
55
63
|
* @param defaultInstantiation 默认实例化代码
|
|
56
64
|
* @param structure 类型结构
|
|
57
65
|
*/
|
|
58
|
-
protected applyWithParam(withParam: string | undefined, defaultInstantiation: string,
|
|
66
|
+
protected applyWithParam(withParam: string | undefined, defaultInstantiation: string,
|
|
67
|
+
structure: TypeStructure): string {
|
|
59
68
|
if (!withParam) {
|
|
60
69
|
return defaultInstantiation;
|
|
61
70
|
}
|
|
@@ -99,9 +99,9 @@ export class CustomClassHandler extends BaseTypeHandler implements ITypeHandler
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
private parseGenericArguments(typeArgs: TypeNode[], context: TypeContext): {
|
|
103
|
-
dependencies: TypeDependency[];
|
|
104
|
-
parsedArgs: TypeStructure[]
|
|
102
|
+
private parseGenericArguments(typeArgs: TypeNode[], context: TypeContext): {
|
|
103
|
+
dependencies: TypeDependency[];
|
|
104
|
+
parsedArgs: TypeStructure[]
|
|
105
105
|
} {
|
|
106
106
|
const dependencies: TypeDependency[] = [];
|
|
107
107
|
const parsedArgs: TypeStructure[] = typeArgs.map(arg => {
|
|
@@ -113,7 +113,7 @@ export class CustomClassHandler extends BaseTypeHandler implements ITypeHandler
|
|
|
113
113
|
dependencies.push(...argStructure.dependencies);
|
|
114
114
|
return argStructure;
|
|
115
115
|
});
|
|
116
|
-
|
|
116
|
+
|
|
117
117
|
return { dependencies, parsedArgs };
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -240,9 +240,6 @@ export class CustomClassHandler extends BaseTypeHandler implements ITypeHandler
|
|
|
240
240
|
throw new CustomError(`Type ${classDetails.classDecl.getName()} is not sendable.
|
|
241
241
|
please add @Sendable or @Serializable({ generateSendable: true })`, ErrorCodes.NOT_SENDABLE);
|
|
242
242
|
}
|
|
243
|
-
|
|
244
|
-
// 未启用generateSendable,返回原类型
|
|
245
|
-
return structure.sourceText;
|
|
246
243
|
}
|
|
247
244
|
|
|
248
245
|
generatePropertyConversion(structure: TypeStructure, sourceValue: string, direction: ConversionDirection): string {
|