From 96115a6d6eb1d625183d564669df56cede93384e Mon Sep 17 00:00:00 2001 From: Vladiwostok <55026261+Vladiwostok@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:57:57 +0300 Subject: [PATCH] Fix Autofix for DeleteCheck (#144) --- src/dscanner/analysis/del.d | 40 +++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/dscanner/analysis/del.d b/src/dscanner/analysis/del.d index abc60fff..91c09210 100644 --- a/src/dscanner/analysis/del.d +++ b/src/dscanner/analysis/del.d @@ -15,10 +15,12 @@ import dsymbol.scope_; */ extern(C++) class DeleteCheck(AST) : BaseAnalyzerDmd { - // alias visit = BaseAnalyzerDmd!AST.visit; alias visit = BaseAnalyzerDmd.visit; mixin AnalyzerInfo!"delete_check"; + private enum KEY = "dscanner.deprecated.delete_keyword"; + private enum MSG = "Avoid using the 'delete' keyword."; + extern(D) this(string fileName) { super(fileName); @@ -26,8 +28,17 @@ extern(C++) class DeleteCheck(AST) : BaseAnalyzerDmd override void visit(AST.DeleteExp d) { - addErrorMessage(cast(ulong) d.loc.linnum, cast(ulong) d.loc.charnum, "dscanner.deprecated.delete_keyword", - "Avoid using the 'delete' keyword."); + import dmd.hdrgen : toChars; + import std.conv : to; + + string exprStr = to!string(toChars(d)); + + addErrorMessage( + cast(ulong) d.loc.linnum, cast(ulong) d.loc.charnum, KEY, MSG, + [AutoFix.replacement(d.loc.fileOffset, d.loc.fileOffset + 6, `destroy(`, "Replace delete with destroy()") + .concat(AutoFix.insertionAt(d.loc.fileOffset + exprStr.length, ")"))] + ); + super.visit(d); } } @@ -35,10 +46,11 @@ extern(C++) class DeleteCheck(AST) : BaseAnalyzerDmd unittest { import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig; - import dscanner.analysis.helpers : assertAnalyzerWarnings; + import dscanner.analysis.helpers : assertAnalyzerWarnings, assertAutoFix; StaticAnalysisConfig sac = disabledConfig(); sac.delete_check = Check.enabled; + assertAnalyzerWarningsDMD(q{ void testDelete() { @@ -50,5 +62,25 @@ unittest } }c, sac); + assertAutoFix(q{ + void testDelete() + { + int[int] data = [1 : 2]; + delete data[1]; // fix + + auto a = new Class(); + delete a; // fix + } + }c, q{ + void testDelete() + { + int[int] data = [1 : 2]; + destroy(data[1]); // fix + + auto a = new Class(); + destroy(a); // fix + } + }c, sac, true); + stderr.writeln("Unittest for DeleteCheck passed."); }