CoolFace
Apppublic

OSS-forge/CodeQualityEval

sourceHugging Facecc-by-sa-4.0updated 10mo agoView on Hugging Face
12likes
process_PMD_results.py132 linesDownload Raw Back to 3_Code_Defects_Analysis
1import json2import os3import re4import pandas as pd5from collections import Counter, defaultdict6 7# === CONFIG ===8REPORTS_DIR = "./reports"  # folder with files report_*.json9ODC_MAPPING_FILE = "../2_ODC_Mapping/Mapping_PMD_ODC.xlsx"  # mapping PMD rule -> ODC10EXCLUDED_RULES = {11    "AvoidDuplicateLiterals",12    "UseLocaleWithCaseConversions",13    "AbstractClassWithoutAbstractMethod", 14    "AccessorClassGeneration",15    "AbstractClassWithoutAnyMethod",16    "ClassWithOnlyPrivateConstructorsShouldBeFinal", 17    "DataClass",18    "GodClass", 19    "CloneMethodReturnTypeMustMatchClassName",20    "MethodWithSameNameAsEnclosingClass", 21    "MissingStaticMethodInNonInstantiatableClass", 22    "UseUtilityClass", 23    "LawOfDemeter", 24    "UnusedPrivateMethod", 25    "AvoidLiteralsInIfCondition"26}27 28# === Load mapping PMD -> ODC ===29mapping_df = pd.read_excel(ODC_MAPPING_FILE, engine="openpyxl")30odc_map = dict(zip(mapping_df["PMD Rule"], mapping_df["ODC Defect Type"]))31 32#input("Did you change the total size of the dataset?")33 34total_size = 100 # total number of samples in the dataset 35 36total_defects = 037odc_counter = Counter()38rule_counter = Counter()39unique_defective_files = set()40defects_by_file = defaultdict(list)41rules_by_odc = defaultdict(Counter)42 43# === NUOVE VARIABILI PER ERRORI ===44processing_errors = defaultdict(int)45error_types_count = Counter()46parse_exception_filenames = set()47priority_counter = Counter()48exception_regex = re.compile(r"(\w+Exception)")49 50# === PARSING FILES REPORT ===51for fname in os.listdir(REPORTS_DIR):52    if fname.startswith("report_") and fname.endswith(".json"):53        with open(os.path.join(REPORTS_DIR, fname)) as f:54            data = json.load(f)55 56        # === ERRORI DI PARSING ===57        if "processingErrors" in data:58            for error in data["processingErrors"]:59                processing_errors["total"] += 160 61                message = error.get("message", "")62                match = exception_regex.search(message)63                if match:64                    error_type = match.group(1)65                    error_types_count[error_type] += 166 67                    if error_type == "ParseException":68                        filename = error.get("filename")69                        if filename:70                            parse_exception_filenames.add(filename)71 72 73        for file_entry in data.get("files", []):74            filename = file_entry.get("filename")75            has_valid_defect = False76 77            for violation in file_entry.get("violations", []):78                rule = violation.get("rule")79                odc = odc_map.get(rule, "--")80                priority = violation.get("priority")81                if priority:82                    priority_counter[priority] += 183 84                if rule in EXCLUDED_RULES:85                    continue  # skip excluded rules86 87                if odc != "--":88                    total_defects += 189                    odc_counter[odc] += 190                    rule_counter[rule] += 191                    defects_by_file[filename].append(odc)92                    rules_by_odc[odc][rule] += 193                    has_valid_defect = True94 95            if has_valid_defect:96                unique_defective_files.add(filename)97 98unique_instance_count = len(unique_defective_files)99average_defects_per_instance = total_defects / unique_instance_count if unique_instance_count else 0100 101print("\nPMD + ODC stats")102print("────────────────────────────")103print(f"Total number of samples: {total_size}")104print(f"Total number of defects: {total_defects}")105print(f"Total number of defective samples: {unique_instance_count} ({(unique_instance_count/total_size)*100:.2f}%)")106print(f"Average number of defects per sample: {average_defects_per_instance:.2f}")107print(f"Total number of samples with ParseException: {len(parse_exception_filenames)} ({(len(parse_exception_filenames)/total_size)*100:.2f}%)")108 109print("\nTotal defects divided per ODC Defect Type:")110for category, count in odc_counter.most_common():111    print(f"  - {category}: {count}")112 113print("\nTop 10 defect:")114for rule, count in rule_counter.most_common(10):115    print(f"  - {rule}: {count}")116 117print("\nDistribution of ODC Defect Types per sample:")118distribution = Counter(len(set(v)) for v in defects_by_file.values())119for num_cats, count in sorted(distribution.items()):120    print(f"  - {count} samples in {num_cats} different ODC defect types")121 122print("\nDistrbution of defects per ODC Defect Type:")123for odc, rule_counter in rules_by_odc.items():124    print(f"\n {odc} ({sum(rule_counter.values())})")125    for rule, count in rule_counter.most_common():126        print(f"   • {rule}: {count}")127 128print("\nDistribution of defects per priority (severity):")129for p, count in sorted(priority_counter.items()):130    print(f"  - Priority {p}: {count}")131 132