Skip to content

Commit bc3375d

Browse files
committed
Separate handling of legacy rule options from '--rule' options
Firstly, this avoids to emit irrelevant hint messages when only using the new rule option interface. Then, for maintaining purpose, splitting those behavior will help us to remove the old rule options API when the time will come.
1 parent 68ddfbe commit bc3375d

File tree

4 files changed

+136
-26
lines changed

4 files changed

+136
-26
lines changed

lkql_checker/src/gnatcheck-projects.adb

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ package body Gnatcheck.Projects is
10561056
-- Process_Rule_Options --
10571057
--------------------------
10581058

1059-
type Option_Kind is (File, Legacy_Option);
1059+
type Option_Kind is (File, Legacy_Option, Single_Rule_Name);
10601060

10611061
type Option_Record is record
10621062
Kind : Option_Kind;
@@ -1085,6 +1085,9 @@ package body Gnatcheck.Projects is
10851085
when Legacy_Option =>
10861086
Process_Legacy_Rule_Option
10871087
(To_String (O.Value), Defined_At => "");
1088+
1089+
when Single_Rule_Name =>
1090+
Process_Single_Rule_Name (To_String (O.Value));
10881091
end case;
10891092
end loop;
10901093
Process_Compiler_Instances;
@@ -1114,11 +1117,16 @@ package body Gnatcheck.Projects is
11141117

11151118
procedure Add_Rule_By_Name (Rule_Name : String; Prepend : Boolean := False)
11161119
is
1117-
Lower_Rule : constant String := To_Lower (Rule_Name);
1118-
Prefix : constant String :=
1119-
(if Lower_Rule = "all" then "+" else "+R");
1120+
use Ada.Strings.Unbounded;
1121+
1122+
Opt_Rec : constant Option_Record :=
1123+
(Single_Rule_Name, To_Unbounded_String (Trim (Rule_Name, Both)));
11201124
begin
1121-
Add_Legacy_Rule_Option (Prefix & Lower_Rule, Prepend => Prepend);
1125+
if Prepend then
1126+
Rule_Options.Prepend (Opt_Rec);
1127+
else
1128+
Rule_Options.Append (Opt_Rec);
1129+
end if;
11221130
end Add_Rule_By_Name;
11231131

11241132
------------------------

lkql_checker/src/gnatcheck-rules-rule_table.adb

Lines changed: 118 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,22 @@ package body Gnatcheck.Rules.Rule_Table is
104104
function Has_Name_Parameter (R : Rident.All_Restrictions) return Boolean;
105105
-- Tries to guess what kind of parameter the argument restriction has.
106106

107+
function Check_Rule_Exists
108+
(Rule_Name : String; Instantiation_Location : String) return Boolean;
109+
-- Check that provided ``Rule`` designates an existing rule, return
110+
-- ``True`` in that case. Otherwise, set ``Bad_Rule_Detected`` to
111+
-- ``True`` and return ``False``.
112+
113+
function Check_Instance_Is_Unique
114+
(Instance_Name, Instantiation_Location : String) return Boolean;
115+
-- Return whether the given instance name isn't already registered in the
116+
-- global instance table.
117+
-- In case the instance name is already registered this function also sets
118+
-- ``Bad_Rule_Detected`` to ``True``, and displays an error message telling
119+
-- that the instance cannot be instantiated at ``Instantiation_Location``
120+
-- because it has already be registered.
121+
122+
107123
procedure Process_Rule_Object
108124
(LKQL_Rule_File_Name : String;
109125
Instance_Id : String;
@@ -330,6 +346,51 @@ package body Gnatcheck.Rules.Rule_Table is
330346
return Result;
331347
end Has_Natural_Parameter;
332348

349+
-----------------------
350+
-- Check_Rule_Exists --
351+
-----------------------
352+
353+
function Check_Rule_Exists
354+
(Rule_Name : String; Instantiation_Location : String) return Boolean
355+
is
356+
Rule : constant Rule_Id := Get_Rule (Rule_Name);
357+
begin
358+
if not Present (Rule) then
359+
Error
360+
("unknown rule: "
361+
& Rule_Name
362+
& ", ignored"
363+
& Instantiation_Location);
364+
Bad_Rule_Detected := True;
365+
return False;
366+
end if;
367+
return True;
368+
end Check_Rule_Exists;
369+
370+
------------------------------
371+
-- Check_Instance_Is_Unique --
372+
------------------------------
373+
374+
function Check_Instance_Is_Unique
375+
(Instance_Name, Instantiation_Location : String) return Boolean
376+
is
377+
Instance : constant Rule_Instance_Access := Get_Instance (Instance_Name);
378+
begin
379+
if Instance /= null then
380+
Error
381+
("rule instance with the same name already exists: """
382+
& Instance_Name
383+
& """ previously instantiated at "
384+
& (if Instance.Defined_At /= ""
385+
then To_String (Instance.Defined_At)
386+
else "command line")
387+
& Instantiation_Location);
388+
Bad_Rule_Detected := True;
389+
return False;
390+
end if;
391+
return True;
392+
end Check_Instance_Is_Unique;
393+
333394
----------------
334395
-- Is_Enabled --
335396
----------------
@@ -863,6 +924,50 @@ package body Gnatcheck.Rules.Rule_Table is
863924
end if;
864925
end Process_LKQL_Rule_File;
865926

927+
------------------------------
928+
-- Process_Single_Rule_Name --
929+
------------------------------
930+
931+
procedure Process_Single_Rule_Name (Rule_Name : String) is
932+
Lower_Rule_Name : constant String := To_Lower (Rule_Name);
933+
Rule : constant Rule_Id := Get_Rule (Lower_Rule_Name);
934+
begin
935+
-- Handle cases where the rule is "all"
936+
if Lower_Rule_Name = "all" then
937+
Turn_All_Rules_On;
938+
return;
939+
end if;
940+
941+
-- First, check that the designated rule exists
942+
if not Check_Rule_Exists (Lower_Rule_Name, "") then
943+
return;
944+
end if;
945+
946+
-- Then, check that the rule isn't already instantiated
947+
if not Check_Instance_Is_Unique (Lower_Rule_Name, "") then
948+
return;
949+
end if;
950+
951+
-- Finally, check that the designated rule is not a compiler rule
952+
if Is_Compiler_Rule (Rule) then
953+
Error
954+
("Cannot enable a compiler based rule through the '--rule' CLI "
955+
& "option");
956+
Bad_Rule_Detected := True;
957+
return;
958+
end if;
959+
960+
-- Finally create a new default instance for the rule
961+
declare
962+
New_Instance : constant Rule_Instance_Access :=
963+
All_Rules (Rule).Create_Instance (False);
964+
begin
965+
New_Instance.Rule := Rule;
966+
New_Instance.Source_Mode := General;
967+
Turn_Instance_On (New_Instance);
968+
end;
969+
end Process_Single_Rule_Name;
970+
866971
--------------------------------
867972
-- Process_Legacy_Rule_Option --
868973
--------------------------------
@@ -1021,16 +1126,15 @@ package body Gnatcheck.Rules.Rule_Table is
10211126

10221127
-- We start by getting the instantiated rule identifier, and verify
10231128
-- its existence.
1024-
Rule := Get_Rule (Option (Word_Start .. Word_End));
1025-
if not Present (Rule) then
1026-
Error
1027-
("unknown rule: "
1028-
& Option (Word_Start .. Word_End)
1029-
& ", ignored"
1030-
& Diag_Defined_At);
1031-
Bad_Rule_Detected := True;
1032-
return;
1033-
end if;
1129+
declare
1130+
R_Name : constant String := Option (Word_Start .. Word_End);
1131+
begin
1132+
if Check_Rule_Exists (R_Name, Diag_Defined_At) then
1133+
Rule := Get_Rule (Option (Word_Start .. Word_End));
1134+
else
1135+
return;
1136+
end if;
1137+
end;
10341138

10351139
-- Then we get the instance name, either the user defined one, or
10361140
-- the default: the rule name.
@@ -1044,23 +1148,17 @@ package body Gnatcheck.Rules.Rule_Table is
10441148
-- Check that the option is not instantiating a rule with an already
10451149
-- registered instance name. If the option is trying to disable an
10461150
-- instance, check that this instance exists.
1047-
if Enable and then Instance /= null then
1048-
Error
1049-
("rule instance with the same name already exists: """
1050-
& To_String (Instance_Name)
1051-
& """ previously instantiated at "
1052-
& (if Instance.Defined_At /= ""
1053-
then To_String (Instance.Defined_At)
1054-
else "command line")
1055-
& Diag_Defined_At);
1151+
if Enable
1152+
and then not Check_Instance_Is_Unique
1153+
(To_String (Instance_Name), Diag_Defined_At)
1154+
then
10561155
if not Instance_Help_Emitted then
10571156
Info
10581157
("if you want to pass multiple parameters to a rule you "
10591158
& "should use the comma separated notation: e.g. "
10601159
& "+RMy_Rule:Param1,Param2");
10611160
Instance_Help_Emitted := True;
10621161
end if;
1063-
Bad_Rule_Detected := True;
10641162
return;
10651163
elsif not Enable and then Instance = null then
10661164
Error

lkql_checker/src/gnatcheck-rules-rule_table.ads

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ package Gnatcheck.Rules.Rule_Table is
1717
function Present (Rule : Rule_Id) return Boolean;
1818
-- Check if the argument represents an existing rule
1919

20+
procedure Process_Single_Rule_Name (Rule_Name : String);
21+
-- Process the provided rule name by instantiating the corresponding rule
22+
-- with its default configuration. If the lowered provided `Rule_Name` is
23+
-- "all", then all available rules are enabled.
24+
2025
procedure Process_Legacy_Rule_Option (Option : String; Defined_At : String);
2126
-- Processes the rule option taken from the command line or from rule file.
2227
--

testsuite/tests/gnatcheck_errors/same_name_instances/test.out

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ In command-line
1111
===============
1212

1313
gnatcheck: error: rule instance with the same name already exists: "goto_statements" previously instantiated at command line
14-
gnatcheck: info: if you want to pass multiple parameters to a rule you should use the comma separated notation: e.g. +RMy_Rule:Param1,Param2
1514
>>>program returned status code 5
1615

1716
In command-line and rule options

0 commit comments

Comments
 (0)