diff --git a/changelog.txt b/changelog.txt index f73d2e36..008e42ff 100644 --- a/changelog.txt +++ b/changelog.txt @@ -14,6 +14,7 @@ Whenever you upgrade code pal for ABAP, it is highly recommended to execute the 2021-04-** v.1.14.0 ------------------ ++ Prefer NEW to CREATE OBJECT (#283) * Standard functions in Prefer IS NOT to NOT IS (#338) * In the profile feature, you can add all the missing checks (#346) diff --git a/docs/check_documentation.md b/docs/check_documentation.md index 056659b6..7afa1dec 100644 --- a/docs/check_documentation.md +++ b/docs/check_documentation.md @@ -40,6 +40,7 @@ - [Number of Output Parameter](checks/number-output-parameter.md) - [Prefer CASE to ELSEIF](checks/prefer-case-to-elseif.md) - [Prefer IS NOT to NOT IS](checks/prefer-is-not-to-not-is.md) +- [Prefer NEW to CREATE OBJECT](checks/prefer-new-to-create-object.md) - [Pseudo Comment Usage](checks/pseudo-comment-usage.md) - [Omit Optional EXPORTING](checks/omit-optional-exporting.md) - [Optional Parameters](checks/optional-parameters.md) diff --git a/docs/checks/prefer-new-to-create-object.md b/docs/checks/prefer-new-to-create-object.md new file mode 100644 index 00000000..e61e8c20 --- /dev/null +++ b/docs/checks/prefer-new-to-create-object.md @@ -0,0 +1,44 @@ +[code pal for ABAP](../../README.md) > [Documentation](../check_documentation.md) > [Prefer New to Create Object](prefer_new_to_create_object.md) + +## Prefer New to Create Object + +### What is the Intent of the Check? + +Prefer `NEW` over `CREATE OBJECT` as it avoids needlessly longer statements. + +### How to solve the issue? + +Preferably, use `NEW` for creating new objects/instances. + +### What to do in case of exception? + +In exceptional cases, you can suppress this finding by using the pseudo comment `"#EC PREF_NEW`: + +```abap + DATA prefer_new_to_crt_obj TYPE REF TO y_check_prefer_new_to_crt_obj. + CREATE OBJECT prefer_new_to_crt_obj. "#EC PREF_NEW +``` + +### Example + +Before the check: + +```abap + DATA prefer_new_to_create_object TYPE REF TO y_check_prefer_new_to_crt_obj. + CREATE OBJECT prefer_new_to_create_object. +``` + +After the check: + +```abap + DATA(prefer_new_to_create_object) = NEW y_check_prefer_new_to_crt_obj( ). +``` + +```abap + DATA prefer_new_to_create_object TYPE REF TO y_check_prefer_new_to_crt_obj. + prefer_new_to_create_object = NEW #( ). +``` + +### Further Readings & Knowledge + +* [ABAP Styleguides on Clean Code](https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-new-to-create-object) diff --git a/src/checks/y_check_prefer_new_to_crt_obj.clas.abap b/src/checks/y_check_prefer_new_to_crt_obj.clas.abap new file mode 100644 index 00000000..e30d43b2 --- /dev/null +++ b/src/checks/y_check_prefer_new_to_crt_obj.clas.abap @@ -0,0 +1,45 @@ +CLASS y_check_prefer_new_to_crt_obj DEFINITION PUBLIC INHERITING FROM y_check_base CREATE PUBLIC . + PUBLIC SECTION. + METHODS constructor . + + PROTECTED SECTION. + METHODS inspect_tokens REDEFINITION. + +ENDCLASS. + + + +CLASS y_check_prefer_new_to_crt_obj IMPLEMENTATION. + + + METHOD constructor. + super->constructor( ). + + settings-pseudo_comment = '"#EC PREF_NEW' ##NO_TEXT. + settings-disable_threshold_selection = abap_true. + settings-threshold = 0. + settings-prio = c_warning. + settings-documentation = |{ c_docs_path-checks }prefer-new-to-create-object.md|. + + set_check_message( 'Prefer NEW to CREATE OBJECT!' ). + ENDMETHOD. + + + METHOD inspect_tokens. + CHECK get_token_abs( statement-from ) = 'CREATE' + AND get_token_abs( statement-from + 1 ) = 'OBJECT'. + + DATA(check_configuration) = detect_check_configuration( statement ). + + IF check_configuration IS INITIAL. + RETURN. + ENDIF. + + raise_error( statement_level = statement-level + statement_index = index + statement_from = statement-from + error_priority = check_configuration-prio ). + ENDMETHOD. + + +ENDCLASS. diff --git a/src/checks/y_check_prefer_new_to_crt_obj.clas.testclasses.abap b/src/checks/y_check_prefer_new_to_crt_obj.clas.testclasses.abap new file mode 100644 index 00000000..da741938 --- /dev/null +++ b/src/checks/y_check_prefer_new_to_crt_obj.clas.testclasses.abap @@ -0,0 +1,68 @@ +CLASS ltc_create_object DEFINITION INHERITING FROM y_unit_test_base FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. + PROTECTED SECTION. + METHODS get_cut REDEFINITION. + METHODS get_code_with_issue REDEFINITION. + METHODS get_code_without_issue REDEFINITION. + METHODS get_code_with_exemption REDEFINITION. +ENDCLASS. + +CLASS ltc_create_object IMPLEMENTATION. + + METHOD get_cut. + result ?= NEW y_check_prefer_new_to_crt_obj( ). + 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_new_to_crt_obj TYPE REF TO y_check_prefer_new_to_crt_obj. ' ) + ( ' CREATE OBJECT prefer_new_to_crt_obj. ' ) + ( ' ENDMETHOD.' ) + ( ' ENDCLASS. ' ) + ). + ENDMETHOD. + + 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_new_to_crt_obj) = NEW y_check_prefer_new_to_crt_obj( ). ' ) + ( ' 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_new_to_crt_obj TYPE REF TO y_check_prefer_new_to_crt_obj. ' ) + ( ' CREATE OBJECT prefer_new_to_crt_obj. "#EC PREF_NEW' ) + ( ' ENDMETHOD.' ) + ( ' ENDCLASS. ' ) + ). + ENDMETHOD. + +ENDCLASS. diff --git a/src/checks/y_check_prefer_new_to_crt_obj.clas.xml b/src/checks/y_check_prefer_new_to_crt_obj.clas.xml new file mode 100644 index 00000000..ea4a0e74 --- /dev/null +++ b/src/checks/y_check_prefer_new_to_crt_obj.clas.xml @@ -0,0 +1,17 @@ + + + + + + Y_CHECK_PREFER_NEW_TO_CRT_OBJ + E + Prefer New to Create Object + 1 + X + X + X + X + + + + diff --git a/src/examples/y_demo_failures.clas.abap b/src/examples/y_demo_failures.clas.abap index 2c3d2447..4bb4d4b1 100644 --- a/src/examples/y_demo_failures.clas.abap +++ b/src/examples/y_demo_failures.clas.abap @@ -114,6 +114,7 @@ CLASS y_demo_failures DEFINITION PUBLIC FINAL CREATE PUBLIC. VALUE(age) TYPE i. "#EC RET_NAME #EC BOOL_PARAM "#EC OPTL_PARAM METHODS prefer_is_not_to_not_is. METHODS prefer_case_to_elseif. + METHODS prefer_new_to_create_object. METHODS deprecated_classes. METHODS scope_of_variable. @@ -402,6 +403,12 @@ CLASS Y_DEMO_FAILURES IMPLEMENTATION. ENDMETHOD. + METHOD prefer_new_to_create_object. + DATA demo_failures TYPE REF TO y_demo_failures. + CREATE OBJECT demo_failures. + ENDMETHOD. + + METHOD prefer_is_not_to_not_is. IF NOT attribute_1 IS INITIAL. attribute_1 = attribute_2.