From 893e77ed3935f39b94705232bb0ea347a194d71a Mon Sep 17 00:00:00 2001 From: Hhyemin Date: Thu, 12 Sep 2024 15:20:51 +0000 Subject: [PATCH] Changes on the new experiment of PUI suppression, worked v2. [Decide move back to the old experiment setting.] --- .../evolution/AccidentalSuppressionFinder.py | 21 ++--- .../AccidentallySuppressedWarning.py | 7 +- .../evolution/MapWarningLines.py | 78 ++++++------------- 3 files changed, 35 insertions(+), 71 deletions(-) diff --git a/src/suppression_study/evolution/AccidentalSuppressionFinder.py b/src/suppression_study/evolution/AccidentalSuppressionFinder.py index cf59da2..8d7e420 100644 --- a/src/suppression_study/evolution/AccidentalSuppressionFinder.py +++ b/src/suppression_study/evolution/AccidentalSuppressionFinder.py @@ -161,35 +161,25 @@ def check_for_accidental_suppressions(repo_dir, history, relevant_commits, relev # if a new warning shows up that wasn't suppressed by this suppression # at the previous commit, create an AccidentallySuppressedWarning if warnings_suppressed_at_previous_commit is not None: - to_append = False if suppression is not None: - refined_warnings = [] + new_warning_hinder = None num_new_warning = 0 current_len = len(warnings_suppressed_at_commit) previous_len = len(warnings_suppressed_at_previous_commit) if previous_len > current_len: pass - elif previous_len == current_len and warnings_suppressed_at_previous_commit != warnings_suppressed_at_commit: + elif previous_len == current_len and warnings_suppressed_at_previous_commit != warnings_suppressed_at_commit: # backup_warnings_suppressed_at_previous_commit = [w for w in warnings_suppressed_at_previous_commit] backup_warnings_suppressed_at_commit = [w for w in warnings_suppressed_at_commit] # the warnings may different, run diff to check the line number maps - refined_warnings, num_new_warning = MapWarningLines(repo_dir, previous_commit, commit, \ + new_warning_hinder, num_new_warning = MapWarningLines(repo_dir, previous_commit, commit, \ backup_warnings_suppressed_at_previous_commit, backup_warnings_suppressed_at_commit ).check_warning_mapping() - if refined_warnings == None: - pass # ignore the cases - else: - if num_new_warning > 0: - to_append == True elif previous_len < current_len: - to_append = True num_new_warning = current_len - previous_len - if to_append == True: + if num_new_warning > 0: # there's a new warning suppressed by this suppression summary = f"from {previous_len} to {current_len}, new warnings: {num_new_warning}" - warnings_suppressed_at_commit_v = warnings_suppressed_at_commit - if refined_warnings: - warnings_suppressed_at_commit_v = refined_warnings accidentally_suppressed_warnings.append( AccidentallySuppressedWarning(summary, previous_commit, @@ -197,7 +187,8 @@ def check_for_accidental_suppressions(repo_dir, history, relevant_commits, relev previous_suppression, suppression, warnings_suppressed_at_previous_commit, - warnings_suppressed_at_commit_v)) + warnings_suppressed_at_commit, + new_warning_hinder)) previous_commit = commit previous_suppression = suppression warnings_suppressed_at_previous_commit = warnings_suppressed_at_commit diff --git a/src/suppression_study/evolution/AccidentallySuppressedWarning.py b/src/suppression_study/evolution/AccidentallySuppressedWarning.py index 582db31..dafeccc 100644 --- a/src/suppression_study/evolution/AccidentallySuppressedWarning.py +++ b/src/suppression_study/evolution/AccidentallySuppressedWarning.py @@ -2,7 +2,8 @@ class AccidentallySuppressedWarning: - def __init__(self, summary, previous_commit, commit, previous_suppression, suppression, previous_warnings, warnings): + def __init__(self, summary, previous_commit, commit, previous_suppression, suppression, \ + previous_warnings, warnings, new_warning_hinder): self.summary = summary self.previous_commit = previous_commit self.commit = commit @@ -10,6 +11,7 @@ def __init__(self, summary, previous_commit, commit, previous_suppression, suppr self.suppression = suppression self.previous_warnings = previous_warnings self.warnings = warnings + self.new_warning_hinder = new_warning_hinder def __lt__(self, other): """Sort based on attributes. Useful for getting a deterministic order when writing to a file.""" @@ -42,7 +44,8 @@ def to_dict(self): "line": self.suppression.line }, "previous_warnings": [{"path": w.path, "kind": w.kind, "line": w.line} for w in sorted(self.previous_warnings)], - "warnings": [{"path": w.path, "kind": w.kind, "line": w.line} for w in sorted(self.warnings)] + "warnings": [{"path": w.path, "kind": w.kind, "line": w.line} for w in sorted(self.warnings)], + "new_warning_hinder": self.new_warning_hinder } return d diff --git a/src/suppression_study/evolution/MapWarningLines.py b/src/suppression_study/evolution/MapWarningLines.py index 54b91f2..9a88d6c 100644 --- a/src/suppression_study/evolution/MapWarningLines.py +++ b/src/suppression_study/evolution/MapWarningLines.py @@ -10,17 +10,14 @@ def __init__(self, repo_dir, pre_c, c, pre_warnings, warnings): self.pre_warnings = pre_warnings self.warnings = warnings - self.refined_warnings = [] - self.mapped_warning_lines = [] + self.new_warning_hinder = [] + self.overall_new_warning_counts = 0 def check_warning_mapping(self): pre_file = self.pre_warnings[0].path file = self.warnings[0].path - for w in self.pre_warnings: - self.mapped_warning_lines.append(w.line) - - commit_diff_command = f"git diff --word-diff --unified=0 {self.pre_c}:{pre_file} {self.c}:{file}" + commit_diff_command = f"git diff --unified=0 {self.pre_c}:{pre_file} {self.c}:{file}" diff_result = subprocess.run(commit_diff_command, cwd=self.repo_dir, shell=True, stdout=subprocess.PIPE, universal_newlines=True) diff_contents = diff_result.stdout @@ -30,55 +27,28 @@ def check_warning_mapping(self): diff_line = diff_line.strip() if diff_line.startswith("@@"): tmp = diff_line.split(" ") - base_hunk_range, base_step = get_diff_reported_range(tmp[1]) - for i, w, warning_line in zip(range(len(self.pre_warnings)), self.pre_warnings, self.mapped_warning_lines): - if warning_line < base_hunk_range.start: - self.map_helper(w, warning_line) - else: - target_hunk_range, target_step = get_diff_reported_range(tmp[2], False) - if warning_line in list(base_hunk_range): - ref_delta = warning_line - base_hunk_range.start - may_mapped_line = target_hunk_range.start + ref_delta - self.map_helper(w, may_mapped_line) - else: - move_steps = target_step - base_step - self.mapped_warning_lines[i] += move_steps - - if not self.mapped_warning_lines: - break - - if self.mapped_warning_lines: - # map the warning after the last changed hunk - for w, warning_line in zip(self.pre_warnings, self.mapped_warning_lines): - self.map_helper(w, warning_line) - if self.mapped_warning_lines: - print(f"Inaccurate mapping happens. Current commit: {self.c}, file path: {file}") - return None, False - - self.refined_warnings.append(None) # A symbol to start adding new warnings - is_new_warning = [] - for w in self.warnings: - if w not in self.refined_warnings: - self.refined_warnings.append(w) - is_new_warning.append(True) - # print(f"{len(is_new_warning)}: is_new_warning") - return self.refined_warnings, len(is_new_warning) # the number of new warnings + base_hunk_range = get_diff_reported_range(tmp[1]) + target_hunk_range = get_diff_reported_range(tmp[2], False) + base_hunk_lines = list(base_hunk_range) + target_hunk_lines = list(target_hunk_range) + previous_warning_line_in_hunk = [w.line for w in self.pre_warnings if w.line in base_hunk_lines] + current_warning_line_in_hunk = [w.line for w in self.warnings if w.line in target_hunk_lines] + previous_len = len(previous_warning_line_in_hunk) + current_len = len(current_warning_line_in_hunk) - def map_helper(self, warning, warning_line): - updated_w = Warning(warning.path, warning.kind, warning_line) - for w in self.warnings: - if updated_w == w: # old warning - self.refined_warnings.append(updated_w) - self.warnings.remove(updated_w) - break - self.refined_warnings.append(None) # mean the self.warnings fixed/disappeared - # do not check the mapped line for it anymore - try: - self.mapped_warning_lines.remove(warning_line) - except: - print(f"{warning_line} and {w.line}") - self.pre_warnings.remove(warning) + if previous_len < current_len: + # new warning occurs + new_warning_count = current_len - previous_len + self.overall_new_warning_counts += new_warning_count + self.new_warning_hinder.append({ + "new_warnings": new_warning_count, + "base_hunk": f"{base_hunk_range}", + "target_hunk": f"{target_hunk_range}", + "mapped_previous_warnings": f"{previous_warning_line_in_hunk}", + "potential_new_warnings": f"{current_warning_line_in_hunk}"}) + return self.new_warning_hinder, self.overall_new_warning_counts + def get_diff_reported_range(meta_range, base=True): ''' @@ -110,4 +80,4 @@ def get_diff_reported_range(meta_range, base=True): reported_range = range(start, end) # [x, y) - return reported_range, step \ No newline at end of file + return reported_range \ No newline at end of file