@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,303 @@
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 { ImportDeclaration } from 'ts-morph';
17
+ import { ITaskContext } from '../..';
18
+ import { GeneratedFileInfo, ImportScanStrategy } from '../types/ImportRewriteTypes';
19
+ import { Logger } from '../../logger/Logger';
20
+ import { PathConstants } from '../../constants';
21
+ import SerializationPathUtil from '../../utils/SerializationPathUtil';
22
+
23
+ export class ImportScanStrategyImpl implements ImportScanStrategy {
24
+ shouldRewriteImport(
25
+ importDeclaration: ImportDeclaration,
26
+ currentFilePath: string,
27
+ generatedFileInfos: GeneratedFileInfo[],
28
+ context: ITaskContext
29
+ ): GeneratedFileInfo | null {
30
+ const moduleSpecifier = importDeclaration.getModuleSpecifierValue();
31
+ const importedTypes = this.extractImportedTypes(importDeclaration);
32
+
33
+ // 跳过类型定义文件的导入重写
34
+ if (this.isTypeDefinitionFile(currentFilePath, generatedFileInfos)) {
35
+ return null;
36
+ }
37
+
38
+ // 检查是否需要重写导入
39
+ const matchedInfo = this.resolveModuleSpecifier(
40
+ moduleSpecifier,
41
+ currentFilePath,
42
+ generatedFileInfos,
43
+ context
44
+ );
45
+
46
+ if (matchedInfo) {
47
+ // 检查导入的类型是否在生成的类列表中
48
+ const matchedTypes = importedTypes.filter(typeName =>
49
+ matchedInfo.classNames.has(typeName)
50
+ );
51
+
52
+ if (matchedTypes.length > 0) {
53
+ return matchedInfo;
54
+ }
55
+ }
56
+
57
+ return null;
58
+ }
59
+
60
+ /**
61
+ * 从导出声明检查是否需要重写
62
+ * 与导入检查逻辑相同,但导出不需要检查导出的类型
63
+ */
64
+ shouldRewriteExport(
65
+ moduleSpecifier: string,
66
+ currentFilePath: string,
67
+ generatedFileInfos: GeneratedFileInfo[],
68
+ context: ITaskContext
69
+ ): GeneratedFileInfo | null {
70
+ // 没有 moduleSpecifier 说明没有 from 子句,不需要处理
71
+ if (!moduleSpecifier) {
72
+ return null;
73
+ }
74
+
75
+ // 跳过类型定义文件的导出重写
76
+ if (this.isTypeDefinitionFile(currentFilePath, generatedFileInfos)) {
77
+ return null;
78
+ }
79
+
80
+ // 使用相同的模块定位逻辑
81
+ return this.resolveModuleSpecifier(
82
+ moduleSpecifier,
83
+ currentFilePath,
84
+ generatedFileInfos,
85
+ context
86
+ );
87
+ }
88
+
89
+ /**
90
+ * 统一的模块定位逻辑
91
+ * 支持相对路径导入和模块化导入(包括旧包名)
92
+ * 复用于 import 和 export 语句
93
+ */
94
+ private resolveModuleSpecifier(
95
+ moduleSpecifier: string,
96
+ currentFilePath: string,
97
+ generatedFileInfos: GeneratedFileInfo[],
98
+ context: ITaskContext
99
+ ): GeneratedFileInfo | null {
100
+ // 1. 先尝试处理相对路径导入
101
+ if (this.isRelativeImport(moduleSpecifier)) {
102
+ const resolvedSourcePath = this.resolveImportPath(moduleSpecifier, currentFilePath);
103
+
104
+ // 在生成信息中查找匹配的源文件
105
+ for (const generatedInfo of generatedFileInfos) {
106
+ if (this.pathMatches(resolvedSourcePath, generatedInfo.sourceFilePath)) {
107
+ return generatedInfo;
108
+ }
109
+ }
110
+
111
+ return null;
112
+ }
113
+
114
+ // 2. 然后尝试处理模块化导入(包括旧包名)
115
+ return this.resolveModularImportToSourceFile(
116
+ moduleSpecifier,
117
+ generatedFileInfos,
118
+ context
119
+ );
120
+ }
121
+
122
+ /**
123
+ * 从模块化导入路径反推源文件
124
+ * 核心逻辑:不依赖包名,只匹配文件路径后缀
125
+ *
126
+ * 例如:
127
+ * 导入: 'sampleentry/ets/model/Person'
128
+ * 源文件相对路径: 'src/main/ets/model/Person'
129
+ * 提取文件路径: 'ets/model/Person'
130
+ * 检查后缀匹配: true ✓
131
+ */
132
+ private resolveModularImportToSourceFile(
133
+ moduleSpecifier: string,
134
+ generatedFileInfos: GeneratedFileInfo[],
135
+ context: ITaskContext
136
+ ): GeneratedFileInfo | null {
137
+ // 1. 提取文件路径部分(去掉包名)
138
+ const filePath = this.extractFilePathFromModularImport(moduleSpecifier);
139
+ if (!filePath) {
140
+ return null;
141
+ }
142
+
143
+ // 2. 遍历所有源文件,尝试匹配
144
+ for (const info of generatedFileInfos) {
145
+ // 获取源文件的相对路径
146
+ const sourceFileRelativePath = context.calculateSourceRootToModuleRoot(info.sourceFilePath);
147
+
148
+ // 移除扩展名
149
+ const pathWithoutExtension = this.removeFileExtension(sourceFileRelativePath);
150
+
151
+ // 统一分隔符为 /
152
+ const normalizedSourcePath = pathWithoutExtension.replaceAll(SerializationPathUtil.sep, '/');
153
+
154
+ // 检查是否为后缀匹配
155
+ if (this.isPathSuffix(filePath, normalizedSourcePath)) {
156
+ Logger.debug(`模块化导入 '${moduleSpecifier}' 匹配源文件: ${info.sourceFilePath}`);
157
+ return info;
158
+ }
159
+ }
160
+
161
+ return null;
162
+ }
163
+
164
+ /**
165
+ * 从模块化导入提取文件路径部分
166
+ *
167
+ * 例如:
168
+ * 'sampleentry/ets/model/Person' -> 'ets/model/Person'
169
+ * '@hadss/pkg/ets/model/Person' -> 'ets/model/Person'
170
+ * 'invalid' -> null
171
+ */
172
+ private extractFilePathFromModularImport(moduleSpecifier: string): string | null {
173
+ const parts = moduleSpecifier.split('/');
174
+
175
+ if (parts.length < 2) {
176
+ return null;
177
+ }
178
+
179
+ // 确定包名占几个部分
180
+ let filePathStartIndex = 1;
181
+ if (parts[0].startsWith('@')) {
182
+ // 作用域包:@org/package
183
+ filePathStartIndex = 2;
184
+ }
185
+
186
+ if (filePathStartIndex >= parts.length) {
187
+ // 没有文件路径部分
188
+ return null;
189
+ }
190
+
191
+ return parts.slice(filePathStartIndex).join('/');
192
+ }
193
+
194
+ /**
195
+ * 检查 shortPath 是否是 fullPath 的后缀
196
+ *
197
+ * 例如:
198
+ * isPathSuffix('ets/model/Person', 'src/main/ets/model/Person') -> true
199
+ * isPathSuffix('model/Person', 'src/main/ets/model/Person') -> true
200
+ * isPathSuffix('ets/model/Person', 'src/main/ets/data/Person') -> false
201
+ */
202
+ private isPathSuffix(shortPath: string, fullPath: string): boolean {
203
+ const shortParts = shortPath.split('/').filter(p => p.length > 0);
204
+ const fullParts = fullPath.split('/').filter(p => p.length > 0);
205
+
206
+ // 如果短路径更长,不可能是后缀
207
+ if (shortParts.length > fullParts.length) {
208
+ return false;
209
+ }
210
+
211
+ // 从后向前匹配
212
+ const offset = fullParts.length - shortParts.length;
213
+ for (let i = 0; i < shortParts.length; i++) {
214
+ if (shortParts[i] !== fullParts[offset + i]) {
215
+ return false;
216
+ }
217
+ }
218
+
219
+ return true;
220
+ }
221
+
222
+ /**
223
+ * 移除文件扩展名
224
+ */
225
+ private removeFileExtension(filePath: string): string {
226
+ const lastDotIndex = filePath.lastIndexOf('.');
227
+ if (lastDotIndex > 0) {
228
+ return filePath.substring(0, lastDotIndex);
229
+ }
230
+ return filePath;
231
+ }
232
+
233
+ /**
234
+ * 检查文件是否为类型定义文件
235
+ * 类型定义文件是指包含 @Serializable 类且生成了序列化代码的源文件
236
+ */
237
+ private isTypeDefinitionFile(filePath: string, generatedFileInfos: GeneratedFileInfo[]): boolean {
238
+ return generatedFileInfos.some(info => info.sourceFilePath === filePath);
239
+ }
240
+
241
+ /**
242
+ * 检查是否为相对路径导入
243
+ */
244
+ private isRelativeImport(moduleSpecifier: string): boolean {
245
+ return moduleSpecifier.startsWith('./') || moduleSpecifier.startsWith('../');
246
+ }
247
+
248
+ /**
249
+ * 解析导入路径为绝对路径
250
+ * '../model/Person' + '/project/src/main/ets/features/EntityClass.ets'
251
+ * -> '/project/src/main/ets/model/Person.ets'
252
+ */
253
+ private resolveImportPath(moduleSpecifier: string, currentFilePath: string): string {
254
+ if (this.isRelativeImport(moduleSpecifier)) {
255
+ const currentDir = SerializationPathUtil.dirname(currentFilePath);
256
+ const resolvedPath = SerializationPathUtil.pathResolve(currentDir, moduleSpecifier);
257
+
258
+ // 如果没有扩展名,添加 .ets
259
+ if (!SerializationPathUtil.extname(resolvedPath)) {
260
+ return resolvedPath + PathConstants.ETS_EXTENSIONS;
261
+ }
262
+ return resolvedPath;
263
+ }
264
+ return moduleSpecifier;
265
+ }
266
+
267
+ /**
268
+ * 路径匹配检查(处理路径标准化)
269
+ */
270
+ private pathMatches(resolvedPath: string, sourcePath: string): boolean {
271
+ const normalizedResolved = SerializationPathUtil.pathResolve(resolvedPath);
272
+ const normalizedSource = SerializationPathUtil.pathResolve(sourcePath);
273
+ return normalizedResolved === normalizedSource;
274
+ }
275
+
276
+ /**
277
+ * 从导入声明中提取导入的类型名
278
+ */
279
+ private extractImportedTypes(importDeclaration: ImportDeclaration): string[] {
280
+ const importedTypes: string[] = [];
281
+
282
+ // 处理命名导入: import { Person, User } from './model'
283
+ const namedImports = importDeclaration.getNamedImports();
284
+ for (const namedImport of namedImports) {
285
+ importedTypes.push(namedImport.getName());
286
+ }
287
+
288
+ // 处理默认导入: import Person from './Person'
289
+ const defaultImport = importDeclaration.getDefaultImport();
290
+ if (defaultImport) {
291
+ importedTypes.push(defaultImport.getText());
292
+ }
293
+
294
+ // 处理命名空间导入: import * as Models from './models'
295
+ const namespaceImport = importDeclaration.getNamespaceImport();
296
+ if (namespaceImport) {
297
+ // 对于命名空间导入,我们暂时不处理,因为这种情况比较复杂
298
+ Logger.warn(`跳过命名空间导入: ${namespaceImport.getText()}`);
299
+ }
300
+
301
+ return importedTypes;
302
+ }
303
+ }
@@ -0,0 +1,100 @@
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 { ImportDeclaration } from 'ts-morph';
17
+ import { ITaskContext, ImportRewriteOptions } from '../..';
18
+
19
+ /**
20
+ * 生成文件信息映射
21
+ * 包含源文件到生成文件的完整映射关系
22
+ */
23
+ export interface GeneratedFileInfo {
24
+ sourceFilePath: string; // 源文件绝对路径
25
+ generatedFilePath: string; // 生成文件绝对路径
26
+ classNames: Set<string>; // 该文件中包含的类名列表
27
+ }
28
+
29
+ /**
30
+ * 导入重写服务接口
31
+ */
32
+ export interface ImportRewriteService {
33
+ /**
34
+ * 重写项目中的导入语句
35
+ * @param context 任务上下文 (ITaskContext)
36
+ * @param generatedFileInfos 生成文件信息列表
37
+ * @param options 导入重写选项
38
+ */
39
+ rewriteImports(
40
+ context: ITaskContext,
41
+ generatedFileInfos: GeneratedFileInfo[],
42
+ options: ImportRewriteOptions
43
+ ): void;
44
+ }
45
+
46
+ /**
47
+ * 导入扫描策略接口
48
+ */
49
+ export interface ImportScanStrategy {
50
+ /**
51
+ * 基于实际生成信息进行精确匹配
52
+ * 只有实际生成了序列化代码的类才会被重写导入
53
+ *
54
+ * @param importDeclaration 导入声明
55
+ * @param currentFilePath 当前文件路径
56
+ * @param generatedFileInfos 生成文件信息列表
57
+ * @param context 任务上下文,用于解析文件路径
58
+ */
59
+ shouldRewriteImport(
60
+ importDeclaration: ImportDeclaration,
61
+ currentFilePath: string,
62
+ generatedFileInfos: GeneratedFileInfo[],
63
+ context: ITaskContext
64
+ ): GeneratedFileInfo | null;
65
+
66
+ /**
67
+ * 检查导出声明是否需要重写
68
+ * 与导入检查逻辑相同
69
+ *
70
+ * @param moduleSpecifier 导出的模块说明符(from 子句的值)
71
+ * @param currentFilePath 当前文件路径
72
+ * @param generatedFileInfos 生成文件信息列表
73
+ * @param context 任务上下文,用于解析文件路径
74
+ */
75
+ shouldRewriteExport(
76
+ moduleSpecifier: string,
77
+ currentFilePath: string,
78
+ generatedFileInfos: GeneratedFileInfo[],
79
+ context: ITaskContext
80
+ ): GeneratedFileInfo | null;
81
+ }
82
+
83
+ /**
84
+ * 导入转换服务接口
85
+ */
86
+ export interface ImportTransformService {
87
+ /**
88
+ * 重写文件中的导入语句
89
+ * @param filePath 文件路径
90
+ * @param context 任务上下文
91
+ * @param generatedFileInfos 生成文件信息列表
92
+ * @param preserveOriginalImports 是否保留原导入注释
93
+ */
94
+ rewriteFileImports(
95
+ filePath: string,
96
+ context: ITaskContext,
97
+ generatedFileInfos: GeneratedFileInfo[],
98
+ preserveOriginalImports?: boolean
99
+ ): void;
100
+ }
@@ -0,0 +1,31 @@
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
+ export * from './interfaces'
17
+
18
+ export * from './logger/Logger';
19
+
20
+ export * from './constants'
21
+
22
+ export * from './Types';
23
+
24
+ export * from './services/CodeGenerationEngine'
25
+
26
+ // 导入重写功能导出
27
+ export * from './import-rewrite/types/ImportRewriteTypes';
28
+ export * from './import-rewrite/services/ImportRewriteService';
29
+ export * from './utils/ConfigManager';
30
+
31
+ export { TempSerializerGenerator } from './services/CodeGenerationService/generators/TempSerializerGenerator'
@@ -0,0 +1,23 @@
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 { ITaskContext } from './ITaskContext'
17
+
18
+ export interface ITask {
19
+ readonly taskName: string
20
+ readonly dependencies: string[]
21
+ readonly postDependencies: string[]
22
+ run(context: ITaskContext): void | Promise<void>
23
+ }
@@ -0,0 +1,94 @@
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
+ export interface ITaskContext {
17
+ /**
18
+ * 将源文件路径映射为输出文件路径
19
+ * @param absSourceFile 源文件的绝对路径
20
+ * @returns 输出文件的绝对路径
21
+ * @example
22
+ * 'module/src/main/ets/User.ets' -> '/module/src/generated/ets/User.ets'
23
+ */
24
+ mapToOutputPath(absSourceFile: string): string
25
+
26
+ /**
27
+ * 获取输出根目录
28
+ * 返回所有生成文件的根目录路径
29
+ * @returns 输出根目录的绝对路径
30
+ * @example
31
+ * 'module/src/generated'
32
+ */
33
+ getOutputRoot(): string
34
+
35
+ /**
36
+ * 获取模块名称
37
+ * 返回当前模块module.json5中配置的name字段
38
+ * @returns 输出当前模块module.json5中配置的name字段
39
+ */
40
+ getModuleName(): string
41
+
42
+ /**
43
+ * 获取模块根路径
44
+ * @returns 输出当前模块根路径
45
+ */
46
+ getModulePath(): string
47
+
48
+ /**
49
+ * 获取package名称
50
+ * 返回当前模块oh-package.json5中配置的name字段
51
+ * @returns 输出当前模块oh-package.json5中配置的name字段
52
+ */
53
+ getPackageName(): string
54
+
55
+ /**
56
+ * 获取文件的相对路径
57
+ * 将绝对路径转换为相对于项目根目录的路径
58
+ * 主要用于日志显示和错误报告
59
+ * @param absolutePath 绝对文件路径
60
+ * @returns 相对于项目根目录的路径
61
+ * @example
62
+ * 'module/src/main/ets/User.ets' -> 'src/main/ets/User.ets'
63
+ */
64
+ getRelativePath(absolutePath: string): string
65
+
66
+ /**
67
+ * 检查输出路径是否有效
68
+ * 验证输出路径是否满足当前环境的要求
69
+ * 用于路径映射的安全性检查
70
+ * @param outputPath 输出文件路径
71
+ * @returns 路径是否有效
72
+ */
73
+ isValidOutputPath(outputPath: string): boolean
74
+
75
+ /**
76
+ * 确保输出目录存在
77
+ * 创建输出文件所需的目录结构
78
+ * @param outputPath 输出文件路径
79
+ * @returns Promise<void>
80
+ */
81
+ ensureOutputDirectory(outputPath: string): void
82
+
83
+
84
+ /**
85
+ * 计算相对于模块根目录的路径
86
+ * 剔除sourceRoots路径前缀,默认包含 './src/main'
87
+ *
88
+ * @param absolutePath 文件的绝对路径
89
+ * @returns 相对于模块根的路径(剔除src/main或src/generated前缀)
90
+ * @example
91
+ * 'module/src/main/ets/User.ets' -> '/ets/User.ets'
92
+ */
93
+ calculateSourceRootToModuleRoot(absolutePath: string): string
94
+ }
@@ -0,0 +1,17 @@
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
+ export { ITask } from './ITask'
17
+ export { ITaskContext } from './ITaskContext';