Skip to content

Commit 2795605

Browse files
committed
Add safe descriptor codemod automation
1 parent 4f17e9e commit 2795605

5 files changed

Lines changed: 1004 additions & 12 deletions

File tree

docs/source/api/public_api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ field-forwarding wrappers as factorable product morphisms when they preserve
3434
common fields and do not own an invariant.
3535

3636
.. automodule:: nominal_refactor_advisor.codemod
37-
:members: PlannedSourceRewrite, CodemodStrategy, CodemodStrategyRegistry, CodemodApplicability, CodemodCandidate, CodemodSimulationReport, codemod_candidates_from_impact_ranking, simulate_planned_rewrites, CancelableCompositionSignal, detect_cancelable_composition_signals
37+
:members: PlannedSourceRewrite, CodemodStrategy, CodemodStrategyRegistry, CodemodRewriteBuilder, SortedTupleWrapperCodemodBuilder, SourceLocationEvidencePropertyCodemodBuilder, ZippedSourceLocationEvidencePropertyCodemodBuilder, CodemodApplicability, CodemodCandidate, CodemodSimulationReport, codemod_candidates_from_impact_ranking, codemod_candidates_with_automated_rewrites, simulate_planned_rewrites, CancelableCompositionSignal, detect_cancelable_composition_signals
3838

3939

4040
Result Records And Taxonomy

nominal_refactor_advisor/__init__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,22 @@
5151
"nominal_refactor_advisor.codemod",
5252
"CodemodStrategyRegistry",
5353
),
54+
"CodemodRewriteBuilder": (
55+
"nominal_refactor_advisor.codemod",
56+
"CodemodRewriteBuilder",
57+
),
58+
"SortedTupleWrapperCodemodBuilder": (
59+
"nominal_refactor_advisor.codemod",
60+
"SortedTupleWrapperCodemodBuilder",
61+
),
62+
"SourceLocationEvidencePropertyCodemodBuilder": (
63+
"nominal_refactor_advisor.codemod",
64+
"SourceLocationEvidencePropertyCodemodBuilder",
65+
),
66+
"ZippedSourceLocationEvidencePropertyCodemodBuilder": (
67+
"nominal_refactor_advisor.codemod",
68+
"ZippedSourceLocationEvidencePropertyCodemodBuilder",
69+
),
5470
"CancelableCompositionSignal": (
5571
"nominal_refactor_advisor.codemod",
5672
"CancelableCompositionSignal",
@@ -67,6 +83,10 @@
6783
"nominal_refactor_advisor.codemod",
6884
"codemod_candidates_from_impact_ranking",
6985
),
86+
"codemod_candidates_with_automated_rewrites": (
87+
"nominal_refactor_advisor.codemod",
88+
"codemod_candidates_with_automated_rewrites",
89+
),
7090
"simulate_planned_rewrites": (
7191
"nominal_refactor_advisor.codemod",
7292
"simulate_planned_rewrites",

nominal_refactor_advisor/cli.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@
2828
format_calibration_markdown,
2929
run_calibration_manifest,
3030
)
31-
from .codemod import CodemodCandidate, codemod_candidates_from_impact_ranking
31+
from .codemod import (
32+
CodemodCandidate,
33+
codemod_candidates_from_impact_ranking,
34+
codemod_candidates_with_automated_rewrites,
35+
)
3236
from .detectors import DetectorConfig
3337
from .economics import (
3438
EconomicsProofReport,
@@ -276,6 +280,11 @@ def _json_payload(
276280
impact_ranking,
277281
source_index,
278282
)
283+
codemod_candidates = codemod_candidates_with_automated_rewrites(
284+
codemod_candidates,
285+
source_index,
286+
{str(module.path): module.source for module in modules},
287+
)
279288
if codemod_candidates is not None:
280289
payload["codemod_candidates"] = tuple(
281290
candidate.to_dict() for candidate in codemod_candidates
@@ -484,6 +493,9 @@ def format_codemod_applicability_markdown(
484493
for candidate in candidates
485494
)
486495
)
496+
safe_count = sum(
497+
(candidate.applicability.safe_to_apply for candidate in candidates)
498+
)
487499
ready_count = sum(
488500
(
489501
candidate.applicability.simulation_status.value == "ready_to_simulate"
@@ -494,6 +506,7 @@ def format_codemod_applicability_markdown(
494506
lines.append(
495507
" - Candidates: "
496508
f"{len(candidates)}; advisory-only: {advisory_count}; "
509+
f"safe mechanical: {safe_count}; "
497510
f"planned rewrites: {planned_count}; ready to simulate: {ready_count}"
498511
)
499512
for index, candidate in enumerate(candidates[:10], start=1):
@@ -503,6 +516,7 @@ def format_codemod_applicability_markdown(
503516
f"`{candidate.opportunity_key.label}` -> "
504517
f"{candidate.target_count} target(s), "
505518
f"{candidate.predicted_removed_finding_count} finding(s), "
519+
f"{applicability.planned_rewrite_count} planned rewrite(s), "
506520
f"simulation {applicability.simulation_status.value}"
507521
)
508522
lines.append(f" strategy: {applicability.strategy_id}")
@@ -787,6 +801,7 @@ def main() -> int:
787801
impact_ranking = None
788802
if args.include_impact_ranking:
789803
source_index = build_source_index(modules, findings)
804+
source_by_path = {str(module.path): module.source for module in modules}
790805
impact_ranking = build_refactor_impact_ranking(
791806
findings,
792807
source_index,
@@ -801,6 +816,11 @@ def main() -> int:
801816
impact_ranking,
802817
source_index,
803818
)
819+
codemod_candidates = codemod_candidates_with_automated_rewrites(
820+
codemod_candidates,
821+
source_index,
822+
source_by_path,
823+
)
804824
else:
805825
codemod_candidates = None
806826
if args.json:

0 commit comments

Comments
 (0)