Skip to content

Commit 061be71

Browse files
committed
Merge branch 'mr/thevenoux/gnatcheck#19' into 'master'
GNATcheck: Improve rule duplicates handling Closes eng/codepeer/gnatcheck#19 See merge request eng/libadalang/langkit-query-language!616
2 parents 412a4e2 + 783ba97 commit 061be71

7 files changed

Lines changed: 171 additions & 17 deletions

File tree

lkql_checker/src/lkql_checker-rules-rule_table.adb

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -413,19 +413,53 @@ package body Lkql_Checker.Rules.Rule_Table is
413413
function Check_Instance_Is_Unique
414414
(Instance_Name, Instantiation_Location : String) return Boolean
415415
is
416+
Is_Legacy_File_Kind : constant Boolean :=
417+
Instantiation_Location'Length > 0;
418+
416419
Instance : constant Rule_Instance_Access := Get_Instance (Instance_Name);
417420
begin
418421
if Instance /= null then
419-
Error
420-
("rule instance with the same name already exists: """
421-
& Instance_Name
422-
& """ previously instantiated at "
423-
& (if Instance.Defined_At /= ""
422+
declare
423+
Location : constant String :=
424+
(if Instance.Defined_At /= ""
424425
then To_String (Instance.Defined_At)
425-
else "command line"),
426-
Location => Instantiation_Location);
427-
Bad_Rule_Detected := True;
428-
return False;
426+
else "command line");
427+
begin
428+
429+
if not Is_Legacy_File_Kind
430+
and then not Instance.Is_Alias
431+
and then not Instance.Has_Parameters
432+
then
433+
-- If the instance to check for uniqueness comes from the
434+
-- command line and is not an alias, we can salefy skip
435+
-- duplicates if the rule has no parameters (we could also
436+
-- compare parameters but this will require to add support to
437+
-- compare them directly from the driver). Emit a simple
438+
-- warning.
439+
440+
Warning
441+
("skipping rule instance """
442+
& Instance_Name
443+
& """ (from command line) previously instantiated at "
444+
& Location);
445+
return True;
446+
else
447+
-- Otherwise, emit an error.
448+
449+
Error
450+
("cannot add rule instance named """
451+
& Instance_Name
452+
& """"
453+
& (if not Is_Legacy_File_Kind
454+
then " (specified from command line)"
455+
else "")
456+
& ", already instantiated at "
457+
& Location,
458+
Location => Instantiation_Location);
459+
Bad_Rule_Detected := True;
460+
return False;
461+
end if;
462+
end;
429463
end if;
430464
return True;
431465
end Check_Instance_Is_Unique;

lkql_checker/src/lkql_checker-rules.adb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3007,6 +3007,22 @@ package body Lkql_Checker.Rules is
30073007

30083008
-- == Overriding operations on rule instances
30093009

3010+
--------------------
3011+
-- Has_Parameters --
3012+
--------------------
3013+
3014+
overriding
3015+
function Has_Parameters (Instance : Custom_Instance) return Boolean is
3016+
begin
3017+
return not Instance.Arguments.Is_Empty;
3018+
end Has_Parameters;
3019+
3020+
overriding
3021+
function Has_Parameters (Instance : Compiler_Instance) return Boolean is
3022+
begin
3023+
return not Instance.Arguments.Is_Empty;
3024+
end Has_Parameters;
3025+
30103026
------------------------------------
30113027
-- Process_Instance_Params_Object --
30123028
------------------------------------

lkql_checker/src/lkql_checker-rules.ads

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ package Lkql_Checker.Rules is
225225
-- Operations that may be redefined by specific rule instances --
226226
-----------------------------------------------------------------
227227

228+
function Has_Parameters (Instance : Rule_Instance) return Boolean
229+
is (False);
230+
-- Return whether the Instance has some parameters set.
231+
228232
procedure Process_Instance_Params_Object
229233
(Instance : in out Rule_Instance; Params_Object : in out JSON_Value)
230234
is null;
@@ -290,6 +294,10 @@ package Lkql_Checker.Rules is
290294
end record;
291295
-- Represents an instance of a rule with only one integer parameter
292296

297+
function Has_Parameters
298+
(Instance : One_Integer_Parameter_Instance) return Boolean
299+
is (True);
300+
293301
overriding
294302
procedure Process_Instance_Params_Object
295303
(Instance : in out One_Integer_Parameter_Instance;
@@ -321,6 +329,10 @@ package Lkql_Checker.Rules is
321329
end record;
322330
-- Represents an instance of a rule with only one boolean parameter
323331

332+
function Has_Parameters
333+
(Instance : One_Boolean_Parameter_Instance) return Boolean
334+
is (True);
335+
324336
overriding
325337
procedure Process_Instance_Params_Object
326338
(Instance : in out One_Boolean_Parameter_Instance;
@@ -351,6 +363,10 @@ package Lkql_Checker.Rules is
351363
end record;
352364
-- Represents an instance of a rule with only one string parameter
353365

366+
function Has_Parameters
367+
(Instance : One_String_Parameter_Instance) return Boolean
368+
is (True);
369+
354370
overriding
355371
procedure Process_Instance_Params_Object
356372
(Instance : in out One_String_Parameter_Instance;
@@ -385,6 +401,10 @@ package Lkql_Checker.Rules is
385401
with null record;
386402
-- Represents an instance of a rule with only on array parameter
387403

404+
function Has_Parameters
405+
(Instance : One_Array_Parameter_Instance) return Boolean
406+
is (True);
407+
388408
overriding
389409
procedure Process_Instance_Params_Object
390410
(Instance : in out One_Array_Parameter_Instance;
@@ -408,6 +428,10 @@ package Lkql_Checker.Rules is
408428
end record;
409429
-- Represents an instance of a rule with one integer and boolean parameters
410430

431+
function Has_Parameters
432+
(Instance : One_Integer_Or_Booleans_Parameter_Instance) return Boolean
433+
is (True);
434+
411435
overriding
412436
procedure Process_Instance_Params_Object
413437
(Instance : in out One_Integer_Or_Booleans_Parameter_Instance;
@@ -447,6 +471,10 @@ package Lkql_Checker.Rules is
447471
end record;
448472
-- Represents an instance of a rule about identifier suffixes
449473

474+
function Has_Parameters
475+
(Instance : Identifier_Suffixes_Instance) return Boolean
476+
is (True);
477+
450478
overriding
451479
procedure Process_Instance_Params_Object
452480
(Instance : in out Identifier_Suffixes_Instance;
@@ -486,6 +514,10 @@ package Lkql_Checker.Rules is
486514
end record;
487515
-- Represents an instance of a rule about identifier prefixes
488516

517+
function Has_Parameters
518+
(Instance : Identifier_Prefixes_Instance) return Boolean
519+
is (True);
520+
489521
overriding
490522
procedure Process_Instance_Params_Object
491523
(Instance : in out Identifier_Prefixes_Instance;
@@ -522,6 +554,10 @@ package Lkql_Checker.Rules is
522554
end record;
523555
-- Represents an instance of a rule about identifiers casing
524556

557+
function Has_Parameters
558+
(Instance : Identifier_Casing_Instance) return Boolean
559+
is (True);
560+
525561
overriding
526562
procedure Process_Instance_Params_Object
527563
(Instance : in out Identifier_Casing_Instance;
@@ -553,6 +589,9 @@ package Lkql_Checker.Rules is
553589
end record;
554590
-- Represents an instance of a rule about forbiddening things
555591

592+
function Has_Parameters (Instance : Forbidden_Instance) return Boolean
593+
is (True);
594+
556595
overriding
557596
procedure Process_Instance_Params_Object
558597
(Instance : in out Forbidden_Instance; Params_Object : in out JSON_Value);
@@ -582,6 +621,10 @@ package Lkql_Checker.Rules is
582621
end record;
583622
-- Represents an instance of a rule about silent exception handlers
584623

624+
function Has_Parameters
625+
(Instance : Silent_Exception_Handlers_Instance) return Boolean
626+
is (True);
627+
585628
overriding
586629
procedure Process_Instance_Params_Object
587630
(Instance : in out Silent_Exception_Handlers_Instance;
@@ -612,6 +655,9 @@ package Lkql_Checker.Rules is
612655
end record;
613656
-- Represents an instance of a rule with arbitrary parameters
614657

658+
overriding
659+
function Has_Parameters (Instance : Custom_Instance) return Boolean;
660+
615661
overriding
616662
procedure Process_Instance_Params_Object
617663
(Instance : in out Custom_Instance; Params_Object : in out JSON_Value);
@@ -639,4 +685,7 @@ package Lkql_Checker.Rules is
639685
Arguments : String_Vector;
640686
end record;
641687

688+
overriding
689+
function Has_Parameters (Instance : Compiler_Instance) return Boolean;
690+
642691
end Lkql_Checker.Rules;

testsuite/drivers/gnatcheck_driver.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,4 +726,15 @@ def output_refiners(self) -> list[OutputRefiner]:
726726
"project search path: <gpr_path>",
727727
)
728728
)
729+
730+
# Remove sloc information for gnatcheck rules temporary files (instances
731+
# order is not deterministic)
732+
if self.test_env.get("canonicalize_gnatcheck_tmp_files", False):
733+
result.append(
734+
PatternSubstitute(
735+
"gnatcheck-rules[0-9]+.TMP:[0-9]+:[0-9]+",
736+
"gnatcheck-rules<N>.TMP:<L>:<C>",
737+
)
738+
)
739+
729740
return result
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
val rules = @{
2+
Slices
3+
}
Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,41 @@
11
In rule options
22
===============
33

4-
gnatcheck: error: rule instance with the same name already exists: "same_alias" previously instantiated at command line
4+
gnatcheck: error: cannot add rule instance named "same_alias" (specified from command line), already instantiated at command line
55
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
6-
gnatcheck: error: rule instance with the same name already exists: "comp_check" previously instantiated at command line
7-
gnatcheck: error: rule instance with the same name already exists: "comp_check" previously instantiated at command line
6+
gnatcheck: error: cannot add rule instance named "comp_check" (specified from command line), already instantiated at command line
7+
gnatcheck: error: cannot add rule instance named "comp_check" (specified from command line), already instantiated at command line
88
>>>program returned status code 5
99

10-
In command-line
11-
===============
10+
In rule options (with alias named after another rule)
11+
=====================================================
12+
13+
gnatcheck: error: cannot add rule instance named "Slices_Alias" (specified from command line), already 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
15+
gnatcheck: error: cannot add rule instance named "Goto_Statements" (specified from command line), already instantiated at command line
16+
gnatcheck: warning: skipping rule instance "slices" (from command line) previously instantiated at command line
17+
gnatcheck-rules<N>.TMP:<L>:<C>: warning: instance slices runs the same check than instance slices_alias declared at gnatcheck-rules<N>.TMP:<L>:<C>
18+
>>>program returned status code 5
19+
20+
In command-line (rules with default arguments)
21+
==============================================
1222

13-
gnatcheck: error: rule instance with the same name already exists: "goto_statements" previously instantiated at command line
23+
gnatcheck: error: cannot add rule instance named "goto_statements" (specified from command line), already instantiated at command line
1424
>>>program returned status code 5
1525

26+
In command-line (rules without arguments)
27+
=========================================
28+
29+
gnatcheck: warning: skipping rule instance "slices" (from command line) previously instantiated at command line
30+
31+
In command-line and rules file (rules without arguments)
32+
========================================================
33+
34+
gnatcheck: warning: skipping rule instance "slices" (from command line) previously instantiated at rules.lkql:1:1
35+
1636
In command-line and rule options
1737
================================
1838

19-
rules.txt:1:1: error: rule instance with the same name already exists: "goto_statements" previously instantiated at command line
39+
rules.txt:1:1: error: cannot add rule instance named "goto_statements", already instantiated at command line
2040
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
2141
>>>program returned status code 5

testsuite/tests/gnatcheck_errors/same_name_instances/test.yaml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
driver: gnatcheck
22
format: brief
3+
canonicalize_gnatcheck_tmp_files: true
34
input_sources:
45
- main.adb
56
tests:
@@ -10,12 +11,32 @@ tests:
1011
- +R:comp_check:Style_Checks:xz
1112
- +R:comp_check:Warnings:u
1213
- +R:comp_check:Restrictions:No_Access_Subprograms
13-
- label: In command-line
14+
- label: In rule options (with alias named after another rule)
15+
rules:
16+
- +R:Slices_Alias:Slices
17+
- +R:Slices_Alias:Slices
18+
- +RGoto_Statements
19+
- +R:Goto_Statements:Slices
20+
- +RSlices
21+
- +RSlices
22+
- label: In command-line (rules with default arguments)
1423
extra_args:
1524
- -r
1625
- goto_statements
1726
- -r
1827
- goto_statements
28+
- label: In command-line (rules without arguments)
29+
extra_args:
30+
- -r
31+
- slices
32+
- -r
33+
- slices
34+
- label: In command-line and rules file (rules without arguments)
35+
extra_args:
36+
- -r
37+
- slices
38+
- --rule-file
39+
- rules.lkql
1940
- label: In command-line and rule options
2041
extra_args:
2142
- -r

0 commit comments

Comments
 (0)