diff --git a/docs/configuring_keyword_alignment_rules.rst b/docs/configuring_keyword_alignment_rules.rst index 3565b5a91..bc15d115f 100644 --- a/docs/configuring_keyword_alignment_rules.rst +++ b/docs/configuring_keyword_alignment_rules.rst @@ -992,3 +992,4 @@ Rules Enforcing Keyword Alignment * `subprogram_body_400 `_ * `subprogram_body_401 `_ * `type_400 `_ +* `variable_401 `_ diff --git a/docs/rule_groups/alignment_rule_group.rst b/docs/rule_groups/alignment_rule_group.rst index 67723a43f..9091300f3 100644 --- a/docs/rule_groups/alignment_rule_group.rst +++ b/docs/rule_groups/alignment_rule_group.rst @@ -79,6 +79,7 @@ Rules Enforcing Alignment Rule Group * `subprogram_body_401 <../subprogram_body_rules.html#subprogram-body-401>`_ * `type_400 <../type_rules.html#type-400>`_ * `variable_400 <../variable_rules.html#variable-400>`_ +* `variable_401 <../variable_rules.html#variable-401>`_ * `variable_assignment_004 <../variable_assignment_rules.html#variable-assignment-004>`_ * `variable_assignment_400 <../variable_assignment_rules.html#variable-assignment-400>`_ * `variable_assignment_401 <../variable_assignment_rules.html#variable-assignment-401>`_ diff --git a/docs/variable_rules.rst b/docs/variable_rules.rst index 338d38ecb..bdc88586f 100644 --- a/docs/variable_rules.rst +++ b/docs/variable_rules.rst @@ -418,6 +418,35 @@ This rule checks alignment of multiline constraints in variable declarations. element2(3 downto 0) ); +variable_401 +############ + +|phase_5| |error| |alignment| + +This rule checks the alignment of assignment keywords in variable declarations. + +|configuring_keyword_alignment_rules_link| + +**Violation** + +.. code-block:: vhdl + + variable v_default_values : t_address_en := ( + c_address_control => false, + c_address_data => true, + others => false + ); + +**Fix** + +.. code-block:: vhdl + + variable v_default_values : t_address_en := ( + c_address_control => false, + c_address_data => true, + others => false + ); + variable_500 ############ diff --git a/tests/variable/rule_401_test_input.fixed_no_no_no_no_no.vhd b/tests/variable/rule_401_test_input.fixed_no_no_no_no_no.vhd new file mode 100644 index 000000000..57f0a78c1 --- /dev/null +++ b/tests/variable/rule_401_test_input.fixed_no_no_no_no_no.vhd @@ -0,0 +1,105 @@ +architecture rtl of fifo is + +begin + + process + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + -- Test hierarchical assignments + -- Desired alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Invalid alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Test single line aggregates + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_2 => ( + AA => 1, + BBBBBBB => ((others => '0')), + CC => 3 -- Not aligned! + ) + ); + + begin + + end process; + +end architecture rtl; diff --git a/tests/variable/rule_401_test_input.fixed_yes_no_no_no_no.vhd b/tests/variable/rule_401_test_input.fixed_yes_no_no_no_no.vhd new file mode 100644 index 000000000..372c6f03c --- /dev/null +++ b/tests/variable/rule_401_test_input.fixed_yes_no_no_no_no.vhd @@ -0,0 +1,105 @@ +architecture rtl of fifo is + +begin + + process + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + -- Test hierarchical assignments + -- Desired alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Invalid alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Test single line aggregates + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_2 => ( + AA => 1, + BBBBBBB => ((others => '0')), + CC => 3 -- Not aligned! + ) + ); + + begin + + end process; + +end architecture rtl; diff --git a/tests/variable/rule_401_test_input.fixed_yes_no_yes_no_no.vhd b/tests/variable/rule_401_test_input.fixed_yes_no_yes_no_no.vhd new file mode 100644 index 000000000..08645b6e1 --- /dev/null +++ b/tests/variable/rule_401_test_input.fixed_yes_no_yes_no_no.vhd @@ -0,0 +1,105 @@ +architecture rtl of fifo is + +begin + + process + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + -- Test hierarchical assignments + -- Desired alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Invalid alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Test single line aggregates + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_2 => ( + AA => 1, + BBBBBBB => ((others => '0')), + CC => 3 -- Not aligned! + ) + ); + + begin + + end process; + +end architecture rtl; diff --git a/tests/variable/rule_401_test_input.fixed_yes_yes_no_no_no.vhd b/tests/variable/rule_401_test_input.fixed_yes_yes_no_no_no.vhd new file mode 100644 index 000000000..94d2224a3 --- /dev/null +++ b/tests/variable/rule_401_test_input.fixed_yes_yes_no_no_no.vhd @@ -0,0 +1,105 @@ +architecture rtl of fifo is + +begin + + process + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + -- Test hierarchical assignments + -- Desired alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Invalid alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Test single line aggregates + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_2 => ( + AA => 1, + BBBBBBB => ((others => '0')), + CC => 3 -- Not aligned! + ) + ); + + begin + + end process; + +end architecture rtl; diff --git a/tests/variable/rule_401_test_input.fixed_yes_yes_yes_yes_no.vhd b/tests/variable/rule_401_test_input.fixed_yes_yes_yes_yes_no.vhd new file mode 100644 index 000000000..7186a7357 --- /dev/null +++ b/tests/variable/rule_401_test_input.fixed_yes_yes_yes_yes_no.vhd @@ -0,0 +1,105 @@ +architecture rtl of fifo is + +begin + + process + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + -- Test hierarchical assignments + -- Desired alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Invalid alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Test single line aggregates + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_2 => ( + AA => 1, + BBBBBBB => ((others => '0')), + CC => 3 -- Not aligned! + ) + ); + + begin + + end process; + +end architecture rtl; diff --git a/tests/variable/rule_401_test_input.fixed_yes_yes_yes_yes_yes.vhd b/tests/variable/rule_401_test_input.fixed_yes_yes_yes_yes_yes.vhd new file mode 100644 index 000000000..e530028c4 --- /dev/null +++ b/tests/variable/rule_401_test_input.fixed_yes_yes_yes_yes_yes.vhd @@ -0,0 +1,105 @@ +architecture rtl of fifo is + +begin + + process + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + -- Test hierarchical assignments + -- Desired alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Invalid alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Test single line aggregates + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_2 => ( + AA => 1, + BBBBBBB => ((others => '0')), + CC => 3 -- Not aligned! + ) + ); + + begin + + end process; + +end architecture rtl; diff --git a/tests/variable/rule_401_test_input.vhd b/tests/variable/rule_401_test_input.vhd new file mode 100644 index 000000000..f768c8d73 --- /dev/null +++ b/tests/variable/rule_401_test_input.vhd @@ -0,0 +1,105 @@ +architecture rtl of fifo is + +begin + + process + variable v_my_rec : t_my_rec := + ( + signal_one => '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour => '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A => true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others => false + ); + + variable v_my_rec : t_my_rec := + ( + signal_one=> '0', + signal_onetwo => '0', + + signal_onetwothree => '0', + signal_onetwothreefour=> '0', + -- Comment + signal_onetwothreefourfive => '0', + signal_onetwothreefourfivesix => '0' + ); + + variable v_default_values : t_address_en := ( + C_ADDRESS_CONTROL_A => false, + C_ADDRESS_DATA_A=> true, + others => false + + C_ADDRESS_CONTROL_B => false, + C_ADDRESS_DATA_B => true, + others => false + -- Comment + C_ADDRESS_CONTROL_C => false, + C_ADDRESS_DATA_C => true, + others=> false + ); + + -- Test hierarchical assignments + -- Desired alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_224 => ( + AA => 1, + BB => 2, + CC => 3 + ) + ); + + -- Invalid alignment + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B=> 2, + C => 3 + ), + ENUM_224=> ( + AA=> 1, + BB => 2, + CC => 3 + ) + ); + + -- Test single line aggregates + variable v_my_var : my_type := ( + ENUM_1 => ( + A => 1, + B => 2, + C => 3 + ), + ENUM_2 => ( + AA => 1, + BBBBBBB => ((others => '0')), + CC => 3 -- Not aligned! + ) + ); + + begin + + end process; + +end architecture rtl; diff --git a/tests/variable/test_rule_401.py b/tests/variable/test_rule_401.py new file mode 100644 index 000000000..7ffa1a1ca --- /dev/null +++ b/tests/variable/test_rule_401.py @@ -0,0 +1,277 @@ +# -*- coding: utf-8 -*- + +import os +import unittest + +from tests import utils +from vsg import vhdlFile +from vsg.rules import variable + +sTestDir = os.path.dirname(__file__) + +lFile, eError = vhdlFile.utils.read_vhdlfile(os.path.join(sTestDir, "rule_401_test_input.vhd")) + + +class test_rule(unittest.TestCase): + def setUp(self): + self.oFile = vhdlFile.vhdlFile(lFile) + self.assertIsNone(eError) + + def test_rule_401_options(self): + oRule = variable.rule_401() + self.assertTrue(oRule) + self.assertEqual(oRule.name, "variable") + self.assertEqual(oRule.identifier, "401") + self.assertEqual(len(oRule.configuration), 12) + + def test_rule_401_yes_no_no_no_no(self): + oRule = variable.rule_401() + oRule.compact_alignment = "yes" + oRule.blank_line_ends_group = "no" + oRule.comment_line_ends_group = "no" + oRule.aggregate_parens_ends_group = "no" + oRule.ignore_single_line_aggregates = "no" + + lExpected = [8, 9, 11, 12, 14] + lExpected.extend([20, 21, 24, 25, 28, 29]) + lExpected.extend([34, 35, 37, 38, 40, 41]) + lExpected.extend([45, 46, 47, 49, 51, 53, 54, 55]) + lExpected.extend([61, 62, 63, 64]) + lExpected.extend([67, 68, 69]) + lExpected.extend([75, 76, 77, 78]) + lExpected.extend([80, 81, 82, 83]) + lExpected.extend([89, 90, 91, 92, 94, 97]) + + oRule.analyze(self.oFile) + self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations)) + + def test_fix_rule_401_yes_no_no_no_no(self): + oRule = variable.rule_401() + oRule.compact_alignment = "yes" + oRule.blank_line_ends_group = "no" + oRule.comment_line_ends_group = "no" + oRule.aggregate_parens_ends_group = "no" + oRule.ignore_single_line_aggregates = "no" + + oRule.fix(self.oFile) + + lExpected = [] + lExpected.append("") + utils.read_file(os.path.join(sTestDir, "rule_401_test_input.fixed_yes_no_no_no_no.vhd"), lExpected) + + lActual = self.oFile.get_lines() + + self.assertEqual(lExpected, lActual) + + oRule.analyze(self.oFile) + self.assertEqual(oRule.violations, []) + + ############################################################################### + def test_rule_401_no_no_no_no_no(self): + oRule = variable.rule_401() + oRule.compact_alignment = "no" + oRule.blank_line_ends_group = "no" + oRule.comment_line_ends_group = "no" + oRule.aggregate_parens_ends_group = "no" + oRule.ignore_single_line_aggregates = "no" + + lExpected = [8, 9, 11, 12, 14] + lExpected.extend([20, 21, 24, 25, 28, 29]) + lExpected.extend([34, 37, 38, 40, 41]) + lExpected.extend([45, 46, 49, 50, 51, 53, 54, 55]) + lExpected.extend([61, 62, 63, 64]) + lExpected.extend([67, 68, 69]) + lExpected.extend([76, 77, 78]) + lExpected.extend([80, 81, 83]) + lExpected.extend([89, 90, 91, 92, 94, 97]) + + oRule.analyze(self.oFile) + self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations)) + + def test_fix_rule_401_no_no_no_no_no(self): + oRule = variable.rule_401() + oRule.compact_alignment = "no" + oRule.blank_line_ends_group = "no" + oRule.comment_line_ends_group = "no" + oRule.aggregate_parens_ends_group = "no" + oRule.ignore_single_line_aggregates = "no" + + oRule.fix(self.oFile) + + lActual = self.oFile.get_lines() + + lExpected = [] + lExpected.append("") + utils.read_file(os.path.join(sTestDir, "rule_401_test_input.fixed_no_no_no_no_no.vhd"), lExpected) + + self.assertEqual(lExpected, lActual) + + oRule.analyze(self.oFile) + self.assertEqual(oRule.violations, []) + + ############################################################################### + def test_rule_401_yes_no_yes_no_no(self): + oRule = variable.rule_401() + oRule.compact_alignment = "yes" + oRule.blank_line_ends_group = "no" + oRule.comment_line_ends_group = "yes" + oRule.aggregate_parens_ends_group = "no" + oRule.ignore_single_line_aggregates = "no" + + lExpected = [8, 9, 11, 14] + lExpected.extend([20, 21, 24, 25, 28, 29]) + lExpected.extend([34, 35, 37, 38, 40, 41]) + lExpected.extend([45, 46, 47, 49, 51, 53, 54, 55]) + lExpected.extend([61, 62, 63, 64]) + lExpected.extend([67, 68, 69]) + lExpected.extend([75, 76, 77, 78]) + lExpected.extend([80, 81, 82, 83]) + lExpected.extend([89, 90, 91, 92, 94, 97]) + + oRule.analyze(self.oFile) + self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations)) + + def test_fix_rule_401_yes_no_yes_no_no(self): + oRule = variable.rule_401() + oRule.compact_alignment = "yes" + oRule.blank_line_ends_group = "no" + oRule.comment_line_ends_group = "yes" + oRule.aggregate_parens_ends_group = "no" + oRule.ignore_single_line_aggregates = "no" + + oRule.fix(self.oFile) + + lActual = self.oFile.get_lines() + + lExpected = [] + lExpected.append("") + utils.read_file(os.path.join(sTestDir, "rule_401_test_input.fixed_yes_no_yes_no_no.vhd"), lExpected) + + self.assertEqual(lExpected, lActual) + + oRule.analyze(self.oFile) + self.assertEqual(oRule.violations, []) + + ############################################################################### + def test_rule_401_yes_yes_no_no_no(self): + oRule = variable.rule_401() + oRule.compact_alignment = "yes" + oRule.blank_line_ends_group = "yes" + oRule.comment_line_ends_group = "no" + oRule.aggregate_parens_ends_group = "no" + oRule.ignore_single_line_aggregates = "no" + + lExpected = [8, 11, 12, 14] + lExpected.extend([20, 21, 24, 25, 28, 29]) + lExpected.extend([34, 35, 37, 38, 40, 41]) + lExpected.extend([45, 46, 47, 49, 51, 53, 54, 55]) + lExpected.extend([61, 62, 63, 64]) + lExpected.extend([67, 68, 69]) + lExpected.extend([75, 76, 77, 78]) + lExpected.extend([80, 81, 82, 83]) + lExpected.extend([89, 90, 91, 92, 94, 97]) + + oRule.analyze(self.oFile) + self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations)) + + def test_fix_rule_401_yes_yes_no_no_no(self): + oRule = variable.rule_401() + oRule.compact_alignment = "yes" + oRule.blank_line_ends_group = "yes" + oRule.comment_line_ends_group = "no" + oRule.aggregate_parens_ends_group = "no" + oRule.ignore_single_line_aggregates = "no" + + oRule.fix(self.oFile) + + lActual = self.oFile.get_lines() + + lExpected = [] + lExpected.append("") + utils.read_file(os.path.join(sTestDir, "rule_401_test_input.fixed_yes_yes_no_no_no.vhd"), lExpected) + + self.assertEqual(lExpected, lActual) + + oRule.analyze(self.oFile) + self.assertEqual(oRule.violations, []) + + ############################################################################### + def test_rule_401_yes_yes_yes_yes_no(self): + oRule = variable.rule_401() + oRule.compact_alignment = "yes" + oRule.blank_line_ends_group = "yes" + oRule.comment_line_ends_group = "yes" + oRule.aggregate_parens_ends_group = "yes" + oRule.ignore_single_line_aggregates = "no" + + lExpected = [8, 11, 14] + lExpected.extend([20, 21, 24, 25, 28, 29]) + lExpected.extend([34, 35, 37, 38, 40, 41]) + lExpected.extend([45, 46, 47, 49, 51, 53, 54, 55]) + lExpected.extend([75, 76, 77, 78]) + lExpected.extend([80, 81, 82, 83]) + + oRule.analyze(self.oFile) + self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations)) + + def test_fix_rule_401_yes_yes_yes_yes_no(self): + oRule = variable.rule_401() + oRule.compact_alignment = "yes" + oRule.blank_line_ends_group = "yes" + oRule.comment_line_ends_group = "yes" + oRule.aggregate_parens_ends_group = "yes" + oRule.ignore_single_line_aggregates = "no" + + oRule.fix(self.oFile) + + lActual = self.oFile.get_lines() + + lExpected = [] + lExpected.append("") + utils.read_file(os.path.join(sTestDir, "rule_401_test_input.fixed_yes_yes_yes_yes_no.vhd"), lExpected) + + self.assertEqual(lExpected, lActual) + + oRule.analyze(self.oFile) + self.assertEqual(oRule.violations, []) + + ############################################################################### + def test_rule_401_yes_yes_yes_yes_yes(self): + oRule = variable.rule_401() + oRule.compact_alignment = "yes" + oRule.blank_line_ends_group = "yes" + oRule.comment_line_ends_group = "yes" + oRule.aggregate_parens_ends_group = "yes" + oRule.ignore_single_line_aggregates = "yes" + + lExpected = [8, 11, 14] + lExpected.extend([20, 21, 24, 25, 28, 29]) + lExpected.extend([34, 35, 37, 38, 40, 41]) + lExpected.extend([45, 46, 47, 49, 51, 53, 54, 55]) + lExpected.extend([75, 76, 77, 78]) + lExpected.extend([80, 81, 82, 83]) + lExpected.extend([97]) + + oRule.analyze(self.oFile) + self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations)) + + def test_fix_rule_401_yes_yes_yes_yes_yes(self): + oRule = variable.rule_401() + oRule.compact_alignment = "yes" + oRule.blank_line_ends_group = "yes" + oRule.comment_line_ends_group = "yes" + oRule.aggregate_parens_ends_group = "yes" + oRule.ignore_single_line_aggregates = "yes" + + oRule.fix(self.oFile) + + lActual = self.oFile.get_lines() + + lExpected = [] + lExpected.append("") + utils.read_file(os.path.join(sTestDir, "rule_401_test_input.fixed_yes_yes_yes_yes_yes.vhd"), lExpected) + + self.assertEqual(lExpected, lActual) + + oRule.analyze(self.oFile) + self.assertEqual(oRule.violations, []) diff --git a/vsg/rules/variable/__init__.py b/vsg/rules/variable/__init__.py index 351baaebd..6755b2d82 100644 --- a/vsg/rules/variable/__init__.py +++ b/vsg/rules/variable/__init__.py @@ -17,5 +17,6 @@ from .rule_102 import rule_102 from .rule_103 import rule_103 from .rule_400 import rule_400 +from .rule_401 import rule_401 from .rule_500 import rule_500 from .rule_600 import rule_600 diff --git a/vsg/rules/variable/rule_401.py b/vsg/rules/variable/rule_401.py new file mode 100644 index 000000000..c768e9d35 --- /dev/null +++ b/vsg/rules/variable/rule_401.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + +from vsg import token +from vsg.rules import ( + align_tokens_in_region_between_tokens_unless_between_tokens as Rule, +) + +lAlign = [] +lAlign.append(token.element_association.assignment) + +lUnless = [] + +oStartToken = token.variable_declaration.assignment_operator +oEndToken = token.variable_declaration.semicolon + + +class rule_401(Rule): + """ + This rule checks the alignment of assignment keywords in variable declarations. + + |configuring_keyword_alignment_rules_link| + + **Violation** + + .. code-block:: vhdl + + variable v_default_values : t_address_en := ( + c_address_control => false, + c_address_data => true, + others => false + ); + + **Fix** + + .. code-block:: vhdl + + variable v_default_values : t_address_en := ( + c_address_control => false, + c_address_data => true, + others => false + ); + """ + + def __init__(self): + super().__init__(lAlign, oStartToken, oEndToken, lUnless) + self.solution = "Align => ." + self.configuration.remove("if_control_statements_ends_group") + self.configuration.remove("case_control_statements_ends_group") + self.configuration.remove("loop_control_statements_ends_group") + self.configuration.remove("separate_generic_port_alignment") + self.configuration.append("aggregate_parens_ends_group") + self.configuration.append("ignore_single_line_aggregates")