|
| 1 | +#!/usr/bin/env python3 |
| 2 | +import sys |
| 3 | +import os |
| 4 | + |
| 5 | + |
| 6 | +def extract_comments(lines): |
| 7 | + comments_map = {} |
| 8 | + in_block_comment = False |
| 9 | + comment_buffer = [] |
| 10 | + |
| 11 | + for line in lines: |
| 12 | + stripped = line.strip() |
| 13 | + |
| 14 | + # Gestione commenti multiriga (JSDoc e /* */) |
| 15 | + if not in_block_comment and stripped.startswith("/*"): |
| 16 | + in_block_comment = True |
| 17 | + comment_buffer.append(line) |
| 18 | + if "*/" in stripped: # Commento aperto e chiuso sulla stessa riga |
| 19 | + in_block_comment = False |
| 20 | + continue |
| 21 | + |
| 22 | + if in_block_comment: |
| 23 | + comment_buffer.append(line) |
| 24 | + if "*/" in stripped: |
| 25 | + in_block_comment = False |
| 26 | + continue |
| 27 | + |
| 28 | + # Gestione commenti singola riga (solo se occupano tutta la riga) |
| 29 | + if stripped.startswith("//"): |
| 30 | + comment_buffer.append(line) |
| 31 | + continue |
| 32 | + |
| 33 | + # Se abbiamo un buffer pieno e troviamo una riga di codice valida (l'ancora) |
| 34 | + if comment_buffer and stripped: |
| 35 | + anchor = stripped |
| 36 | + # Ignoriamo ancore troppo generiche (es. solo una graffa) per evitare falsi positivi |
| 37 | + if len(anchor) > 2: |
| 38 | + if anchor not in comments_map: |
| 39 | + comments_map[anchor] = [] |
| 40 | + # Salviamo il blocco di commenti associato a questa riga di codice |
| 41 | + comments_map[anchor].append("".join(comment_buffer)) |
| 42 | + |
| 43 | + comment_buffer = [] # Reset del buffer |
| 44 | + |
| 45 | + return comments_map |
| 46 | + |
| 47 | + |
| 48 | +def restore(orig_file, stripped_file, output_file): |
| 49 | + if not os.path.exists(orig_file) or not os.path.exists(stripped_file): |
| 50 | + print("❌ Errore: Uno dei file di input non esiste.") |
| 51 | + sys.exit(1) |
| 52 | + |
| 53 | + with open(orig_file, "r", encoding="utf-8") as f: |
| 54 | + orig_lines = f.readlines() |
| 55 | + |
| 56 | + with open(stripped_file, "r", encoding="utf-8") as f: |
| 57 | + stripped_lines = f.readlines() |
| 58 | + |
| 59 | + print(f"[*] Analisi del file originale in corso...") |
| 60 | + comments_map = extract_comments(orig_lines) |
| 61 | + total_blocks = sum(len(v) for v in comments_map.values()) |
| 62 | + print(f"[*] Trovati {total_blocks} blocchi di commenti/JSDoc mappati ad ancore.") |
| 63 | + |
| 64 | + output_lines = [] |
| 65 | + restored_count = 0 |
| 66 | + |
| 67 | + for line in stripped_lines: |
| 68 | + stripped = line.strip() |
| 69 | + |
| 70 | + # Se la riga corrente del nuovo file corrisponde a un'ancora mappata |
| 71 | + if stripped in comments_map and comments_map[stripped]: |
| 72 | + # Pop() garantisce l'ordine cronologico se ci sono ancore identiche |
| 73 | + comment_block = comments_map[stripped].pop(0) |
| 74 | + output_lines.append(comment_block) |
| 75 | + restored_count += 1 |
| 76 | + |
| 77 | + output_lines.append(line) |
| 78 | + |
| 79 | + with open(output_file, "w", encoding="utf-8") as f: |
| 80 | + f.writelines(output_lines) |
| 81 | + |
| 82 | + print(f"[+] Operazione Completata!") |
| 83 | + print(f"[+] Ripristinati {restored_count} su {total_blocks} blocchi di commenti/tipi.") |
| 84 | + print(f"[+] Nuovo file salvato in: {output_file}") |
| 85 | + |
| 86 | + |
| 87 | +if __name__ == "__main__": |
| 88 | + if len(sys.argv) != 4: |
| 89 | + print("Uso: python3 cc-restore-types.py <file_vecchio_con_commenti.js> <file_nuovo_tagliato.js> <output_ripristinato.js>") |
| 90 | + print("Esempio: python3 cc-restore-types.py script_v1.js script_v2.js script_v2_commentato.js") |
| 91 | + sys.exit(1) |
| 92 | + |
| 93 | + restore(sys.argv[1], sys.argv[2], sys.argv[3]) |
0 commit comments