diff --git a/docs/configuring_disabled_rules.rst b/docs/configuring_disabled_rules.rst index 7e14c1883..448dcac3f 100644 --- a/docs/configuring_disabled_rules.rst +++ b/docs/configuring_disabled_rules.rst @@ -50,6 +50,7 @@ Rules Disabled by Default * `function_600 `_ * `function_601 `_ * `generate_017 `_ +* `generate_022 `_ * `generate_600 `_ * `generate_601 `_ * `generate_602 `_ diff --git a/docs/configuring_optional_items.rst b/docs/configuring_optional_items.rst index 1155da19a..178057983 100644 --- a/docs/configuring_optional_items.rst +++ b/docs/configuring_optional_items.rst @@ -97,6 +97,7 @@ Rules Enforcing Optional Items * `function_018 `_ * `function_020 `_ * `generate_011 `_ +* `generate_022 `_ * `instantiation_033 `_ * `loop_statement_007 `_ * `package_007 `_ diff --git a/docs/generate_rules.rst b/docs/generate_rules.rst index 64bef955f..6e3ca01d0 100644 --- a/docs/generate_rules.rst +++ b/docs/generate_rules.rst @@ -462,6 +462,29 @@ This rule checks a label colon is on the same line as the **case**, **if**, and label : case +generate_022 +############ + +|phase_1| |disabled| |error| |structure| |structure_optional| + +This rule checks for the existence of the **begin** keyword in for generate statements. + +|configuring_optional_items_link| + +**Violation** + +.. code-block:: vhdl + + ram_array : for i in 0 to 7 generate + end generate; + +**Fix** + +.. code-block:: vhdl + + ram_array : for i in 0 to 7 generate begin + end generate; + generate_400 ############ diff --git a/docs/rule_groups/structure_optional_rule_group.rst b/docs/rule_groups/structure_optional_rule_group.rst index 49347c863..507ecc56c 100644 --- a/docs/rule_groups/structure_optional_rule_group.rst +++ b/docs/rule_groups/structure_optional_rule_group.rst @@ -18,6 +18,7 @@ Rules Enforcing Structure::Optional Rule Group * `function_018 <../function_rules.html#function-018>`_ * `function_020 <../function_rules.html#function-020>`_ * `generate_011 <../generate_rules.html#generate-011>`_ +* `generate_022 <../generate_rules.html#generate-022>`_ * `instantiation_033 <../instantiation_rules.html#instantiation-033>`_ * `loop_statement_007 <../loop_statement_rules.html#loop-statement-007>`_ * `package_007 <../package_rules.html#package-007>`_ diff --git a/docs/rule_groups/structure_rule_group.rst b/docs/rule_groups/structure_rule_group.rst index 1e43aa997..1f4b633a5 100644 --- a/docs/rule_groups/structure_rule_group.rst +++ b/docs/rule_groups/structure_rule_group.rst @@ -71,6 +71,7 @@ Rules Enforcing Structure Rule Group * `generate_019 <../generate_rules.html#generate-019>`_ * `generate_020 <../generate_rules.html#generate-020>`_ * `generate_021 <../generate_rules.html#generate-021>`_ +* `generate_022 <../generate_rules.html#generate-022>`_ * `generic_010 <../generic_rules.html#generic-010>`_ * `generic_013 <../generic_rules.html#generic-013>`_ * `generic_016 <../generic_rules.html#generic-016>`_ diff --git a/tests/generate/rule_022_test_input.fixed.vhd b/tests/generate/rule_022_test_input.fixed.vhd new file mode 100644 index 000000000..a5e04b93f --- /dev/null +++ b/tests/generate/rule_022_test_input.fixed.vhd @@ -0,0 +1,16 @@ +architecture RTL of FIFO is + +begin + + gen0 : for i in 0 to 7 generate + begin + end generate; + + -- Violations below + + gen1 : for i in 0 to 7 generate begin + end generate; + + gen2 : for i in 0 to 7 generate begin end generate; + +end; diff --git a/tests/generate/rule_022_test_input.vhd b/tests/generate/rule_022_test_input.vhd new file mode 100644 index 000000000..5baac57a0 --- /dev/null +++ b/tests/generate/rule_022_test_input.vhd @@ -0,0 +1,16 @@ +architecture RTL of FIFO is + +begin + + gen0 : for i in 0 to 7 generate + begin + end generate; + + -- Violations below + + gen1 : for i in 0 to 7 generate + end generate; + + gen2 : for i in 0 to 7 generate end generate; + +end; diff --git a/tests/generate/test_rule_022.py b/tests/generate/test_rule_022.py new file mode 100644 index 000000000..dc2a931e3 --- /dev/null +++ b/tests/generate/test_rule_022.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- + +import os +import unittest + +from tests import utils +from vsg import vhdlFile +from vsg.rules import generate + +sTestDir = os.path.dirname(__file__) + +lFile, eError = vhdlFile.utils.read_vhdlfile(os.path.join(sTestDir, "rule_022_test_input.vhd")) + +lExpected = [] +lExpected.append("") +utils.read_file(os.path.join(sTestDir, "rule_022_test_input.fixed.vhd"), lExpected) + + +class test_generate_rule(unittest.TestCase): + def setUp(self): + self.oFile = vhdlFile.vhdlFile(lFile) + self.assertIsNone(eError) + + def test_rule_022(self): + oRule = generate.rule_022() + self.assertTrue(oRule) + self.assertEqual(oRule.name, "generate") + self.assertEqual(oRule.identifier, "022") + + lExpected = [11, 14] + + oRule.analyze(self.oFile) + self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations)) + + def test_fix_rule_022(self): + oRule = generate.rule_022() + + oRule.fix(self.oFile) + + lActual = self.oFile.get_lines() + + self.assertEqual(lExpected, lActual) + + oRule.analyze(self.oFile) + self.assertEqual(oRule.violations, []) diff --git a/vsg/rules/generate/__init__.py b/vsg/rules/generate/__init__.py index a55d99038..c45a17268 100644 --- a/vsg/rules/generate/__init__.py +++ b/vsg/rules/generate/__init__.py @@ -21,6 +21,7 @@ from .rule_019 import rule_019 from .rule_020 import rule_020 from .rule_021 import rule_021 +from .rule_022 import rule_022 from .rule_400 import rule_400 from .rule_401 import rule_401 from .rule_402 import rule_402 diff --git a/vsg/rules/generate/rule_022.py b/vsg/rules/generate/rule_022.py new file mode 100644 index 000000000..08d810188 --- /dev/null +++ b/vsg/rules/generate/rule_022.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + +from vsg.rules import ( + insert_token_right_of_possible_tokens_if_it_does_not_exist_before_token, +) +from vsg.token import for_generate_statement, generate_statement_body + +oInsertToken = generate_statement_body.begin_keyword("begin") +lRightTokens = [for_generate_statement.generate_keyword] +oBeforeToken = for_generate_statement.end_keyword + + +class rule_022(insert_token_right_of_possible_tokens_if_it_does_not_exist_before_token): + """ + This rule checks for the existence of the **begin** keyword in for generate statements. + + |configuring_optional_items_link| + + **Violation** + + .. code-block:: vhdl + + ram_array : for i in 0 to 7 generate + end generate; + + **Fix** + + .. code-block:: vhdl + + ram_array : for i in 0 to 7 generate begin + end generate; + """ + + def __init__(self): + super().__init__(oInsertToken, lRightTokens, oBeforeToken) + insert_token_right_of_possible_tokens_if_it_does_not_exist_before_token.__init__(self, oInsertToken, lRightTokens, oBeforeToken) + self.solution = "*begin* keyword" + self.groups.append("structure::optional") + self.disable = True