|
47 | 47 | import java.io.PrintStream; |
48 | 48 | import java.nio.file.Files; |
49 | 49 | import java.nio.file.Paths; |
| 50 | +import java.security.MessageDigest; |
| 51 | +import java.security.NoSuchAlgorithmException; |
50 | 52 | import java.util.ArrayList; |
51 | 53 | import java.util.Arrays; |
52 | 54 | import java.util.HashMap; |
@@ -153,9 +155,10 @@ public Binding generateBinding(DataRow dataRow, HashSet<String> interfaceNames) |
153 | 155 | name = getSimpleClassname(clazz.getClassName()); |
154 | 156 | } else { |
155 | 157 | name = getSimpleClassname(clazz.getClassName().replace("$", "_")) + "_"; |
156 | | - // name of the class: last portion of the full file name + line + column + variable name |
157 | | - String[] lastFilePathPart = dataRow.getFile().split("_"); |
158 | | - name += lastFilePathPart[lastFilePathPart.length - 1] + "_" + dataRow.getLine() + "_" + dataRow.getColumn() + "_" + dataRow.getNewClassName(); |
| 158 | + // Generate a unique identifier that prevents naming collisions |
| 159 | + // especially with .mjs files and complex Angular component structures |
| 160 | + String fileIdentifier = generateUniqueFileIdentifier(dataRow.getFile()); |
| 161 | + name += fileIdentifier + "_" + dataRow.getLine() + "_" + dataRow.getColumn() + "_" + dataRow.getNewClassName(); |
159 | 162 | } |
160 | 163 | } |
161 | 164 |
|
@@ -279,6 +282,51 @@ private String getSimpleClassname(String classname) { |
279 | 282 | return classname.substring(idx + 1).replace("$", "_"); |
280 | 283 | } |
281 | 284 |
|
| 285 | + /** |
| 286 | + * Generates a unique file identifier by combining multiple path components |
| 287 | + * with a hash to prevent naming collisions in .mjs and complex file structures |
| 288 | + */ |
| 289 | + private String generateUniqueFileIdentifier(String filePath) { |
| 290 | + if (filePath == null || filePath.isEmpty()) { |
| 291 | + return "unknown"; |
| 292 | + } |
| 293 | + |
| 294 | + // Split the file path by underscores |
| 295 | + String[] pathParts = filePath.split("_"); |
| 296 | + |
| 297 | + // Use last 3 components if available, otherwise use what we have |
| 298 | + StringBuilder identifier = new StringBuilder(); |
| 299 | + int startIndex = Math.max(0, pathParts.length - 3); |
| 300 | + |
| 301 | + for (int i = startIndex; i < pathParts.length; i++) { |
| 302 | + if (identifier.length() > 0) { |
| 303 | + identifier.append("_"); |
| 304 | + } |
| 305 | + identifier.append(pathParts[i]); |
| 306 | + } |
| 307 | + |
| 308 | + // Add a short hash of the full path to ensure uniqueness |
| 309 | + try { |
| 310 | + MessageDigest md = MessageDigest.getInstance("MD5"); |
| 311 | + byte[] hash = md.digest(filePath.getBytes()); |
| 312 | + // Convert to hex and take first 6 characters |
| 313 | + StringBuilder hexString = new StringBuilder(); |
| 314 | + for (int i = 0; i < Math.min(3, hash.length); i++) { |
| 315 | + String hex = Integer.toHexString(0xff & hash[i]); |
| 316 | + if (hex.length() == 1) { |
| 317 | + hexString.append('0'); |
| 318 | + } |
| 319 | + hexString.append(hex); |
| 320 | + } |
| 321 | + identifier.append("_").append(hexString.toString()); |
| 322 | + } catch (NoSuchAlgorithmException e) { |
| 323 | + // Fallback: use hashCode if MD5 is not available |
| 324 | + identifier.append("_").append(Integer.toHexString(Math.abs(filePath.hashCode()))); |
| 325 | + } |
| 326 | + |
| 327 | + return identifier.toString(); |
| 328 | + } |
| 329 | + |
282 | 330 | private void writeBinding(Writer w, DataRow dataRow, JavaClass clazz, String packageName, String name) { |
283 | 331 | GenericsAwareClassHierarchyParser genericsAwareClassHierarchyParser = new GenericsAwareClassHierarchyParserImpl(new GenericSignatureReader(), classes); |
284 | 332 | List<JavaClass> userImplementedInterfaces = getInterfacesFromCache(Arrays.asList(dataRow.getInterfaces())); |
|
0 commit comments