@hadss/turbo-trans-json-plugin 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/LICENSE +177 -0
  2. package/README.md +253 -0
  3. package/dist/core/Types.d.ts +196 -0
  4. package/dist/core/Types.js +47 -0
  5. package/dist/core/analyzers/ClassAnalyzer.d.ts +23 -0
  6. package/dist/core/analyzers/ClassAnalyzer.js +480 -0
  7. package/dist/core/analyzers/CustomTypeAnalyzer.d.ts +21 -0
  8. package/dist/core/analyzers/CustomTypeAnalyzer.js +243 -0
  9. package/dist/core/analyzers/SendableMergeChecker.d.ts +9 -0
  10. package/dist/core/analyzers/SendableMergeChecker.js +100 -0
  11. package/dist/core/analyzers/SendableMergeabilityRegistry.d.ts +7 -0
  12. package/dist/core/analyzers/SendableMergeabilityRegistry.js +23 -0
  13. package/dist/core/constants/DecoratorConstants.d.ts +7 -0
  14. package/dist/core/constants/DecoratorConstants.js +13 -0
  15. package/dist/core/constants/PathConstants.d.ts +6 -0
  16. package/dist/core/constants/PathConstants.js +10 -0
  17. package/dist/core/constants/StringConstants.d.ts +83 -0
  18. package/dist/core/constants/StringConstants.js +87 -0
  19. package/dist/core/constants/index.d.ts +3 -0
  20. package/dist/core/constants/index.js +19 -0
  21. package/dist/core/handlers/BaseTypeHandler.d.ts +23 -0
  22. package/dist/core/handlers/BaseTypeHandler.js +57 -0
  23. package/dist/core/handlers/CustomClassHandler.d.ts +21 -0
  24. package/dist/core/handlers/CustomClassHandler.js +191 -0
  25. package/dist/core/handlers/DateHandler.d.ts +2 -0
  26. package/dist/core/handlers/DateHandler.js +60 -0
  27. package/dist/core/handlers/DecimalHandler.d.ts +2 -0
  28. package/dist/core/handlers/DecimalHandler.js +60 -0
  29. package/dist/core/handlers/EnumHandler.d.ts +2 -0
  30. package/dist/core/handlers/EnumHandler.js +89 -0
  31. package/dist/core/handlers/GenericContainerHandler.d.ts +2 -0
  32. package/dist/core/handlers/GenericContainerHandler.js +440 -0
  33. package/dist/core/handlers/GenericHandler.d.ts +18 -0
  34. package/dist/core/handlers/GenericHandler.js +92 -0
  35. package/dist/core/handlers/HandlerBootstrap.d.ts +2 -0
  36. package/dist/core/handlers/HandlerBootstrap.js +28 -0
  37. package/dist/core/handlers/ITypeHandler.d.ts +23 -0
  38. package/dist/core/handlers/ITypeHandler.js +8 -0
  39. package/dist/core/handlers/PrimitiveHandler.d.ts +2 -0
  40. package/dist/core/handlers/PrimitiveHandler.js +127 -0
  41. package/dist/core/handlers/TupleHandler.d.ts +2 -0
  42. package/dist/core/handlers/TupleHandler.js +98 -0
  43. package/dist/core/handlers/TypeHandlerRegistry.d.ts +20 -0
  44. package/dist/core/handlers/TypeHandlerRegistry.js +113 -0
  45. package/dist/core/handlers/UnionTypeHandler.d.ts +2 -0
  46. package/dist/core/handlers/UnionTypeHandler.js +263 -0
  47. package/dist/core/handlers/index.d.ts +2 -0
  48. package/dist/core/handlers/index.js +5 -0
  49. package/dist/core/import-rewrite/services/BuildProfileUpdater.d.ts +8 -0
  50. package/dist/core/import-rewrite/services/BuildProfileUpdater.js +92 -0
  51. package/dist/core/import-rewrite/services/ImportRewriteService.d.ts +9 -0
  52. package/dist/core/import-rewrite/services/ImportRewriteService.js +61 -0
  53. package/dist/core/import-rewrite/services/ImportTransformService.d.ts +15 -0
  54. package/dist/core/import-rewrite/services/ImportTransformService.js +109 -0
  55. package/dist/core/import-rewrite/strategies/ImportScanStrategy.d.ts +17 -0
  56. package/dist/core/import-rewrite/strategies/ImportScanStrategy.js +137 -0
  57. package/dist/core/import-rewrite/types/ImportRewriteTypes.d.ts +17 -0
  58. package/dist/core/import-rewrite/types/ImportRewriteTypes.js +2 -0
  59. package/dist/core/index.d.ts +9 -0
  60. package/dist/core/index.js +27 -0
  61. package/dist/core/interfaces/ITask.d.ts +7 -0
  62. package/dist/core/interfaces/ITask.js +2 -0
  63. package/dist/core/interfaces/ITaskContext.d.ts +11 -0
  64. package/dist/core/interfaces/ITaskContext.js +2 -0
  65. package/dist/core/interfaces/index.d.ts +2 -0
  66. package/dist/core/interfaces/index.js +2 -0
  67. package/dist/core/logger/Logger.d.ts +13 -0
  68. package/dist/core/logger/Logger.js +78 -0
  69. package/dist/core/services/CodeAnalysisService.d.ts +7 -0
  70. package/dist/core/services/CodeAnalysisService.js +43 -0
  71. package/dist/core/services/CodeGenerationEngine.d.ts +12 -0
  72. package/dist/core/services/CodeGenerationEngine.js +102 -0
  73. package/dist/core/services/CodeGenerationService/CodeGenerationService.d.ts +13 -0
  74. package/dist/core/services/CodeGenerationService/CodeGenerationService.js +110 -0
  75. package/dist/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.d.ts +13 -0
  76. package/dist/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.js +119 -0
  77. package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.d.ts +21 -0
  78. package/dist/core/services/CodeGenerationService/generators/OriginalClassGenerator.js +224 -0
  79. package/dist/core/services/CodeGenerationService/generators/SendableClassGenerator.d.ts +24 -0
  80. package/dist/core/services/CodeGenerationService/generators/SendableClassGenerator.js +307 -0
  81. package/dist/core/services/CodeGenerationService/generators/SerializerGenerator.d.ts +28 -0
  82. package/dist/core/services/CodeGenerationService/generators/SerializerGenerator.js +259 -0
  83. package/dist/core/services/CodeGenerationService/generators/TempSerializerGenerator.d.ts +19 -0
  84. package/dist/core/services/CodeGenerationService/generators/TempSerializerGenerator.js +178 -0
  85. package/dist/core/services/CodeGenerationService/index.d.ts +1 -0
  86. package/dist/core/services/CodeGenerationService/index.js +5 -0
  87. package/dist/core/services/CodeGenerationService/shared/ImportManager.d.ts +27 -0
  88. package/dist/core/services/CodeGenerationService/shared/ImportManager.js +127 -0
  89. package/dist/core/template/HandlebarsTemplateEngine.d.ts +26 -0
  90. package/dist/core/template/HandlebarsTemplateEngine.js +226 -0
  91. package/dist/core/utils/ConfigManager.d.ts +10 -0
  92. package/dist/core/utils/ConfigManager.js +32 -0
  93. package/dist/core/utils/CustomError.d.ts +30 -0
  94. package/dist/core/utils/CustomError.js +37 -0
  95. package/dist/core/utils/DeepCopyUtil.d.ts +15 -0
  96. package/dist/core/utils/DeepCopyUtil.js +138 -0
  97. package/dist/core/utils/GenericTypeSubstitutionUtil.d.ts +9 -0
  98. package/dist/core/utils/GenericTypeSubstitutionUtil.js +68 -0
  99. package/dist/core/utils/SerializationPathUtil.d.ts +18 -0
  100. package/dist/core/utils/SerializationPathUtil.js +107 -0
  101. package/dist/core/utils/TsMorphUtil.d.ts +8 -0
  102. package/dist/core/utils/TsMorphUtil.js +34 -0
  103. package/dist/index.d.ts +4 -0
  104. package/dist/index.js +57 -0
  105. package/dist/json-plugin/JSONExecuteController.d.ts +13 -0
  106. package/dist/json-plugin/JSONExecuteController.js +103 -0
  107. package/dist/json-plugin/constants/TaskConstants.d.ts +7 -0
  108. package/dist/json-plugin/constants/TaskConstants.js +11 -0
  109. package/dist/json-plugin/interfaces/IModuleContext.d.ts +10 -0
  110. package/dist/json-plugin/interfaces/IModuleContext.js +2 -0
  111. package/dist/json-plugin/interfaces/ITargetContext.d.ts +8 -0
  112. package/dist/json-plugin/interfaces/ITargetContext.js +2 -0
  113. package/dist/json-plugin/interfaces/impl/ModuleContext.d.ts +12 -0
  114. package/dist/json-plugin/interfaces/impl/ModuleContext.js +24 -0
  115. package/dist/json-plugin/interfaces/impl/TargetContext.d.ts +23 -0
  116. package/dist/json-plugin/interfaces/impl/TargetContext.js +113 -0
  117. package/dist/json-plugin/tasks/BaseTask.d.ts +14 -0
  118. package/dist/json-plugin/tasks/BaseTask.js +53 -0
  119. package/dist/json-plugin/tasks/CleanTask.d.ts +8 -0
  120. package/dist/json-plugin/tasks/CleanTask.js +25 -0
  121. package/dist/json-plugin/tasks/CodeProcessingTask.d.ts +8 -0
  122. package/dist/json-plugin/tasks/CodeProcessingTask.js +26 -0
  123. package/dist/json-plugin/tasks/SyncTask.d.ts +8 -0
  124. package/dist/json-plugin/tasks/SyncTask.js +21 -0
  125. package/dist/json-plugin/tasks/WatchTask.d.ts +11 -0
  126. package/dist/json-plugin/tasks/WatchTask.js +102 -0
  127. package/package.json +46 -0
  128. package/src/core/Types.ts +356 -0
  129. package/src/core/analyzers/ClassAnalyzer.ts +824 -0
  130. package/src/core/analyzers/CustomTypeAnalyzer.ts +337 -0
  131. package/src/core/analyzers/SendableMergeChecker.ts +195 -0
  132. package/src/core/analyzers/SendableMergeabilityRegistry.ts +72 -0
  133. package/src/core/constants/DecoratorConstants.ts +27 -0
  134. package/src/core/constants/PathConstants.ts +31 -0
  135. package/src/core/constants/StringConstants.ts +152 -0
  136. package/src/core/constants/index.ts +21 -0
  137. package/src/core/handlers/BaseTypeHandler.ts +121 -0
  138. package/src/core/handlers/CustomClassHandler.ts +278 -0
  139. package/src/core/handlers/DateHandler.ts +75 -0
  140. package/src/core/handlers/DecimalHandler.ts +75 -0
  141. package/src/core/handlers/EnumHandler.ts +142 -0
  142. package/src/core/handlers/GenericContainerHandler.ts +621 -0
  143. package/src/core/handlers/GenericHandler.ts +130 -0
  144. package/src/core/handlers/HandlerBootstrap.ts +64 -0
  145. package/src/core/handlers/ITypeHandler.ts +133 -0
  146. package/src/core/handlers/PrimitiveHandler.ts +159 -0
  147. package/src/core/handlers/TupleHandler.ts +145 -0
  148. package/src/core/handlers/TypeHandlerRegistry.ts +236 -0
  149. package/src/core/handlers/UnionTypeHandler.ts +400 -0
  150. package/src/core/handlers/index.ts +18 -0
  151. package/src/core/import-rewrite/services/BuildProfileUpdater.ts +145 -0
  152. package/src/core/import-rewrite/services/ImportRewriteService.ts +129 -0
  153. package/src/core/import-rewrite/services/ImportTransformService.ts +200 -0
  154. package/src/core/import-rewrite/strategies/ImportScanStrategy.ts +303 -0
  155. package/src/core/import-rewrite/types/ImportRewriteTypes.ts +100 -0
  156. package/src/core/index.ts +31 -0
  157. package/src/core/interfaces/ITask.ts +23 -0
  158. package/src/core/interfaces/ITaskContext.ts +94 -0
  159. package/src/core/interfaces/index.ts +17 -0
  160. package/src/core/logger/Logger.ts +149 -0
  161. package/src/core/services/CodeAnalysisService.ts +67 -0
  162. package/src/core/services/CodeGenerationEngine.ts +181 -0
  163. package/src/core/services/CodeGenerationService/CodeGenerationService.ts +159 -0
  164. package/src/core/services/CodeGenerationService/generators/MergedSendableClassGenerator.ts +189 -0
  165. package/src/core/services/CodeGenerationService/generators/OriginalClassGenerator.ts +314 -0
  166. package/src/core/services/CodeGenerationService/generators/SendableClassGenerator.ts +421 -0
  167. package/src/core/services/CodeGenerationService/generators/SerializerGenerator.ts +392 -0
  168. package/src/core/services/CodeGenerationService/generators/TempSerializerGenerator.ts +277 -0
  169. package/src/core/services/CodeGenerationService/index.ts +16 -0
  170. package/src/core/services/CodeGenerationService/shared/ImportManager.ts +191 -0
  171. package/src/core/template/HandlebarsTemplateEngine.ts +282 -0
  172. package/src/core/utils/ConfigManager.ts +49 -0
  173. package/src/core/utils/CustomError.ts +51 -0
  174. package/src/core/utils/DeepCopyUtil.ts +185 -0
  175. package/src/core/utils/GenericTypeSubstitutionUtil.ts +136 -0
  176. package/src/core/utils/SerializationPathUtil.ts +142 -0
  177. package/src/core/utils/TsMorphUtil.ts +50 -0
  178. package/src/index.ts +81 -0
  179. package/src/json-plugin/JSONExecuteController.ts +134 -0
  180. package/src/json-plugin/constants/TaskConstants.ts +22 -0
  181. package/src/json-plugin/interfaces/IModuleContext.ts +27 -0
  182. package/src/json-plugin/interfaces/ITargetContext.ts +25 -0
  183. package/src/json-plugin/interfaces/impl/ModuleContext.ts +45 -0
  184. package/src/json-plugin/interfaces/impl/TargetContext.ts +196 -0
  185. package/src/json-plugin/tasks/BaseTask.ts +94 -0
  186. package/src/json-plugin/tasks/CleanTask.ts +36 -0
  187. package/src/json-plugin/tasks/CodeProcessingTask.ts +41 -0
  188. package/src/json-plugin/tasks/SyncTask.ts +33 -0
  189. package/src/json-plugin/tasks/WatchTask.ts +99 -0
  190. package/template/SerializerPerformanceTemplate.hbs +35 -0
  191. package/template/SerializerRegisterTemplate.hbs +10 -0
  192. package/template/SerializerStrictTemplate.hbs +89 -0
  193. package/template/SerializerTemplate.hbs +176 -0
  194. package/tsconfig.json +17 -0
  195. package/tslint.json +3 -0
@@ -0,0 +1,185 @@
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 {
17
+ PropertyAnalysis, TypeStructure, TypeDependency, PropertyDecorators, DependencySource,
18
+ TypeDetails, EnumDetails, EnumMemberInfo, ClassDetails, InterfaceDetails, TypeAliasDetails
19
+ } from '..';
20
+
21
+ export class DeepCopyUtil {
22
+ static copyPropertyAnalysis(original: PropertyAnalysis): PropertyAnalysis {
23
+ return {
24
+ name: original.name,
25
+ defaultValue: original.defaultValue,
26
+ decorators: this.copyPropertyDecorators(original.decorators),
27
+ isMust: original.isMust,
28
+ type: this.copyTypeStructure(original.type)
29
+ };
30
+ }
31
+
32
+ private static copyPropertyDecorators(original?: PropertyDecorators): PropertyDecorators | undefined {
33
+ if (!original) {
34
+ return undefined;
35
+ }
36
+ return {
37
+ serialName: original.serialName,
38
+ isRequired: original.isRequired,
39
+ isTransient: original.isTransient,
40
+ with: original.with
41
+ };
42
+ }
43
+
44
+ static copyTypeStructure(original: TypeStructure): TypeStructure {
45
+ const copy: TypeStructure = {
46
+ kind: original.kind,
47
+ depth: original.depth,
48
+ sourceText: original.sourceText,
49
+ args: [], // 初始化为空数组,后面会根据原始值拷贝
50
+ dependencies: this.copyTypeDependencies(original.dependencies)
51
+ };
52
+
53
+ // 深拷贝枚举详细信息
54
+ if (original.enumDetails) {
55
+ copy.enumDetails = this.copyEnumDetails(original.enumDetails);
56
+ }
57
+
58
+ // 深拷贝类详细信息
59
+ if (original.classDetails) {
60
+ copy.classDetails = this.copyClassDetails(original.classDetails);
61
+ }
62
+
63
+ if (original.unionDetails) {
64
+ copy.unionDetails = original.unionDetails.map(
65
+ member => this.copyTypeStructure(member)
66
+ );
67
+ }
68
+
69
+ if (original.args && original.args.length > 0) {
70
+ copy.args = original.args.map(
71
+ arg => this.copyTypeStructure(arg)
72
+ );
73
+ }
74
+
75
+ return copy;
76
+ }
77
+
78
+ static copyTypeDependencies(original: TypeDependency[]): TypeDependency[] {
79
+ return original.map(dependency => this.copyTypeDependency(dependency));
80
+ }
81
+
82
+ private static copyTypeDependency(original: TypeDependency): TypeDependency {
83
+ const copy: TypeDependency = {
84
+ typeName: original.typeName,
85
+ typeKind: original.typeKind,
86
+ importPath: original.importPath,
87
+ source: this.copyDependencySource(original.source)
88
+ };
89
+
90
+ // 深拷贝详细信息(如果存在)
91
+ if (original.details) {
92
+ copy.details = this.copyTypeDetails(original.details);
93
+ }
94
+
95
+ return copy;
96
+ }
97
+
98
+ private static copyDependencySource(original: DependencySource): DependencySource {
99
+ return {
100
+ type: original.type,
101
+ sourceFilePath: original.sourceFilePath,
102
+ originalImport: original.originalImport,
103
+ packageName: original.packageName
104
+ };
105
+ }
106
+
107
+ private static copyTypeDetails(original: TypeDetails): TypeDetails {
108
+ // TypeDetails 是联合类型,需要根据 kind 分别处理
109
+ switch (original.kind) {
110
+ case 'enum':
111
+ return this.copyEnumDetails(original);
112
+ case 'class':
113
+ return this.copyClassDetails(original);
114
+ case 'interface':
115
+ return this.copyInterfaceDetails(original);
116
+ case 'type':
117
+ return this.copyTypeAliasDetails(original);
118
+ default:
119
+ // 默认浅拷贝未知类型
120
+ return { ...original };
121
+ }
122
+ }
123
+
124
+ private static copyEnumDetails(original: EnumDetails): EnumDetails {
125
+ return {
126
+ kind: original.kind,
127
+ members: original.members ? original.members.map((member: EnumMemberInfo) => ({
128
+ name: member.name,
129
+ value: member.value,
130
+ literalValue: member.literalValue
131
+ })) : [],
132
+ valueType: original.valueType
133
+ };
134
+ }
135
+
136
+ private static copyClassDetails(original: ClassDetails): ClassDetails {
137
+ return {
138
+ kind: original.kind,
139
+ classDecl: original.classDecl,
140
+ isGeneric: original.isGeneric
141
+ };
142
+ }
143
+
144
+ private static copyInterfaceDetails(original: InterfaceDetails): InterfaceDetails {
145
+ return {
146
+ kind: original.kind,
147
+ interfaceDecl: original.interfaceDecl,
148
+ isGeneric: original.isGeneric
149
+ };
150
+ }
151
+
152
+ private static copyTypeAliasDetails(original: TypeAliasDetails): TypeAliasDetails {
153
+ return {
154
+ kind: original.kind,
155
+ aliasedType: original.aliasedType,
156
+ resolvedType: this.copyTypeStructure(original.resolvedType!)
157
+ };
158
+ }
159
+
160
+ static deepCopy<T>(obj: T): T {
161
+ if (obj === null || typeof obj !== 'object') {
162
+ return obj;
163
+ }
164
+
165
+ if (obj instanceof Date) {
166
+ return new Date(obj.getTime()) as unknown as T;
167
+ }
168
+
169
+ if (obj instanceof Array) {
170
+ return obj.map(item => this.deepCopy(item)) as unknown as T;
171
+ }
172
+
173
+ if (typeof obj === 'object') {
174
+ const copy: any = {};
175
+ for (const key in obj) {
176
+ if (obj.hasOwnProperty(key)) {
177
+ copy[key] = this.deepCopy((obj as any)[key]);
178
+ }
179
+ }
180
+ return copy as T;
181
+ }
182
+
183
+ return obj;
184
+ }
185
+ }
@@ -0,0 +1,136 @@
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 { PropertyAnalysis, TypeStructure, PropertyKind, TypeDependency } from '..';
18
+ import { TypeHandlerRegistry } from '../handlers';
19
+ import { DeepCopyUtil } from './DeepCopyUtil';
20
+
21
+ export class GenericTypeSubstitutionUtil {
22
+ /**
23
+ * 构建泛型参数映射表
24
+ * @param parentGenericParams 父类泛型参数定义 ["T", "U"]
25
+ * @param childTypeArguments 子类传入的具体类型 ["string", "number"]
26
+ * @returns 映射表 Map { "T" => "string", "U" => "number" }
27
+ */
28
+ static buildGenericMapping(parentGenericParams: string[], childTypeArguments: TypeNode[]): Map<string, TypeNode> {
29
+ const mapping = new Map<string, TypeNode>();
30
+
31
+ const length = Math.min(parentGenericParams.length, childTypeArguments.length);
32
+
33
+ for (let i = 0; i < length; i++) {
34
+ mapping.set(parentGenericParams[i], childTypeArguments[i]);
35
+ }
36
+
37
+ return mapping;
38
+ }
39
+
40
+ /**
41
+ * 对属性类型进行泛型替换
42
+ * @param property 原始属性分析
43
+ * @param genericMapping 泛型参数映射 { "T": "string", "U": "number" }
44
+ * @param currentClassGenericParams 当前类的泛型参数列表
45
+ * @returns 替换后的属性分析
46
+ */
47
+ static substitutePropertyType(
48
+ property: PropertyAnalysis,
49
+ genericMapping: Map<string, TypeNode>,
50
+ currentClassGenericParams: string[] = []
51
+ ): PropertyAnalysis {
52
+ if (genericMapping.size === 0) {
53
+ return property; // 没有泛型替换,直接返回
54
+ }
55
+
56
+ // 使用深拷贝避免引用问题
57
+ const newProperty: PropertyAnalysis = DeepCopyUtil.copyPropertyAnalysis(property);
58
+
59
+ // 递归替换类型结构中的泛型参数
60
+ newProperty.type = this.substituteTypeStructure(newProperty.type, genericMapping, currentClassGenericParams);
61
+
62
+ return newProperty;
63
+ }
64
+
65
+ private static substituteTypeStructure(
66
+ typeStructure: TypeStructure,
67
+ mapping: Map<string, TypeNode>,
68
+ currentClassGenericParams: string[] = []
69
+ ): TypeStructure {
70
+ // 1. 处理泛型类型替换(核心逻辑)
71
+ if (typeStructure.kind === PropertyKind.GENERIC) {
72
+ // 对于泛型类型,sourceText 就是泛型参数名(如 "T", "U", "TData")
73
+ const genericTypeName = typeStructure.sourceText;
74
+ if (mapping.has(genericTypeName)) {
75
+ const substitutedTypeNode = mapping.get(genericTypeName)!;
76
+
77
+ return this.constructTypeStructureFromTypeName(substitutedTypeNode, currentClassGenericParams);
78
+ }
79
+ // 如果没有找到对应的映射,保持原样
80
+ return typeStructure;
81
+ }
82
+
83
+ // 2. 递归处理非泛型类型的子结构
84
+ // 使用深拷贝避免修改原始对象
85
+ const newStructure: TypeStructure = DeepCopyUtil.copyTypeStructure(typeStructure);
86
+
87
+ // 递归替换所有子结构中的泛型类型
88
+ if (newStructure.unionDetails) {
89
+ newStructure.unionDetails = newStructure.unionDetails.map(
90
+ member => this.substituteTypeStructure(member, mapping, currentClassGenericParams)
91
+ );
92
+ }
93
+
94
+ if (newStructure.args) {
95
+ newStructure.args = newStructure.args.map(
96
+ arg => this.substituteTypeStructure(arg, mapping, currentClassGenericParams)
97
+ );
98
+ }
99
+
100
+ // 重新计算依赖信息
101
+ newStructure.dependencies = this.collectDependenciesFromChildren(newStructure);
102
+
103
+ return newStructure;
104
+ }
105
+
106
+ private static constructTypeStructureFromTypeName(
107
+ typeNode: TypeNode,
108
+ currentClassGenericParams: string[] = []
109
+ ): TypeStructure {
110
+ return TypeHandlerRegistry.getInstance().parseType(typeNode, {
111
+ depth: 0,
112
+ genericParams: currentClassGenericParams // ✅ 传递当前类的泛型参数上下文
113
+ })
114
+ }
115
+
116
+ private static collectDependenciesFromChildren(children: TypeStructure): TypeDependency[] {
117
+ const allDependencies: TypeDependency[] = [];
118
+
119
+ if (children.unionDetails) {
120
+ for (const member of children.unionDetails) {
121
+ if (member.dependencies) {
122
+ allDependencies.push(...member.dependencies);
123
+ }
124
+ }
125
+ }
126
+ if (children.args) {
127
+ for (const arg of children.args) {
128
+ if (arg.dependencies) {
129
+ allDependencies.push(...arg.dependencies);
130
+ }
131
+ }
132
+ }
133
+
134
+ return allDependencies;
135
+ }
136
+ }
@@ -0,0 +1,142 @@
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 { FileUtil } from '@ohos/hvigor';
17
+ import * as path from "path";
18
+ import * as fs from "fs";
19
+ import { ITaskContext, PathConstants } from '..';
20
+
21
+ export default class SerializationPathUtil extends FileUtil {
22
+ static readonly sep: string = path.sep;
23
+
24
+ static dirname(p: string): string {
25
+ return path.dirname(p);
26
+ }
27
+
28
+ static basename(p: string, suffix?: string): string {
29
+ return path.basename(p, suffix);
30
+ }
31
+
32
+ static extname(p: string): string {
33
+ return path.extname(p);
34
+ }
35
+
36
+ static isAbsolute(p: string): boolean {
37
+ return path.isAbsolute(p)
38
+ }
39
+
40
+ static normalize(p: string): string {
41
+ return path.normalize(p)
42
+ }
43
+
44
+ static relative(from: string, to: string): string {
45
+ return path.relative(from, to);
46
+ }
47
+
48
+ static join(...paths: string[]): string {
49
+ return path.join(...paths);
50
+ }
51
+
52
+ static rmSync(path: fs.PathLike, options?: fs.RmOptions,): void {
53
+ return fs.rmSync(path, options);
54
+ }
55
+
56
+ /**
57
+ * 计算模块化导入路径
58
+ * 将绝对文件路径转换为模块化导入路径
59
+ *
60
+ * @param absolutePath 绝对文件路径,例如: /project/sampleentry/src/generated/ets/model/Person.ets
61
+ * @param context 任务上下文,提供模块名称和路径上下文
62
+ * @returns 模块化导入路径,例如: sampleentry/ets/model/Person
63
+ */
64
+ static calculateModularImportPath(absolutePath: string, context: ITaskContext): string {
65
+ const packageName = context.getPackageName();
66
+
67
+ const moduleRelativePath = context.calculateSourceRootToModuleRoot(absolutePath);
68
+
69
+ // 移除文件扩展名
70
+ const pathWithoutExtension = this.removeFileExtension(moduleRelativePath);
71
+
72
+ // 拼接模块化路径
73
+ return `${packageName}/${pathWithoutExtension}`;
74
+ }
75
+
76
+ /**
77
+ * 计算Sendable类的输出路径
78
+ * 将原始源文件路径映射到sendableModel目录
79
+ *
80
+ * @param className 原始类名
81
+ * @param context 任务上下文
82
+ * @returns Sendable类的输出路径
83
+ */
84
+ static mapToSendableOutputPath(className: string, context: ITaskContext): string {
85
+ // 获取基础输出路径(不包含文件名)
86
+ const baseOutputDir = context.getOutputRoot();
87
+
88
+ // 构建sendableModel目录路径
89
+ const sendableModelDir = this.join(baseOutputDir, 'ets/sendableModel');
90
+
91
+ // 返回完整的Sendable类文件路径
92
+ return this.join(sendableModelDir, `Sendable${className}.ets`);
93
+ }
94
+
95
+ /**
96
+ * 递归扫描目录,获取所有 ETS 文件
97
+ *
98
+ * @param directory 要扫描的目录路径
99
+ * @returns 所有 ETS 文件的绝对路径数组
100
+ */
101
+ static scanEtsFiles(directory: string): string[] {
102
+ const etsFiles: string[] = [];
103
+
104
+ const deepScanEtsFiles = (scanPath: string, relativePath: string) => {
105
+ let resolvePath = this.pathResolve(scanPath, relativePath);
106
+
107
+ if (!this.exist(resolvePath)) {
108
+ return;
109
+ }
110
+
111
+ if (this.isDictionary(resolvePath)) {
112
+ const files: string[] = fs.readdirSync(resolvePath);
113
+ files.forEach(file => {
114
+ deepScanEtsFiles(resolvePath, file);
115
+ });
116
+ } else {
117
+ // 只收集 .ets 文件
118
+ if (path.extname(relativePath) === PathConstants.ETS_EXTENSIONS) {
119
+ etsFiles.push(resolvePath);
120
+ }
121
+ }
122
+ }
123
+
124
+ deepScanEtsFiles(directory, '');
125
+
126
+ return etsFiles;
127
+ }
128
+
129
+ /**
130
+ * 移除文件扩展名
131
+ *
132
+ * @param filePath 文件路径
133
+ * @returns 无扩展名的路径
134
+ */
135
+ private static removeFileExtension(filePath: string): string {
136
+ const lastDotIndex = filePath.lastIndexOf('.');
137
+ if (lastDotIndex > 0) {
138
+ return filePath.substring(0, lastDotIndex);
139
+ }
140
+ return filePath;
141
+ }
142
+ }
@@ -0,0 +1,50 @@
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 { Project, ProjectOptions, TypeChecker } from 'ts-morph';
17
+ import { Logger } from '../logger/Logger';
18
+
19
+ export class TsMorphUtil {
20
+ public static project: Project | null = null;
21
+ private constructor() { }
22
+ public static getProject(options?: ProjectOptions): Project {
23
+ if (!this.project) {
24
+ Logger.info('创建ts-morph项目');
25
+ this.project = new Project(
26
+ options || {
27
+ compilerOptions: {
28
+ allowNonTsExtensions: true
29
+ }
30
+ }
31
+ );
32
+ }
33
+ return this.project;
34
+ }
35
+
36
+ public static getTypeChecker(): TypeChecker {
37
+ return this.getProject().getTypeChecker();
38
+ }
39
+
40
+ public static clearProject(): void {
41
+ const sourceFiles = TsMorphUtil.getProject().getSourceFiles();
42
+ Logger.info(`Clearing ${sourceFiles.length} source files...`);
43
+ if (sourceFiles && sourceFiles.length > 0) {
44
+ sourceFiles.forEach((sourceFile) => {
45
+ TsMorphUtil.getProject().removeSourceFile(sourceFile);
46
+ });
47
+ }
48
+ TsMorphUtil.project = null;
49
+ }
50
+ }
package/src/index.ts ADDED
@@ -0,0 +1,81 @@
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 { HvigorNode, HvigorPlugin } from '@ohos/hvigor';
17
+ import { Hvigor } from '@ohos/hvigor/src/base/external/core/hvigor';
18
+ import { DeserializationMode, PathConstants, TurboTransJsonPluginOptions, StringConstants } from './core';
19
+ import { initializeTypeHandlers } from './core/handlers/HandlerBootstrap';
20
+ import { JSONExecuteController } from './json-plugin/JSONExecuteController';
21
+
22
+ const PLUGIN_ID = StringConstants.PLUGIN_ID;
23
+ const DEFAULT_OPTIONS: TurboTransJsonPluginOptions = {
24
+ ignoreModuleNames: [],
25
+ scanDir: PathConstants.DEFAULT_SCAN_DIRS,
26
+ deserializationMode: DeserializationMode.PERFORMANCE,
27
+ };
28
+
29
+ export function turboTransJsonPlugin(hvigor: Hvigor,
30
+ options: TurboTransJsonPluginOptions = DEFAULT_OPTIONS): HvigorPlugin {
31
+ return {
32
+ pluginId: PLUGIN_ID,
33
+ apply(node: HvigorNode): void {
34
+ TurboTransJSONPluginManager.getInstance(hvigor).initialization(node, options);
35
+ }
36
+ };
37
+ }
38
+
39
+ class TurboTransJSONPluginManager {
40
+ private static instance: TurboTransJSONPluginManager | null;
41
+ private moduleExecuteControllers: Set<JSONExecuteController> = new Set(); // 每个模块对应的JSON插件
42
+
43
+ private constructor(hvigor: Hvigor) {
44
+ this.setupHvigorHooks(hvigor);
45
+ }
46
+
47
+ static getInstance(hvigor: Hvigor): TurboTransJSONPluginManager {
48
+ if (!TurboTransJSONPluginManager.instance) {
49
+ TurboTransJSONPluginManager.instance = new TurboTransJSONPluginManager(hvigor);
50
+ }
51
+ return TurboTransJSONPluginManager.instance;
52
+ }
53
+
54
+ initialization(node: HvigorNode, options: TurboTransJsonPluginOptions) {
55
+ initializeTypeHandlers();
56
+ node.subNodes(subNode => {
57
+ const subNodeName = subNode.getNodeName();
58
+ if (options.ignoreModuleNames.includes(subNodeName)) {
59
+ return;
60
+ }
61
+ const executeController = new JSONExecuteController(subNode, options);
62
+ this.moduleExecuteControllers.add(executeController);
63
+ });
64
+ }
65
+
66
+ private setupHvigorHooks(hvigor: Hvigor) {
67
+ hvigor.nodesEvaluated(() => {
68
+ this.moduleExecuteControllers.forEach(controller => {
69
+ controller.execute();
70
+ });
71
+ });
72
+
73
+ hvigor.buildFinished(() => {
74
+ this.moduleExecuteControllers.forEach(controller => {
75
+ controller.compile();
76
+ });
77
+ this.moduleExecuteControllers.clear();
78
+ TurboTransJSONPluginManager.instance = null;
79
+ });
80
+ }
81
+ }