jeremiah-c-leary / vhdl-style-guide

Style guide enforcement for VHDL
GNU General Public License v3.0
192 stars 39 forks source link

Add consistent case rules for parameter names in subprograms #1310

Open JHertz5 opened 1 week ago

JHertz5 commented 1 week ago

Is your feature request related to a problem? Please describe. I would like to be able to enforce consistent case of parameter names in functions and procedures, e.g. correcting

  procedure my_proc (
    i_param : in  integer;
    o_param : out integer
  ) is
  begin
    O_PARAM := I_PARAM;
  end procedure;

to

  procedure my_proc (
    i_param : in  integer;
    o_param : out integer
  ) is
  begin
    o_param := i_param;
  end procedure;

Describe the solution you'd like I would like new rules to enforce consistent case for the cases described above.

Additional context This issue was split out from #1251, which is related to #1249. See this comment for details on how the solution for this issue may look.

JHertz5 commented 5 days ago

The challenge here comes from nested subprograms. As mentioned on #1254, nested subprograms still have visibility of the parameters (or any other declaration, in fact) of the outer subprogram unless that parameter is hidden by another declaration that has the same identifier within the inner subprogram.

For example, the following would be correct output from this consistent case rule:

  procedure my_proc1 (
    i_param : in  integer;
    o_param : out integer
  ) is

    procedure my_proc2 (
      I_PARAM : in boolean
    ) is
    begin

      report to_string(I_PARAM) & to_string(o_param);

    end procedure my_proc2;

  begin

    o_param := i_param;

  end procedure my_proc1;

In this code, the my_proc2 would have visibility of o_param of my_proc1, but my_proc2's parameter i_param hides my_proc1's i_param within the scope of my_proc2. This holds true for other declaration types as well. For example, the following would be correct output from this rule:

  procedure my_proc1 (
    i_param : in  integer;
    o_param : out integer
  ) is

    procedure my_proc2 is
      constant I_PARAM : integer := 1;
    begin

      report to_string(I_PARAM) & to_string(o_param);

    end procedure my_proc2;

  begin

    o_param := i_param;

  end procedure my_proc1;

Again, o_param of my_proc1 is visible within the scope of my_proc2, by i_param of my_proc1 is hidden within the scope of my_proc2 by a constant that has the same identifier.

As a result, the steps that this consistent case rule needs to follow would look something like this:

  1. Construct the list of formal parameter names for this subprogram.
  2. Construct a list of each instances of these formal parameter names being used - we'll need to identify the token types that we want to check.
  3. Find cases within nested subprograms.
  4. For each case within a nested subprogram, check whether the formal parameter name is hidden by any declarations within the inner subprogram.
  5. Remove these from the list.
  6. Produce violations for each list element that doesn't match consistent case.