diff --git a/docs/check_documentation.md b/docs/check_documentation.md index 827790f7..b43627a6 100644 --- a/docs/check_documentation.md +++ b/docs/check_documentation.md @@ -45,6 +45,7 @@ - [Prefer CASE to ELSEIF](checks/prefer-case-to-elseif.md) - [Prefer RETURNING to EXPORTING](checks/prefer-returning-to-exporting.md) - [Prefer IS NOT to NOT IS](checks/prefer-is-not-to-not-is.md) +- [Prefer INSERT INTO TABLE to APPEND TO](checks/prefer-insert-into-to-append.md) - [Prefer LINE_EXISTS or LINE_INDEX to READ TABLE or LOOP AT](checks/prefer-line-exists.md) - [Prefer NEW to CREATE OBJECT](checks/prefer-new-to-create-object.md) - [Prefer Pragmas to Pseudo Comments](checks/prefer-pragmas-to-pseudo-comments.md) diff --git a/docs/checks/prefer-insert-into-to-append.md b/docs/checks/prefer-insert-into-to-append.md new file mode 100644 index 00000000..b47328da --- /dev/null +++ b/docs/checks/prefer-insert-into-to-append.md @@ -0,0 +1,40 @@ +[code pal for ABAP](../../README.md) > [Documentation](../check_documentation.md) > [Prefer INSERT INTO TABLE to APPEND TO](prefer-insert-into-to-append.md) + +## Prefer INSERT INTO TABLE to APPEND TO + +### What is the intent of the check? + +This check searches for `APPEND` statements and reports a finding. `INSERT INTO TABLE` works with all table and key types, thus making it easier for you to refactor the table's type and key definitions if your performance requirements change. + +### How to solve the issue? + +Use `INSERT INTO` instead of `APPEND TO`. + +### What to do in case of exception? + +In exceptional cases, you can suppress this finding by using the pseudo comment `"#EC PREF_INSERT_INT`: + +```abap + DATA prefer_insert_into_table TYPE TABLE OF string. + APPEND `example` TO prefer_insert_into_table. "#EC PREF_INSERT_INT +``` + +### Example + +Before the check: + +```abap + DATA prefer_insert_into_table TYPE TABLE OF string. + APPEND `example` TO prefer_insert_into_table. +``` + +After the check: + +```abap + DATA prefer_insert_into_table TYPE TABLE OF string. + INSERT `example` INTO TABLE prefer_insert_into_table. +``` + +### Further Readings & Knowledge + +* [Clean ABAP - Prefer INSERT INTO TABLE to APPEND TO](https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-insert-into-table-to-append-to) diff --git a/src/y_check_prefer_insert_into.clas.abap b/src/y_check_prefer_insert_into.clas.abap new file mode 100644 index 00000000..ad02db0d --- /dev/null +++ b/src/y_check_prefer_insert_into.clas.abap @@ -0,0 +1,50 @@ +CLASS y_check_prefer_insert_into DEFINITION + PUBLIC + INHERITING FROM y_check_base + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + METHODS constructor. + PROTECTED SECTION. + METHODS: inspect_tokens REDEFINITION. + PRIVATE SECTION. +ENDCLASS. + + + +CLASS y_check_prefer_insert_into IMPLEMENTATION. + + METHOD constructor. + super->constructor( ). + + settings-pseudo_comment = '"#EC PREF_INSERT_INT' ##NO_TEXT. + settings-disable_threshold_selection = abap_true. + settings-threshold = 0. + settings-documentation = |{ c_docs_path-checks }prefer-insert-into-to-append.md|. + + set_check_message( 'Prefer INSERT INTO TABLE to APPEND TO.' ). + + ENDMETHOD. + + METHOD inspect_tokens. + + IF get_token_abs( statement-from ) <> 'APPEND'. + RETURN. + ENDIF. + + IF next2( p_word1 = 'SORTED' + p_word2 = 'BY' ) IS NOT INITIAL. + RETURN. + ENDIF. + + DATA(check_configuration) = detect_check_configuration( statement ). + + raise_error( statement_level = statement-level + statement_index = index + statement_from = statement-from + check_configuration = check_configuration ). + + ENDMETHOD. + +ENDCLASS. diff --git a/src/y_check_prefer_insert_into.clas.testclasses.abap b/src/y_check_prefer_insert_into.clas.testclasses.abap new file mode 100644 index 00000000..eef9cbeb --- /dev/null +++ b/src/y_check_prefer_insert_into.clas.testclasses.abap @@ -0,0 +1,182 @@ +CLASS ltc_append_to DEFINITION INHERITING FROM y_unit_test_base FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. + PROTECTED SECTION. + METHODS: get_cut REDEFINITION, + get_code_with_issue REDEFINITION, + get_code_without_issue REDEFINITION, + get_code_with_exemption REDEFINITION. + +ENDCLASS. + + +CLASS ltc_append_to IMPLEMENTATION. + + METHOD get_code_without_issue. + + result = VALUE #( + ( ' REPORT y_example.' ) + + ( ' CLASS y_example DEFINITION.' ) + ( ' PUBLIC SECTION.' ) + ( ' METHODS example.' ) + ( ' ENDCLASS.' ) + + ( ' CLASS y_example IMPLEMENTATION.' ) + ( ' METHOD example.' ) + ( ' DATA prefer_insert_into_table TYPE TABLE OF string.' ) + ( ' INSERT `example` INTO TABLE prefer_insert_into_table.' ) + ( ' ENDMETHOD.' ) + ( ' ENDCLASS.' ) + ). + + ENDMETHOD. + + METHOD get_code_with_exemption. + + result = VALUE #( + ( ' REPORT y_example.' ) + + ( ' CLASS y_example DEFINITION.' ) + ( ' PUBLIC SECTION.' ) + ( ' METHODS example.' ) + ( ' ENDCLASS.' ) + + ( ' CLASS y_example IMPLEMENTATION.' ) + ( ' METHOD example.' ) + ( ' DATA prefer_insert_into_table TYPE TABLE OF string.' ) + ( ' APPEND `example` TO prefer_insert_into_table. "#EC PREF_INSERT_INT' ) + ( ' ENDMETHOD.' ) + ( ' ENDCLASS.' ) + ). + + ENDMETHOD. + + METHOD get_code_with_issue. + + result = VALUE #( + ( ' REPORT y_example.' ) + + ( ' CLASS y_example DEFINITION.' ) + ( ' PUBLIC SECTION.' ) + ( ' METHODS example.' ) + ( ' ENDCLASS.' ) + + ( ' CLASS y_example IMPLEMENTATION.' ) + ( ' METHOD example.' ) + ( ' DATA prefer_insert_into_table TYPE TABLE OF string.' ) + ( ' APPEND `example` TO prefer_insert_into_table.' ) + ( ' ENDMETHOD.' ) + ( ' ENDCLASS.' ) + ). + + ENDMETHOD. + + METHOD get_cut. + result ?= NEW y_check_prefer_insert_into( ). + ENDMETHOD. + +ENDCLASS. + +CLASS ltc_append_initial_line DEFINITION INHERITING FROM ltc_append_to FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. + PROTECTED SECTION. + METHODS get_code_with_issue REDEFINITION. +ENDCLASS. + +CLASS ltc_append_initial_line IMPLEMENTATION. + + METHOD get_code_with_issue. + result = VALUE #( + ( ' REPORT y_example.' ) + + ( ' CLASS y_example DEFINITION.' ) + ( ' PUBLIC SECTION.' ) + ( ' METHODS example.' ) + ( ' ENDCLASS.' ) + + ( ' CLASS y_example IMPLEMENTATION.' ) + ( ' METHOD example.' ) + ( ' DATA prefer_insert_into_table TYPE TABLE OF string.' ) + ( ' FIELD-SYMBOLS TYPE string.' ) + ( ' APPEND INITIAL LINE TO prefer_insert_into_table ASSIGNING .' ) + ( ' ENDMETHOD.' ) + ( ' ENDCLASS.' ) + ). + ENDMETHOD. + +ENDCLASS. + +CLASS ltc_append_lines_of DEFINITION INHERITING FROM ltc_append_to FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. + PROTECTED SECTION. + METHODS get_code_with_issue REDEFINITION. +ENDCLASS. + +CLASS ltc_append_lines_of IMPLEMENTATION. + + METHOD get_code_with_issue. + result = VALUE #( + ( ' REPORT y_example.' ) + + ( ' CLASS y_example DEFINITION.' ) + ( ' PUBLIC SECTION.' ) + ( ' METHODS example.' ) + ( ' ENDCLASS.' ) + + ( ' CLASS y_example IMPLEMENTATION.' ) + ( ' METHOD example.' ) + ( ' DATA prefer_insert_into_table TYPE TABLE OF string.' ) + ( ' DATA example_table TYPE TABLE OF string.' ) + ( ' APPEND LINES OF example_table TO prefer_insert_into_table.' ) + ( ' ENDMETHOD.' ) + ( ' ENDCLASS.' ) + ). + ENDMETHOD. + +ENDCLASS. + +CLASS ltc_append_sorted_by DEFINITION INHERITING FROM ltc_append_to FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. + PROTECTED SECTION. + METHODS get_code_without_issue REDEFINITION. +ENDCLASS. + +CLASS ltc_append_sorted_by IMPLEMENTATION. + + METHOD get_code_without_issue. + result = VALUE #( + ( ' REPORT y_example.' ) + + ( ' CLASS y_example DEFINITION.' ) + ( ' PUBLIC SECTION.' ) + ( ' METHODS example.' ) + ( ' ENDCLASS.' ) + + ( ' CLASS y_example IMPLEMENTATION.' ) + ( ' METHOD example.' ) + ( ' DATA prefer_insert_into_table TYPE TABLE OF sflight.' ) + ( ' DATA example_line TYPE sflight.' ) + ( ' APPEND example_line TO prefer_insert_into_table SORTED BY fldate.' ) + ( ' ENDMETHOD.' ) + ( ' ENDCLASS.' ) + ). + ENDMETHOD. + +ENDCLASS. + + +CLASS ltc_select DEFINITION INHERITING FROM ltc_append_to FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. + PROTECTED SECTION. + METHODS get_code_without_issue REDEFINITION. +ENDCLASS. + +CLASS ltc_select IMPLEMENTATION. + + METHOD get_code_without_issue. + result = VALUE #( + ( ' REPORT ut_test.' ) + ( ' START-OF-SELECTION.' ) + ( ' DATA example_table TYPE TABLE OF sflight.' ) + ( ' SELECT * FROM sflight APPENDING TABLE example_table.' ) + ). + ENDMETHOD. + +ENDCLASS. diff --git a/src/y_check_prefer_insert_into.clas.xml b/src/y_check_prefer_insert_into.clas.xml new file mode 100644 index 00000000..9be2c895 --- /dev/null +++ b/src/y_check_prefer_insert_into.clas.xml @@ -0,0 +1,17 @@ + + + + + + Y_CHECK_PREFER_INSERT_INTO + E + Prefer INSERT INTO TABLE to APPEND TO + 1 + X + X + X + X + + + +