├── .github
├── CODEOWNERS
├── workflows
│ └── on_pull_request.yml
└── ISSUE_TEMPLATE
│ ├── bug.md
│ └── new-check.md
├── src
├── test_objects
│ ├── #cc4a#test_prefer_is_not.clas.locals_def.abap
│ ├── #cc4a#test_method_signature_if.intf.abap
│ ├── #cc4a#if_test_avoid_self_ref.intf.abap
│ ├── #cc4a#test_prefer_methods.fugr.#cc4a#ltest_prefer_methodstop.abap
│ ├── #cc4a#bp_test_rap_unamanaged.clas.abap
│ ├── #cc4a#test_check_constant_if2.intf.abap
│ ├── #cc4a#test_rap_unamanaged.ddls.baseinfo
│ ├── #cc4a#test_check_constant_if1.clas.abap
│ ├── #cc4a#test_db_access_in_ut.clas.abap
│ ├── #cc4a#test_prefer_methods.fugr.#cc4a#rfc_disabled_module.abap
│ ├── #cc4a#test_prefer_methods.fugr.#cc4a#rfc_enabled_module.abap
│ ├── #cc4a#test_prefer_is_not.clas.locals_imp.abap
│ ├── #cc4a#test_rap_unamanaged.bdef.asbdef
│ ├── package.devc.xml
│ ├── #cc4a#test_avoid_self_ref_sup.clas.abap
│ ├── #cc4a#test_rap_unamanaged.ddls.asddls
│ ├── #cc4a#test_prefer_is_not_2.clas.abap
│ ├── #cc4a#test_rap_unamanaged.ddls.xml
│ ├── #cc4a#test_prefer_methods.fugr.#cc4a#ltest_prefer_methodstop.xml
│ ├── #cc4a#test_modern_language.clas.xml
│ ├── #cc4a#test_prefer_methods.fugr.#cc4a#sapltest_prefer_methods.xml
│ ├── #cc4a#test_proper_bool_expr.clas.xml
│ ├── #cc4a#test_scope_of_variable.clas.xml
│ ├── #cc4a#if_test_avoid_self_ref.intf.xml
│ ├── #cc4a#test_method_signature_if.intf.xml
│ ├── #cc4a#test_for_db_statements.clas.xml
│ ├── #cc4a#test_check_constant_if2.intf.xml
│ ├── #cc4a#test_avoid_test_seam.clas.xml
│ ├── #cc4a#test_prefer_is_not_2.clas.xml
│ ├── #cc4a#test_chain_declaration.clas.xml
│ ├── #cc4a#test_method_signature.clas.xml
│ ├── #cc4a#test_prefer_is_not.clas.xml
│ ├── #cc4a#test_avoid_default_key.clas.xml
│ ├── #cc4a#test_avoid_self_ref_sup.clas.xml
│ ├── #cc4a#test_method_signature_1.clas.xml
│ ├── #cc4a#test_method_signature_2.clas.xml
│ ├── #cc4a#test_check_constant_if1.clas.xml
│ ├── #cc4a#test_equal_sign_chaining.clas.xml
│ ├── #cc4a#test_check_in_iteration.clas.xml
│ ├── #cc4a#test_avoid_self_ref.clas.xml
│ ├── #cc4a#test_db_access_in_ut.clas.xml
│ ├── #cc4a#bp_test_rap_unamanaged.clas.xml
│ ├── #cc4a#test_method_signature_3.clas.xml
│ ├── #cc4a#test_method_signature_3.clas.abap
│ ├── #cc4a#rfc_enabled_module_rfc.sco2.xml
│ ├── #cc4a#test_prefer_methods.fugr.xml
│ ├── #cc4a#test_method_signature_2.clas.abap
│ ├── #cc4a#rfc_enabled_module_rfc_ibs.sia6.xml
│ ├── #cc4a#test_prefer_methods.fugr.#cc4a#sapltest_prefer_methods.abap
│ ├── #cc4a#rfc_enabled_module rf.sush.xml
│ ├── #cc4a#test_method_signature_1.clas.abap
│ ├── #cc4a#test_equal_sign_chaining.clas.abap
│ ├── #cc4a#test_avoid_self_ref.clas.testclasses.abap
│ ├── #cc4a#test_check_constant_if1.clas.locals_imp.abap
│ ├── #cc4a#test_avoid_test_seam.clas.abap
│ ├── #cc4a#test_rap_unamanaged.bdef.xml
│ ├── #cc4a#test_db.tabl.xml
│ ├── #cc4a#test_avoid_default_key.clas.abap
│ ├── #cc4a#bp_test_rap_unamanaged.clas.locals_imp.abap
│ ├── #cc4a#test_avoid_self_ref.clas.locals_imp.abap
│ ├── #cc4a#test_rap.tabl.xml
│ ├── #cc4a#test_check_in_iteration.clas.abap
│ ├── #cc4a#test_modern_language.clas.locals_imp.abap
│ ├── #cc4a#test_avoid_self_ref.clas.abap
│ ├── #cc4a#test_prefer_is_not.clas.abap
│ ├── #cc4a#test_proper_bool_expr.clas.abap
│ ├── #cc4a#tstflight1.tabl.xml
│ ├── #cc4a#test_method_signature.clas.abap
│ ├── #cc4a#test_for_db_statements.clas.abap
│ ├── #cc4a#test_scope_of_variable.clas.abap
│ └── #cc4a#test_chain_declaration.clas.abap
├── core
│ ├── (cc4a)code_pal.chkc.json
│ ├── package.devc.xml
│ ├── #cc4a#if_check_meta_data.intf.abap
│ ├── #cc4a#cx_clause_is_initial.clas.abap
│ ├── #cc4a#cx_line_break_impossible.clas.abap
│ ├── #cc4a#cx_token_is_no_bracket.clas.abap
│ ├── #cc4a#cx_token_is_no_operator.clas.abap
│ ├── #cc4a#if_abap_analyzer.intf.xml
│ ├── #cc4a#if_check_meta_data.intf.xml
│ ├── #cc4a#check_meta_data.clas.xml
│ ├── #cc4a#abap_analyzer.clas.xml
│ ├── #cc4a#cx_clause_is_initial.clas.xml
│ ├── #cc4a#cx_line_break_impossible.clas.xml
│ ├── #cc4a#cx_token_is_no_bracket.clas.xml
│ ├── #cc4a#cx_token_is_no_operator.clas.xml
│ ├── (cc4a)code_pal_remote.chkv.json
│ ├── (cc4a)code_pal_full.chkv.json
│ ├── #cc4a#check_meta_data.clas.abap
│ └── #cc4a#if_abap_analyzer.intf.abap
├── checks
│ ├── #cc4a#modern_language.clas.locals_imp.abap
│ ├── (cc4a)modern.chko.json
│ ├── #cc4a#modern_language.clas.locals_def.abap
│ ├── (cc4a)variable_scope.chko.json
│ ├── (cc4a)prefer_methods.chko.json
│ ├── (cc4a)avoid_test_seam.chko.json
│ ├── (cc4a)assignment_chaining.chko.json
│ ├── (cc4a)chain_declarations.chko.json
│ ├── (cc4a)check_in_iteration.chko.json
│ ├── package.devc.xml
│ ├── (cc4a)prefer_is_not.chko.json
│ ├── (cc4a)avoid_db_access_in_aunit.chko.json
│ ├── (cc4a)constants_interface.chko.json
│ ├── (cc4a)proper_bool_usage.chko.json
│ ├── (cc4a)avoid_self_reference.chko.json
│ ├── (cc4a)avoid_default_key.chko.json
│ ├── #cc4a#avoid_test_seam.clas.xml
│ ├── #cc4a#db_access_in_ut.clas.xml
│ ├── #cc4a#check_constant_interface.clas.xml
│ ├── #cc4a#prefer_is_not.clas.xml
│ ├── #cc4a#avoid_self_reference.clas.xml
│ ├── #cc4a#avoid_default_key.clas.xml
│ ├── #cc4a#scope_of_variable.clas.xml
│ ├── #cc4a#chain_declaration.clas.xml
│ ├── #cc4a#prefer_methods.clas.xml
│ ├── #cc4a#equals_sign_chaining.clas.xml
│ ├── #cc4a#scope_of_variable.clas.locals_def.abap
│ ├── #cc4a#check_in_iteration.clas.xml
│ ├── (cc4a)method_signature.chko.json
│ ├── #cc4a#proper_bool_expression.clas.xml
│ ├── #cc4a#method_signature.clas.xml
│ ├── #cc4a#prefer_methods.clas.testclasses.abap
│ ├── #cc4a#scope_of_variable.clas.locals_imp.abap
│ ├── #cc4a#avoid_test_seam.clas.abap
│ ├── #cc4a#check_constant_interface.clas.testclasses.abap
│ ├── #cc4a#avoid_test_seam.clas.testclasses.abap
│ ├── #cc4a#modern_language.clas.xml
│ ├── #cc4a#prefer_methods.clas.abap
│ ├── #cc4a#check_constant_interface.clas.abap
│ ├── #cc4a#equals_sign_chaining.clas.testclasses.abap
│ ├── #cc4a#avoid_default_key.clas.abap
│ ├── #cc4a#avoid_default_key.clas.testclasses.abap
│ └── #cc4a#equals_sign_chaining.clas.abap
├── package.devc.xml
└── #cc4a#.nspc.xml
├── .abapgit.xml
├── REUSE.toml
├── docs
└── contributing-code.md
├── CONTRIBUTING.md
├── README.md
└── CODE_OF_CONDUCT.md
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | @SAP/code-pal-for-abap-cloud-admin
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_is_not.clas.locals_def.abap:
--------------------------------------------------------------------------------
1 | class tester definition deferred.
2 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_method_signature_if.intf.abap:
--------------------------------------------------------------------------------
1 | INTERFACE /cc4a/test_method_signature_if
2 | PUBLIC .
3 | METHODS public_inst_interface_meth.
4 |
5 | ENDINTERFACE.
6 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#if_test_avoid_self_ref.intf.abap:
--------------------------------------------------------------------------------
1 | interface /cc4a/if_test_avoid_self_ref
2 | public.
3 |
4 | methods meth_1
5 | importing var_1 type i.
6 |
7 | endinterface.
8 |
--------------------------------------------------------------------------------
/src/core/(cc4a)code_pal.chkc.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Code Pal",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_methods.fugr.#cc4a#ltest_prefer_methodstop.abap:
--------------------------------------------------------------------------------
1 | FUNCTION-POOL /CC4A/TEST_PREFER_METHODS. "MESSAGE-ID ..
2 |
3 | * INCLUDE /CC4A/LTEST_PREFER_METHODSD... " Local class definition
4 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#bp_test_rap_unamanaged.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/bp_test_rap_unamanaged definition public abstract final for behavior of /cc4a/test_rap_unamanaged.
2 | endclass.
3 |
4 | class /cc4a/bp_test_rap_unamanaged implementation.
5 | endclass.
6 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_check_constant_if2.intf.abap:
--------------------------------------------------------------------------------
1 | INTERFACE /cc4a/test_check_constant_if2 PUBLIC.
2 | CONSTANTS:
3 | co_1 TYPE symsgty VALUE 'E',
4 | co_2 TYPE symsgty VALUE 'W',
5 | co_3 TYPE symsgty VALUE 'N'.
6 | ENDINTERFACE.
7 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#modern_language.clas.locals_imp.abap:
--------------------------------------------------------------------------------
1 | *"* use this source file for the definition and implementation of
2 | *"* local helper classes, interface definitions and type
3 | *"* declarations
4 |
5 | class lcx_error implementation.
6 | endclass.
7 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)modern.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Modern Language",
5 | "originalLanguage": "en"
6 | },
7 | "category": "/CC4A/CODE_PAL",
8 | "implementingClass": "/CC4A/MODERN_LANGUAGE",
9 | "checkType": "remoteEnabled"
10 | }
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_rap_unamanaged.ddls.baseinfo:
--------------------------------------------------------------------------------
1 | {
2 | "BASEINFO":
3 | {
4 | "FROM":
5 | [
6 | "/CC4A/TEST_RAP"
7 | ],
8 | "ASSOCIATED":
9 | [],
10 | "BASE":
11 | [],
12 | "ANNO_REF":
13 | [],
14 | "SCALAR_FUNCTION":
15 | [],
16 | "VERSION":0,
17 | "ANNOREF_EVALUATION_ERROR":""
18 | }
19 | }
--------------------------------------------------------------------------------
/src/checks/#cc4a#modern_language.clas.locals_def.abap:
--------------------------------------------------------------------------------
1 | *"* use this source file for any type of declarations (class
2 | *"* definitions, interfaces or type declarations) you need for
3 | *"* components in the private section
4 | class lcx_error definition final
5 | inheriting from cx_static_check.
6 | endclass.
7 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)variable_scope.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Scope of Variable",
5 | "originalLanguage": "en"
6 | },
7 | "category": "/CC4A/CODE_PAL",
8 | "implementingClass": "/CC4A/SCOPE_OF_VARIABLE",
9 | "checkType": "remoteEnabled"
10 | }
11 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_check_constant_if1.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS /cc4a/test_check_constant_if1 DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 | PROTECTED SECTION.
8 | PRIVATE SECTION.
9 | ENDCLASS.
10 |
11 |
12 |
13 | CLASS /CC4A/TEST_CHECK_CONSTANT_IF1 IMPLEMENTATION.
14 | ENDCLASS.
15 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_db_access_in_ut.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_db_access_in_ut definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | protected section.
8 | private section.
9 | endclass.
10 |
11 |
12 |
13 | class /cc4a/test_db_access_in_ut implementation.
14 | endclass.
15 |
16 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_methods.fugr.#cc4a#rfc_disabled_module.abap:
--------------------------------------------------------------------------------
1 | FUNCTION /CC4A/RFC_DISABLED_MODULE.
2 | *"--------------------------------------------------------------------
3 | *"*"Local Interface:
4 | *"--------------------------------------------------------------------
5 |
6 |
7 |
8 |
9 |
10 | ENDFUNCTION.
11 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_methods.fugr.#cc4a#rfc_enabled_module.abap:
--------------------------------------------------------------------------------
1 | FUNCTION /CC4A/RFC_ENABLED_MODULE.
2 | *"--------------------------------------------------------------------
3 | *"*"Local Interface:
4 | *"--------------------------------------------------------------------
5 |
6 |
7 |
8 |
9 |
10 | ENDFUNCTION.
11 |
--------------------------------------------------------------------------------
/.abapgit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | E
6 | /src/
7 | PREFIX
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)prefer_methods.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Prefer methods over other procedures",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/PREFER_METHODS"
10 | }
11 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_is_not.clas.locals_imp.abap:
--------------------------------------------------------------------------------
1 | class tester definition final.
2 | public section.
3 | methods check
4 | importing val type i
5 | returning value(bool) type abap_bool.
6 | endclass.
7 |
8 | CLASS tester IMPLEMENTATION.
9 |
10 | METHOD check.
11 |
12 | ENDMETHOD.
13 |
14 | ENDCLASS.
15 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)avoid_test_seam.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Usage of TEST-SEAM",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/AVOID_TEST_SEAM",
10 | "checkType": "remoteEnabled"
11 | }
12 |
--------------------------------------------------------------------------------
/src/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Code Pal for Cloud
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)assignment_chaining.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Assignment Chaining",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/EQUALS_SIGN_CHAINING",
10 | "checkType": "remoteEnabled"
11 | }
12 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)chain_declarations.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Chained declarations",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/CHAIN_DECLARATION",
10 | "checkType": "remoteEnabled"
11 | }
12 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)check_in_iteration.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Check in iteration",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/CHECK_IN_ITERATION",
10 | "checkType": "remoteEnabled"
11 | }
12 |
--------------------------------------------------------------------------------
/src/checks/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Check implementations
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)prefer_is_not.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "\"NOT IS\" in logical expressions",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/PREFER_IS_NOT",
10 | "checkType": "remoteEnabled"
11 | }
12 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)avoid_db_access_in_aunit.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Database access in unit-tests",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/DB_ACCESS_IN_UT",
10 | "checkType": "remoteEnabled"
11 | }
12 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)constants_interface.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Constants in Interfaces",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/CHECK_CONSTANT_INTERFACE",
10 | "checkType": "remoteEnabled"
11 | }
12 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)proper_bool_usage.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Standard Boolean Expressions",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/PROPER_BOOL_EXPRESSION",
10 | "checkType": "remoteEnabled"
11 | }
12 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_rap_unamanaged.bdef.asbdef:
--------------------------------------------------------------------------------
1 | unmanaged implementation in class /cc4a/bp_test_rap_unamanaged unique;
2 | strict ( 2 );
3 |
4 | define behavior for /CC4A/TEST_RAP_UNAMANAGED //alias
5 | //late numbering
6 | lock master
7 | authorization master ( instance )
8 | //etag master
9 | {
10 | create;
11 | update;
12 | delete;
13 | }
--------------------------------------------------------------------------------
/src/test_objects/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Test objects for Code Pal
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)avoid_self_reference.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Find unnecessary self-references",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/AVOID_SELF_REFERENCE",
10 | "checkType": "remoteEnabled"
11 | }
12 |
--------------------------------------------------------------------------------
/src/core/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Code Pal for Cloud core functionality
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)avoid_default_key.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Internal table definitions with default key",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/AVOID_DEFAULT_KEY",
10 | "checkType": "remoteEnabled"
11 | }
12 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_avoid_self_ref_sup.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_avoid_self_ref_sup definition
2 | public
3 | create public .
4 |
5 | public section.
6 | methods super_meth
7 | importing imp type i.
8 | protected section.
9 | private section.
10 | endclass.
11 |
12 |
13 |
14 | class /cc4a/test_avoid_self_ref_sup implementation.
15 |
16 | method super_meth.
17 |
18 | endmethod.
19 |
20 | endclass.
21 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_rap_unamanaged.ddls.asddls:
--------------------------------------------------------------------------------
1 | @AccessControl.authorizationCheck: #NOT_REQUIRED
2 | define root view entity /CC4A/TEST_RAP_UNAMANAGED
3 | as select from /cc4a/test_rap
4 | {
5 | key key_field as KeyFieldRoot,
6 | data_field as DataFieldRoot,
7 | char_field as CharFieldRoot,
8 | crea_date_time as Timestamp,
9 | lchg_date_time as LastChangedAt
10 | }
11 |
--------------------------------------------------------------------------------
/src/core/#cc4a#if_check_meta_data.intf.abap:
--------------------------------------------------------------------------------
1 | interface /cc4a/if_check_meta_data
2 | public.
3 |
4 | interfaces if_ci_atc_check_meta_data.
5 |
6 | methods has_valid_pseudo_comment
7 | importing
8 | statement type if_ci_atc_source_code_provider=>ty_statement
9 | finding_code type if_ci_atc_check_meta_data=>ty_finding_code_info-code
10 | returning value(has_valid_pseudo_comment) type abap_bool.
11 |
12 | endinterface.
13 |
--------------------------------------------------------------------------------
/REUSE.toml:
--------------------------------------------------------------------------------
1 | version = 1
2 | SPDX-PackageName = "code pal for ABAP cloud"
3 | SPDX-PackageSupplier = "code pal for ABAP cloud team (@SAP/code-pal-for-abap-cloud-team)"
4 | SPDX-PackageDownloadLocation = "https://github.com/SAP/code-pal-for-abap-cloud"
5 |
6 | [[annotations]]
7 | path = "**"
8 | precedence = "aggregate"
9 | SPDX-FileCopyrightText = "2021 SAP SE or an SAP affiliate company and code pal for ABAP contributors"
10 | SPDX-License-Identifier = "Apache-2.0"
11 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_is_not_2.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_prefer_is_not_2 definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | protected section.
8 | private section.
9 | methods meth.
10 | endclass.
11 |
12 |
13 |
14 | class /cc4a/test_prefer_is_not_2 implementation.
15 |
16 | method meth.
17 | data(var_1) = 1.
18 | data(var_2) = 2.
19 | if var_1 is not initial and var_2 <> 2.
20 | endif.
21 | endmethod.
22 |
23 | endclass.
24 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_rap_unamanaged.ddls.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_RAP_UNAMANAGED
7 | E
8 | Test RAP unmanaged
9 | W
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.github/workflows/on_pull_request.yml:
--------------------------------------------------------------------------------
1 | name: CI (on pull request)
2 |
3 | on: pull_request_target
4 |
5 | permissions:
6 | checks: write
7 | contents: read
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
15 | - uses: actions/checkout@v3
16 |
17 | - name: abaplint
18 | uses: abaplint/actions-abaplint@main
19 | env:
20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21 |
--------------------------------------------------------------------------------
/src/core/#cc4a#cx_clause_is_initial.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/cx_clause_is_initial definition
2 | public
3 | inheriting from cx_dynamic_check
4 | final
5 | create public .
6 |
7 | public section.
8 |
9 | methods constructor.
10 | protected section.
11 | private section.
12 | endclass.
13 |
14 |
15 |
16 | class /cc4a/cx_clause_is_initial implementation.
17 | method constructor ##ADT_SUPPRESS_GENERATION.
18 |
19 | super->constructor( textid = textid previous = previous ).
20 |
21 | endmethod.
22 |
23 | endclass.
24 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug.md:
--------------------------------------------------------------------------------
1 | ---
2 | name : Bug
3 | about : Use this template to report a bug, in particular false positive or negative findings from the Code Pal checks
4 | labels : bug
5 |
6 | ---
7 |
8 | **Affected Checks**
9 | > Which of the Code Pal checks is this about?
10 |
11 | **Expectation**
12 | > Describe the expected behavior of the check(s).
13 |
14 | **Actual Behavior**
15 | > Describe the actual behavior of the check(s).
16 |
17 | **Code**
18 | > If applicable, post an ABAP code example with which the behavior can be reproduced.
--------------------------------------------------------------------------------
/src/core/#cc4a#cx_line_break_impossible.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/cx_line_break_impossible definition
2 | public
3 | inheriting from cx_dynamic_check
4 | final
5 | create public .
6 |
7 | public section.
8 |
9 | methods constructor.
10 | protected section.
11 | private section.
12 | endclass.
13 |
14 |
15 |
16 | class /cc4a/cx_line_break_impossible implementation.
17 | method constructor ##ADT_SUPPRESS_GENERATION.
18 |
19 | super->constructor( textid = textid previous = previous ).
20 |
21 | endmethod.
22 |
23 | endclass.
24 |
--------------------------------------------------------------------------------
/src/core/#cc4a#cx_token_is_no_bracket.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/cx_token_is_no_bracket definition
2 | public
3 | inheriting from cx_dynamic_check
4 | final
5 | create public .
6 |
7 | public section.
8 |
9 | methods constructor.
10 | protected section.
11 | private section.
12 | ENDCLASS.
13 |
14 |
15 |
16 | CLASS /CC4A/CX_TOKEN_IS_NO_BRACKET IMPLEMENTATION.
17 |
18 |
19 | method constructor ##ADT_SUPPRESS_GENERATION.
20 |
21 | super->constructor( textid = textid previous = previous ).
22 |
23 | endmethod.
24 | ENDCLASS.
25 |
--------------------------------------------------------------------------------
/src/#cc4a#.nspc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/
7 | 22229904900326563203
8 |
9 |
10 | E
11 | Clean Code for ABAP
12 | FIEDLERT
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/core/#cc4a#cx_token_is_no_operator.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/cx_token_is_no_operator definition
2 | public
3 | inheriting from cx_dynamic_check
4 | final
5 | create public .
6 |
7 | public section.
8 |
9 | methods constructor.
10 | protected section.
11 | private section.
12 | ENDCLASS.
13 |
14 |
15 |
16 | CLASS /CC4A/CX_TOKEN_IS_NO_OPERATOR IMPLEMENTATION.
17 |
18 |
19 | method constructor ##ADT_SUPPRESS_GENERATION.
20 |
21 | super->constructor( textid = textid previous = previous ).
22 |
23 | endmethod.
24 | ENDCLASS.
25 |
--------------------------------------------------------------------------------
/src/core/#cc4a#if_abap_analyzer.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/IF_ABAP_ANALYZER
7 | E
8 | ABAP code analysis
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_methods.fugr.#cc4a#ltest_prefer_methodstop.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/LTEST_PREFER_METHODSTOP
7 | S
8 | D$
9 | I
10 | S
11 | X
12 | D$S
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/core/#cc4a#if_check_meta_data.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/IF_CHECK_META_DATA
7 | E
8 | Shared meta data for checks
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_modern_language.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_MODERN_LANGUAGE
7 | E
8 | test
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_methods.fugr.#cc4a#sapltest_prefer_methods.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/SAPLTEST_PREFER_METHODS
7 | S
8 | D$
9 | F
10 | S
11 | E
12 | X
13 | D$S
14 | 5
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_proper_bool_expr.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_PROPER_BOOL_EXPR
7 | E
8 | Test
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_scope_of_variable.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_SCOPE_OF_VARIABLE
7 | E
8 | Test
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/new-check.md:
--------------------------------------------------------------------------------
1 | ---
2 | name : New check
3 | about : Use this template to propose a new Code Pal check
4 | labels : feature-request
5 |
6 | ---
7 |
8 | **Relevant style guide recommendations**
9 | > Explain which sections of the [Clean ABAP style guide](https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md) the new check is supposed to implement.
10 |
11 | **Feasibility**
12 | > Explain how this part of the style guide could be checked automatically
13 |
14 | **Prior Work**
15 | > Are there already other ATC checks (outside of Code Pal) that implement similar features?
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#if_test_avoid_self_ref.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/IF_TEST_AVOID_SELF_REF
7 | E
8 | Test object for /CC4A/AVOID_SELF_REFERENCE
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_method_signature_if.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_METHOD_SIGNATURE_IF
7 | E
8 | Test Interface for check Method Signature
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/core/#cc4a#check_meta_data.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/CHECK_META_DATA
7 | E
8 | Shared meta data implementation for all checks
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_for_db_statements.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_FOR_DB_STATEMENTS
7 | E
8 | test for db statements
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_check_constant_if2.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_CHECK_CONSTANT_IF2
7 | E
8 | Test Interface for check Constants Interface Check
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_avoid_test_seam.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_AVOID_TEST_SEAM
7 | E
8 | Test class for check Avoid TEST-SEAM
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_is_not_2.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_PREFER_IS_NOT_2
7 | E
8 | Test object for /CC4A/PREFER_IS_NOT
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/core/#cc4a#abap_analyzer.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/ABAP_ANALYZER
7 | E
8 | ABAP code analysis
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/core/#cc4a#cx_clause_is_initial.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/CX_CLAUSE_IS_INITIAL
7 | E
8 | clause is initial
9 | 40
10 | 1
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_chain_declaration.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_CHAIN_DECLARATION
7 | E
8 | Test class for check Chain Declaration
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_method_signature.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_METHOD_SIGNATURE
7 | E
8 | Test class for check Message Easy to Find
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_is_not.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_PREFER_IS_NOT
7 | E
8 | Test class for check Prefer IS NOT to NOT IS
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_avoid_default_key.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_AVOID_DEFAULT_KEY
7 | E
8 | Test class for check Avoid Default Table Key
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_avoid_self_ref_sup.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_AVOID_SELF_REF_SUP
7 | E
8 | Test object for /CC4A/AVOID_SELF_REFERENCE
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_method_signature_1.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_METHOD_SIGNATURE_1
7 | E
8 | Test class for check Message Easy to Find
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_method_signature_2.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_METHOD_SIGNATURE_2
7 | E
8 | Test class for check Message Easy to Find
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_check_constant_if1.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_CHECK_CONSTANT_IF1
7 | E
8 | Test Class for check Constants Interface Check
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_equal_sign_chaining.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_EQUAL_SIGN_CHAINING
7 | E
8 | Test class for check Equals Sign Chaining
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/core/#cc4a#cx_line_break_impossible.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/CX_LINE_BREAK_IMPOSSIBLE
7 | E
8 | line break impossible
9 | 40
10 | 1
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_check_in_iteration.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_CHECK_IN_ITERATION
7 | E
8 | Test class for check statements within iterations
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/core/#cc4a#cx_token_is_no_bracket.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/CX_TOKEN_IS_NO_BRACKET
7 | E
8 | Exception if given token is not a bracket
9 | 40
10 | 1
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/core/#cc4a#cx_token_is_no_operator.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/CX_TOKEN_IS_NO_OPERATOR
7 | E
8 | Exception if given token is not an operator
9 | 40
10 | 1
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_avoid_self_ref.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_AVOID_SELF_REF
7 | E
8 | Test class for check Avoid Self Reference
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_db_access_in_ut.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_DB_ACCESS_IN_UT
7 | E
8 | Test class for check Avoid database access in unit-tests
9 | 1
10 | X
11 | X
12 | 5
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#bp_test_rap_unamanaged.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/BP_TEST_RAP_UNAMANAGED
7 | E
8 | Behavior Implementation for /CC4A/TEST_RAP_UNAMANAGED
9 | 06
10 | 1
11 | X
12 | X
13 | X
14 | /CC4A/TEST_RAP_UNAMANAGED
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_method_signature_3.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_METHOD_SIGNATURE_3
7 | E
8 | Test class for check Message Easy to Find
9 | 05
10 | 1
11 | X
12 | X
13 | X
14 | 12
15 | 11
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_method_signature_3.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS /cc4a/test_method_signature_3 DEFINITION
2 | PUBLIC ABSTRACT CREATE PUBLIC
3 | FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
4 |
5 | PUBLIC SECTION.
6 | METHODS public_inst_no_interface_meth1 FOR TESTING.
7 | METHODS public_inst_no_interface_meth2.
8 |
9 | PROTECTED SECTION.
10 |
11 | PRIVATE SECTION.
12 |
13 | ENDCLASS.
14 |
15 |
16 |
17 | CLASS /CC4A/TEST_METHOD_SIGNATURE_3 IMPLEMENTATION.
18 |
19 |
20 | METHOD public_inst_no_interface_meth1.
21 | "only signature is relevant for this test
22 | ENDMETHOD.
23 |
24 |
25 | METHOD public_inst_no_interface_meth2.
26 | "only signature is relevant for this test
27 | ENDMETHOD.
28 | ENDCLASS.
29 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#rfc_enabled_module_rfc.sco2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/RFC_ENABLED_MODULE_RFC
7 | SRFC
8 | /CC4A/RFC_ENABLED_MODULE
9 | X
10 | 5
11 | /CC4A/RFC_ENABLED_MODULE_RFC
12 | RFC Service /CC4A/RFC_ENABLED_MODULE
13 | 5
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_methods.fugr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Test class for prefer methods check
6 |
7 | /CC4A/LTEST_PREFER_METHODSTOP
8 | /CC4A/SAPLTEST_PREFER_METHODS
9 |
10 |
11 | -
12 | /CC4A/RFC_DISABLED_MODULE
13 | Test module where rfc is disabled
14 |
15 | -
16 | /CC4A/RFC_ENABLED_MODULE
17 | R
18 | Test module where rfc is enabled
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_method_signature_2.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS /cc4a/test_method_signature_2 DEFINITION
2 | INHERITING FROM /cc4a/test_method_signature_1
3 | PUBLIC
4 | FINAL
5 | CREATE PUBLIC .
6 |
7 | PUBLIC SECTION.
8 | METHODS public_inst_no_interface_meth1 REDEFINITION.
9 | METHODS public_inst_no_interface_meth3.
10 |
11 | PROTECTED SECTION.
12 |
13 | PRIVATE SECTION.
14 | METHODS priv_inst_not_interface_meth.
15 |
16 | ENDCLASS.
17 |
18 |
19 |
20 | CLASS /CC4A/TEST_METHOD_SIGNATURE_2 IMPLEMENTATION.
21 |
22 |
23 | METHOD priv_inst_not_interface_meth.
24 | "only signature is relevant for this test
25 | ENDMETHOD.
26 |
27 |
28 | METHOD public_inst_no_interface_meth1.
29 | "only signature is relevant for this test
30 | ENDMETHOD.
31 |
32 |
33 | METHOD public_inst_no_interface_meth3.
34 | "only signature is relevant for this test
35 | ENDMETHOD.
36 | ENDCLASS.
37 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#avoid_test_seam.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/AVOID_TEST_SEAM
7 | E
8 | Avoid using TEST-SEAM
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DES
19 | Usage of TEST-SEAM
20 | 88
21 |
22 | -
23 | I
24 | UOT
25 | Usage of TEST-SEAM
26 | 88
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#db_access_in_ut.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/DB_ACCESS_IN_UT
7 | E
8 | Avoid database access in unit tests
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DAU
19 | Database access in unit test
20 | 88
21 |
22 | -
23 | I
24 | DES
25 | Database access in unit tests
26 | 88
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#check_constant_interface.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/CHECK_CONSTANT_INTERFACE
7 | E
8 | Constants Interface Check
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DES
19 | Constants in Interfaces
20 | 132
21 |
22 | -
23 | I
24 | MC1
25 | Interface contains only constants
26 | 132
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#rfc_enabled_module_rfc_ibs.sia6.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | /CC4A/RFC_ENABLED_MODULE_RFC_IBS
8 | SIA6
9 | RFC Service /CC4A/RFC_ENABLED_MODULE
10 | CB9980000871
11 | EN
12 | X11
13 |
14 | /CC4A/CODE_PAL_TEST_OBJECTS
15 |
16 | 5
17 |
18 | /CC4A/RFC_ENABLED_MODULE_RFC_IBS
19 | IBS
20 | 5
21 | /CC4A/RFC_ENABLED_MODULE_RFC
22 | p
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/contributing-code.md:
--------------------------------------------------------------------------------
1 | All objects belonging to Code Pal for Cloud should lie in the `/CC4A/` namespace. The basic package structure is:
2 | - `core` for functionality shared by more than one check
3 | - `check` for the actual check implementation and their "ATC Check" objects
4 | - `test_objects` for test objects, i.e. everything that only exists for the automated (unit) tests
5 |
6 | All our code should conform to the recommendations of the [Clean ABAP style guide](https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md). In particular this means that there should be no findings from Code Pal checks on Code Pal code.
7 |
8 | SAP's new check implementation framework via the interface `IF_CI_ATC_CHECK` is no longer based on inheritance, so we also prefer composition over inheritance: Instead of having check classes share logic by subclassing, they should delegate shared logic to other global classes. `/CC4A/CHECK_META_DATA` does this for the checks' meta data and `/CC4A/ABAP_ANALYZER` should contain all logic that analyzes ABAP code. Do not hesitate to add methods to these classes or introduce new classes for more shared functionality.
--------------------------------------------------------------------------------
/src/checks/#cc4a#prefer_is_not.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/PREFER_IS_NOT
7 | E
8 | Prefer IS NOT to NOT IS
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DES
19 | Prefer IS NOT to NOT IS
20 | 88
21 |
22 | -
23 | I
24 | NIC
25 | Usage of NOT IS condition
26 | 88
27 |
28 | -
29 | I
30 | QIN
31 | Replace NOT IS condition with IS NOT
32 | 88
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#avoid_self_reference.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/AVOID_SELF_REFERENCE
7 | E
8 | Avoid self-reference
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DES
19 | Find unnecessary self-references
20 | 88
21 |
22 | -
23 | I
24 | DUS
25 | Unnecessary self-reference
26 | 88
27 |
28 | -
29 | I
30 | QRS
31 | Remove self-reference
32 | 88
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#avoid_default_key.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/AVOID_DEFAULT_KEY
7 | E
8 | Avoid Default Table Keys
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DES
19 | Avoid default keys
20 | 88
21 |
22 | -
23 | I
24 | DTK
25 | Usage of default table key
26 | 88
27 |
28 | -
29 | I
30 | QEK
31 | Replace WITH DEFAULT KEY with WITH EMPTY KEY
32 | 88
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#scope_of_variable.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/SCOPE_OF_VARIABLE
7 | E
8 | Scope of Variable
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | 001
19 | Variable &1 declared inside block and used outside
20 | 94
21 |
22 | -
23 | I
24 | DES
25 | Scope of Variable
26 | 27
27 |
28 | -
29 | I
30 | QF1
31 | Change scope of variable
32 | 48
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#chain_declaration.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/CHAIN_DECLARATION
7 | E
8 | Avoid chain declaration
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DES
19 | Avoid Chain Declaration
20 | 88
21 |
22 | -
23 | I
24 | QSD
25 | Replace Chain Declaration with Single Declaration
26 | 88
27 |
28 | -
29 | I
30 | UCD
31 | Usage of Chain Declaration
32 | 88
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#prefer_methods.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/PREFER_METHODS
7 | E
8 | Prefer methods over other procedures
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DES
19 | Prefer methods over other procedures
20 | 88
21 |
22 | -
23 | I
24 | PRM
25 | Definition of function module &1
26 | 88
27 |
28 | -
29 | I
30 | UFR
31 | Definition of FORM routine &1
32 | 88
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#equals_sign_chaining.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/EQUALS_SIGN_CHAINING
7 | E
8 | Equals Sign Chaining
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DES
19 | Assignment Chaining
20 | 132
21 |
22 | -
23 | I
24 | MC1
25 | Values are allocated more than once within one statement
26 | 132
27 |
28 | -
29 | I
30 | Q1S
31 | Break assignment chain into multiple rows
32 | 132
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_methods.fugr.#cc4a#sapltest_prefer_methods.abap:
--------------------------------------------------------------------------------
1 | *******************************************************************
2 | * System-defined Include-files. *
3 | *******************************************************************
4 | INCLUDE /CC4A/LTEST_PREFER_METHODSTOP. " Global Declarations
5 | INCLUDE /CC4A/LTEST_PREFER_METHODSUXX. " Function Modules
6 |
7 | *******************************************************************
8 | * User-defined Include-files (if necessary). *
9 | *******************************************************************
10 | * INCLUDE /CC4A/LTEST_PREFER_METHODSF... " Subroutines
11 | * INCLUDE /CC4A/LTEST_PREFER_METHODSO... " PBO-Modules
12 | * INCLUDE /CC4A/LTEST_PREFER_METHODSI... " PAI-Modules
13 | * INCLUDE /CC4A/LTEST_PREFER_METHODSE... " Events
14 | * INCLUDE /CC4A/LTEST_PREFER_METHODSP... " Local class implement.
15 | * INCLUDE /CC4A/LTEST_PREFER_METHODST99. " ABAP Unit tests
16 |
17 | form test_form.
18 |
19 |
20 | endform.
21 |
22 | form pseudo_comment. "#EC CI_FROM
23 |
24 |
25 | endform.
26 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#scope_of_variable.clas.locals_def.abap:
--------------------------------------------------------------------------------
1 | types ty_block_list type sorted table of i with unique key table_line.
2 |
3 | class block_finder definition final.
4 | public section.
5 | types:
6 | begin of ty_block_info,
7 | block type i,
8 | inside_injection type abap_bool,
9 | end of ty_block_info.
10 |
11 | methods constructor
12 | importing
13 | blocks type if_ci_atc_source_code_provider=>ty_blocks
14 | first_valid_block type i.
15 | methods find_parent_branch
16 | importing block type i
17 | returning value(result) type ty_block_info.
18 | methods find_outer_block
19 | importing blocks type ty_block_list
20 | returning value(result) type i.
21 | private section.
22 | data first_valid_block type i.
23 | data blocks type if_ci_Atc_source_code_provider=>ty_blocks.
24 |
25 | methods least_common_parent
26 | importing
27 | block_1 type i
28 | block_2 type i
29 | returning
30 | value(result) type i.
31 | methods is_parent
32 | importing
33 | parent type i
34 | child type i
35 | returning
36 | value(result) type abap_bool.
37 | endclass.
38 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#check_in_iteration.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/CHECK_IN_ITERATION
7 | E
8 | Avoid using of CHECK-statement
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DES
19 | Avoid using of CHECK-statement
20 | 88
21 |
22 | -
23 | I
24 | ICC
25 | Replace CHECK condition with IF condition
26 | 88
27 |
28 | -
29 | I
30 | USG
31 | Usage of CHECK-statement
32 | 88
33 |
34 | -
35 | I
36 | WLD
37 | Replace CHECK condition with a WHERE condition in loop
38 | 88
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#rfc_enabled_module rf.sush.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/RFC_ENABLED_MODULE
7 | RF
8 | /CC4A/RFC_ENABLED_MODULE
9 | Test module where rfc is enabled
10 | /CC4A/CODE_PAL_TEST_OBJECTS
11 | 5
12 |
13 |
14 |
15 | /CC4A/RFC_ENABLED_MODULE
16 | RF
17 |
18 | X
19 |
20 |
21 |
22 | -
23 |
24 | Authorization Check for RFC Access
25 | AAAB
26 | X
27 | SRCX
28 | BC-MID-RFC
29 | Check
30 | Check
31 | No
32 | 3
33 | Okay
34 | @08@
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/checks/(cc4a)method_signature.chko.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Method Signature",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "category": "/CC4A/CODE_PAL",
9 | "implementingClass": "/CC4A/METHOD_SIGNATURE",
10 | "checkType": "remoteEnabled",
11 | "parameters": [
12 | {
13 | "name": "CheckPubMethodNoInterface",
14 | "description": "Check for public methods which are not in an interface"
15 | },
16 | {
17 | "name": "CheckInputParamBoolean",
18 | "description": "Check for importing parameter of type boolean"
19 | },
20 | {
21 | "name": "CheckInputParamOptional",
22 | "description": "Check for importing parameter which are optional"
23 | },
24 | {
25 | "name": "CheckOutputParamNumber",
26 | "description": "Check number of output parameter (exporting, changing, returning)"
27 | },
28 | {
29 | "name": "CheckOutputParamType",
30 | "description": "Check for output parameter combinations (exporting, changing, returning)"
31 | },
32 | {
33 | "name": "CheckRetParamNotNamedResult",
34 | "description": "Check returning parameter not named RESULT"
35 | },
36 | {
37 | "name": "CheckExpParamNumberNotOne",
38 | "description": "Check number of exporting parameter more than 1"
39 | }
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_method_signature_1.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS /cc4a/test_method_signature_1 DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC ABSTRACT.
4 |
5 | PUBLIC SECTION.
6 | INTERFACES /cc4a/test_method_signature_if.
7 |
8 | CLASS-METHODS public_stat_no_interface_meth.
9 |
10 | METHODS constructor.
11 | METHODS public_inst_no_interface_meth1 ABSTRACT.
12 | METHODS public_inst_no_interface_meth2.
13 |
14 | PROTECTED SECTION.
15 | METHODS prot_inst_not_interface_meth.
16 |
17 | PRIVATE SECTION.
18 | METHODS priv_inst_not_interface_meth.
19 |
20 | ENDCLASS.
21 |
22 |
23 |
24 | CLASS /CC4A/TEST_METHOD_SIGNATURE_1 IMPLEMENTATION.
25 |
26 |
27 | METHOD /cc4a/test_method_signature_if~public_inst_interface_meth.
28 | "only signature is relevant for this test
29 | ENDMETHOD.
30 |
31 |
32 | METHOD constructor.
33 | "only signature is relevant for this test
34 | ENDMETHOD.
35 |
36 |
37 | METHOD priv_inst_not_interface_meth.
38 | "only signature is relevant for this test
39 | ENDMETHOD.
40 |
41 |
42 | METHOD prot_inst_not_interface_meth.
43 | "only signature is relevant for this test
44 | ENDMETHOD.
45 |
46 |
47 | METHOD public_inst_no_interface_meth2.
48 | "only signature is relevant for this test
49 | ENDMETHOD.
50 |
51 |
52 | METHOD public_stat_no_interface_meth.
53 | "only signature is relevant for this test
54 | ENDMETHOD.
55 | ENDCLASS.
56 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | ## Code of Conduct
4 |
5 | All members of the project community must abide by the [Contributor Covenant, version 2.1](CODE_OF_CONDUCT.md).
6 | Only by respecting each other we can develop a productive, collaborative community.
7 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting [a project maintainer](.reuse/dep5).
8 |
9 | ## Contributing Code or Documentation
10 |
11 | Contributions should be submitted as GitHub pull requests.
12 |
13 | - If you're working on a contribution that will resolve an issue, please claim that issue beforehand (by commenting on it) so that other people know you're working on it.
14 | - Contributions must be licensed under the [Apache 2.0 License](./LICENSE)
15 | - For legal reasons, contributors will be asked to accept a Developer Certificate of Origin (DCO) when they create their first pull request to this project. This happens in an automated fashion during the submission process. SAP uses [the standard DCO text of the Linux Foundation](https://developercertificate.org/).
16 |
17 | See our [guide for code contributors](contributing-code.md) for coding style and architectural guidelines.
18 |
19 | ## Issues and Planning
20 |
21 | We use GitHub issues to track bugs and enhancement requests.
22 |
23 | Please provide as much context as possible when you open an issue. In particular, when reporting a false positive or negative finding, always provide a code sample with which other contributors can reproduce that finding.
24 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_equal_sign_chaining.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS /cc4a/test_equal_sign_chaining DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 | " Currently one method per finding needed due to a bug in CL_CI_ATC_UNIT_DRIVER
8 | METHODS finding_1.
9 | METHODS finding_2.
10 | METHODS finding_3.
11 | METHODS finding_4.
12 | protected section.
13 | private section.
14 | ENDCLASS.
15 |
16 |
17 |
18 | CLASS /CC4A/TEST_EQUAL_SIGN_CHAINING IMPLEMENTATION.
19 |
20 |
21 | METHOD finding_1.
22 | DATA:
23 | a TYPE string,
24 | b TYPE string,
25 | c TYPE string,
26 | d TYPE string.
27 | a = b = c = d.
28 | " Space needed because of bug
29 | " Space needed because of bug
30 | ENDMETHOD.
31 |
32 |
33 | METHOD finding_2.
34 | DATA:
35 | a TYPE string,
36 | b TYPE string,
37 | c TYPE string.
38 | a = b = CONV #( c ).
39 | ENDMETHOD.
40 |
41 |
42 | METHOD finding_3.
43 | DATA:
44 | a TYPE string,
45 | b TYPE string,
46 | c TYPE string,
47 | d TYPE string.
48 | a = b = c = d. "#EC EQUALS_CHAINING
49 | " Space needed because of bug
50 | " Space needed because of bug
51 | ENDMETHOD.
52 |
53 |
54 | METHOD finding_4.
55 | DATA:
56 | a TYPE string,
57 | b TYPE string,
58 | c TYPE string.
59 | " Intentional offset, don't pretty print
60 | a = b = c.
61 | " Space needed because of bug
62 | ENDMETHOD.
63 | ENDCLASS.
64 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_avoid_self_ref.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 | class test definition final for testing
2 | duration short
3 | risk level harmless.
4 |
5 | private section.
6 |
7 | data att1 type i.
8 | data att2 type string.
9 | data att3 type c.
10 | data att4 type i.
11 | data att5 type string.
12 | methods m1 importing att1 type i.
13 | methods m2 changing att3 type c.
14 | methods m3 returning value(att4) type string.
15 | endclass.
16 |
17 | class test implementation.
18 | method m1.
19 |
20 | endmethod.
21 |
22 | method m2.
23 | data att2 type f.
24 | me->att2 = 'Hugo'.
25 | att2 = '1.2'.
26 | me->att3 = 'Hugo'.
27 | me->att4 = 7.
28 | endmethod.
29 |
30 | method m3.
31 | me->att4 = 5.
32 | me->att1 = 2.
33 | att4 = 'HUHU'.
34 | endmethod.
35 | endclass.
36 |
37 | class test2 definition final for testing
38 | duration short
39 | risk level harmless.
40 |
41 | private section.
42 |
43 | data att1 type i.
44 | data att2 type string.
45 | data att3 type c.
46 | data att4 type i.
47 | data att5 type string.
48 | methods m1.
49 | methods m2.
50 | methods m3.
51 | endclass.
52 |
53 | class test2 implementation.
54 | method m1.
55 |
56 | endmethod.
57 |
58 | method m2.
59 | data att2 type f.
60 | me->att2 = 'Hugo'.
61 | att2 = '1.2'.
62 | me->att3 = 'Hugo'.
63 | me->att4 = 7.
64 | endmethod.
65 |
66 | method m3.
67 | me->att4 = 5.
68 | me->att1 = 2.
69 | att4 = 'HUHU'.
70 | endmethod.
71 | endclass.
72 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_check_constant_if1.clas.locals_imp.abap:
--------------------------------------------------------------------------------
1 | *"* use this source file for the definition and implementation of
2 | *"* local helper classes, interface definitions and type
3 | *"* declarations
4 | INTERFACE if_local_1.
5 | " Finding expected
6 | CONSTANTS:
7 | co_1 TYPE symsgty VALUE 'E',
8 | co_2 TYPE symsgty VALUE 'W',
9 | co_3 TYPE symsgty VALUE 'N'.
10 | ENDINTERFACE.
11 |
12 | CLASS cl_local_1 DEFINITION.
13 | PUBLIC SECTION.
14 | INTERFACES if_local_1.
15 | ENDCLASS.
16 |
17 | INTERFACE if_local_2.
18 | " Finding expected
19 | CONSTANTS:
20 | co_1 TYPE symsgty VALUE 'E',
21 | co_2 TYPE symsgty VALUE 'W',
22 | co_3 TYPE symsgty VALUE 'N'.
23 | ENDINTERFACE.
24 |
25 | CLASS cl_local_2 DEFINITION.
26 | PUBLIC SECTION.
27 | INTERFACES if_local_2.
28 | ENDCLASS.
29 |
30 | INTERFACE if_local_3. "#EC CONS_INTF
31 | " No finding expected due to pseudo comment
32 | CONSTANTS:
33 | co_1 TYPE symsgty VALUE 'E',
34 | co_2 TYPE symsgty VALUE 'W',
35 | co_3 TYPE symsgty VALUE 'N'.
36 | ENDINTERFACE.
37 |
38 | CLASS cl_local_3 DEFINITION.
39 | PUBLIC SECTION.
40 | INTERFACES if_local_3.
41 | ENDCLASS.
42 |
43 | INTERFACE if_local_4.
44 | " No finding expected due to method declaration
45 | CONSTANTS:
46 | co_1 TYPE symsgty VALUE 'E',
47 | co_2 TYPE symsgty VALUE 'W',
48 | co_3 TYPE symsgty VALUE 'N'.
49 | METHODS:
50 | a.
51 | ENDINTERFACE.
52 |
53 | INTERFACE if_local_5.
54 | " No finding expected since no constants are declared
55 | ENDINTERFACE.
56 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_avoid_test_seam.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_avoid_test_seam definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | protected section.
8 | private section.
9 | methods without_pseudo_comments.
10 | methods with_pseudo_comments.
11 | endclass.
12 |
13 |
14 |
15 | class /cc4a/test_avoid_test_seam implementation.
16 | method without_pseudo_comments.
17 | test-seam abc.
18 | data(a) = 1.
19 | end-test-seam.
20 |
21 | data b type standard table of i.
22 |
23 | loop at b assigning field-symbol().
24 | if < 2.
25 | test-seam hij.
26 | end-test-seam.
27 | endif.
28 | endloop.
29 |
30 | if 1 = 2.
31 | if 1 = 3.
32 | if 3 = 2.
33 | test-seam rtz.
34 | end-test-seam.
35 | endif.
36 | endif.
37 | endif.
38 | endmethod.
39 |
40 | method with_pseudo_comments.
41 | test-seam opl. "#EC TEST_SEAM_USAGE
42 | data(a) = 1.
43 | end-test-seam.
44 |
45 | data b type standard table of i.
46 |
47 | loop at b assigning field-symbol().
48 | if < 2.
49 | test-seam qwe. "#EC TEST_SEAM_USAGE
50 | end-test-seam.
51 | endif.
52 | endloop.
53 |
54 | if 1 = 2.
55 | if 1 = 3.
56 | if 3 = 2.
57 | test-seam tzu. "#EC TEST_SEAM_USAGE
58 | end-test-seam.
59 | endif.
60 | endif.
61 | endif.
62 | endmethod.
63 |
64 | endclass.
65 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_rap_unamanaged.bdef.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_RAP_UNAMANAGED
7 | BDEF/BDO
8 | Test RAP unmanaged
9 | 60
10 | EN
11 |
12 | -
13 | ./%2Fcc4a%2Ftest_rap_unamanaged/source/main/versions
14 | http://www.sap.com/adt/relations/versions
15 | Historic versions
16 |
17 | -
18 | ./%2Fcc4a%2Ftest_rap_unamanaged/source/main
19 | http://www.sap.com/adt/relations/source
20 | text/plain
21 | Source Content
22 |
23 | -
24 | ./%2Fcc4a%2Ftest_rap_unamanaged/source/main
25 | http://www.sap.com/adt/relations/source
26 | text/html
27 | Source Content (HTML)
28 |
29 |
30 | EN
31 | 5
32 | ./%2Fcc4a%2Ftest_rap_unamanaged/source/main
33 | ABAP_SOURCE
34 | true
35 | true
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#proper_bool_expression.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/PROPER_BOOL_EXPRESSION
7 | E
8 | Use proper boolean expression
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | BOL
19 | 'X', ' ', or SPACE can be replaced by ABAP_TRUE or ABAP_FALSE
20 | 122
21 |
22 | -
23 | I
24 | DES
25 | Standard boolean expressions
26 | 88
27 |
28 | -
29 | I
30 | INI
31 | IS (NOT) INITIAL can be replaced by comparison with ABAP_BOOL
32 | 122
33 |
34 | -
35 | I
36 | QCE
37 | Replace literal with ABAP_TRUE or ABAP_FALSE
38 | 66
39 |
40 | -
41 | I
42 | QIB
43 | Replace with comparison to ABAP_TRUE or ABAP_FALSE
44 | 62
45 |
46 | -
47 | I
48 | QIE
49 | Replace with call to XSDBOOL
50 | 40
51 |
52 | -
53 | I
54 | XSD
55 | IF...ENDIF block can be replaced by inline XSDBOOL( )
56 | 106
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/src/core/(cc4a)code_pal_remote.chkv.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "Remote CodePal checks",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "selectedChecks": [
9 | {
10 | "checkName": "/CC4A/PREFER_IS_NOT"
11 | },
12 | {
13 | "checkName": "/CC4A/ASSIGNMENT_CHAINING"
14 | },
15 | {
16 | "checkName": "/CC4A/AVOID_DB_ACCESS_IN_AUNIT"
17 | },
18 | {
19 | "checkName": "/CC4A/AVOID_TEST_SEAM"
20 | },
21 | {
22 | "checkName": "/CC4A/CHAIN_DECLARATIONS"
23 | },
24 | {
25 | "checkName": "/CC4A/CONSTANTS_INTERFACE"
26 | },
27 | {
28 | "checkName": "/CC4A/AVOID_SELF_REFERENCE"
29 | },
30 | {
31 | "checkName": "/CC4A/AVOID_DEFAULT_KEY"
32 | },
33 | {
34 | "checkName": "/CC4A/METHOD_SIGNATURE",
35 | "parameters": [
36 | {
37 | "name": "CheckPubMethodNoInterface",
38 | "value": "true"
39 | },
40 | {
41 | "name": "CheckInputParamBoolean",
42 | "value": "true"
43 | },
44 | {
45 | "name": "CheckInputParamOptional",
46 | "value": "true"
47 | },
48 | {
49 | "name": "CheckOutputParamNumber",
50 | "value": "true"
51 | },
52 | {
53 | "name": "CheckOutputParamType",
54 | "value": "true"
55 | },
56 | {
57 | "name": "CheckRetParamNotNamedResult",
58 | "value": "true"
59 | },
60 | {
61 | "name": "CheckExpParamNumberNotOne",
62 | "value": "true"
63 | }
64 | ]
65 | },
66 | {
67 | "checkName": "/CC4A/CHECK_IN_ITERATION"
68 | },
69 | {
70 | "checkName": "/CC4A/PROPER_BOOL_USAGE"
71 | },
72 | {
73 | "checkName": "/CC4A/MODERN"
74 | },
75 | {
76 | "checkName": "/CC4A/VARIABLE_SCOPE"
77 | }
78 | ]
79 | }
80 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_db.tabl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_DB
7 | E
8 | TRANSP
9 | X
10 | Database Table for testing checks
11 | E
12 | A
13 | 1
14 |
15 |
16 | /CC4A/TEST_DB
17 | A
18 | 0
19 | APPL0
20 | N
21 |
22 |
23 |
24 | USER_ID
25 | X
26 | 0
27 | C
28 | 000006
29 | X
30 | CLNT
31 | 000003
32 | CLNT
33 |
34 |
35 | FIRST_NAME
36 | 0
37 | g
38 | 000008
39 | SSTR
40 | 000030
41 | SSTR
42 |
43 |
44 | LAST_NAME
45 | 0
46 | g
47 | 000008
48 | SSTR
49 | 000030
50 | SSTR
51 |
52 |
53 | AGE
54 | 0
55 | X
56 | 000001
57 | INT1
58 | 000003
59 | INT1
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#method_signature.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/METHOD_SIGNATURE
7 | E
8 | Message Signature
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | DS1
19 | Findings regarding method signature.
20 | 132
21 |
22 | -
23 | I
24 | PC1
25 | Method with more than one output parameter type
26 | 132
27 |
28 | -
29 | I
30 | PC2
31 | Method with more than one output parameter
32 | 132
33 |
34 | -
35 | I
36 | PC3
37 | Method with importing parameter of type boolean
38 | 132
39 |
40 | -
41 | I
42 | PC4
43 | Method with optional importing parameter
44 | 132
45 |
46 | -
47 | I
48 | PC5
49 | Public instance method which is not part of an interface
50 | 132
51 |
52 | -
53 | I
54 | PC6
55 | Method with one exporting parameter
56 | 132
57 |
58 | -
59 | I
60 | PC7
61 | Returning Parameter of method not named RESULT
62 | 132
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/src/core/(cc4a)code_pal_full.chkv.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": "1",
3 | "header": {
4 | "description": "All CodePal checks",
5 | "originalLanguage": "en",
6 | "abapLanguageVersion": "cloudDevelopment"
7 | },
8 | "selectedChecks": [
9 | {
10 | "checkName": "/CC4A/PREFER_IS_NOT"
11 | },
12 | {
13 | "checkName": "/CC4A/ASSIGNMENT_CHAINING"
14 | },
15 | {
16 | "checkName": "/CC4A/AVOID_DB_ACCESS_IN_AUNIT"
17 | },
18 | {
19 | "checkName": "/CC4A/AVOID_TEST_SEAM"
20 | },
21 | {
22 | "checkName": "/CC4A/CHAIN_DECLARATIONS"
23 | },
24 | {
25 | "checkName": "/CC4A/CONSTANTS_INTERFACE"
26 | },
27 | {
28 | "checkName": "/CC4A/AVOID_SELF_REFERENCE"
29 | },
30 | {
31 | "checkName": "/CC4A/AVOID_DEFAULT_KEY"
32 | },
33 | {
34 | "checkName": "/CC4A/METHOD_SIGNATURE",
35 | "parameters": [
36 | {
37 | "name": "CheckPubMethodNoInterface",
38 | "value": "true"
39 | },
40 | {
41 | "name": "CheckInputParamBoolean",
42 | "value": "true"
43 | },
44 | {
45 | "name": "CheckInputParamOptional",
46 | "value": "true"
47 | },
48 | {
49 | "name": "CheckOutputParamNumber",
50 | "value": "true"
51 | },
52 | {
53 | "name": "CheckOutputParamType",
54 | "value": "true"
55 | },
56 | {
57 | "name": "CheckRetParamNotNamedResult",
58 | "value": "true"
59 | },
60 | {
61 | "name": "CheckExpParamNumberNotOne",
62 | "value": "true"
63 | }
64 | ]
65 | },
66 | {
67 | "checkName": "/CC4A/PREFER_METHODS"
68 | },
69 | {
70 | "checkName": "/CC4A/CHECK_IN_ITERATION"
71 | },
72 | {
73 | "checkName": "/CC4A/PROPER_BOOL_USAGE"
74 | },
75 | {
76 | "checkName": "/CC4A/MODERN"
77 | },
78 | {
79 | "checkName": "/CC4A/VARIABLE_SCOPE"
80 | }
81 | ]
82 | }
83 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#prefer_methods.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 | class test definition final for testing
2 | duration short
3 | risk level harmless.
4 |
5 | private section.
6 | constants test_class type c length 30 value '/CC4A/TEST_PREFER_METHODS'.
7 | constants form_finding_class type c length 30 value '/CC4A/SAPLTEST_PREFER_METHODS'.
8 | constants method_finding_class type c length 30 value '/CC4A/LTEST_PREFER_METHODS$01'.
9 | methods execute_test_class for testing raising cx_static_check.
10 | endclass.
11 |
12 | class test implementation.
13 | method execute_test_class.
14 |
15 | data(form_finding_1) = value if_ci_atc_check=>ty_location(
16 | object = value #( name = form_finding_class type = `PROG` )
17 | position = value #( line = 17 column = 0 ) ).
18 |
19 | data(methods_finding_1) = value if_ci_atc_check=>ty_location(
20 | object = value #( name = method_finding_class type = `PROG` )
21 | position = value #( line = 1 column = 0 ) ).
22 |
23 | data(form_finding_1_pseudo) = value if_ci_atc_check=>ty_location(
24 | object = value #( name = form_finding_class type = `PROG` )
25 | position = value #( line = 22 column = 0 ) ).
26 |
27 | cl_ci_atc_unit_driver=>create_asserter( )->check_and_assert(
28 | check = new /cc4a/prefer_methods( )
29 | object = value #( type = 'FUGR' name = test_class )
30 | expected_findings = value #(
31 | (
32 | location = form_finding_1
33 | code = /cc4a/prefer_methods=>finding_codes-avoid_form
34 | )
35 | (
36 | location = methods_finding_1
37 | code = /cc4a/prefer_methods=>finding_codes-prefer_methods
38 | )
39 | (
40 | location = form_finding_1_pseudo
41 | code = /cc4a/prefer_methods=>finding_codes-avoid_form
42 | )
43 | )
44 | asserter_config = value #( quickfixes = abap_false ) ).
45 | endmethod.
46 | endclass.
47 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_avoid_default_key.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_avoid_default_key definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | protected section.
8 | private section.
9 | class-methods static_findings.
10 | methods with_pseudo_comments.
11 | methods without_pseudo_comments.
12 |
13 | types:
14 | begin of ty_struct,
15 | comp1 type i,
16 | comp2 type string,
17 | end of ty_struct.
18 |
19 | class-data abc type table of ty_struct with default key.
20 | class-data def type table of ty_struct with empty key.
21 | class-data ghi type table of ty_struct with default key. "#EC DEFAULT_KEY
22 | ENDCLASS.
23 |
24 |
25 |
26 | CLASS /CC4A/TEST_AVOID_DEFAULT_KEY IMPLEMENTATION.
27 |
28 |
29 | method with_pseudo_comments.
30 | data mno type table of ty_struct with empty key.
31 | data pqr type table of ty_struct with empty key.
32 | data stu type table of ty_struct with default key. "#EC DEFAULT_KEY
33 |
34 | types: begin of type1,
35 | vwx type standard table of ty_struct with non-unique key comp2,
36 | yza type standard table of i with default key, "#EC DEFAULT_KEY
37 | bcd type standard table of string with empty key,
38 | end of type1.
39 |
40 | data with.
41 | types:
42 | begin of ty_malicious,
43 | with type i,
44 | default type i,
45 | key type i,
46 | end of ty_malicious.
47 | types ty_table type sorted table of ty_malicious with unique key !with default key.
48 | endmethod.
49 |
50 |
51 | method without_pseudo_comments.
52 | data mno type table of ty_struct with empty key.
53 | data pqr type table of ty_struct with empty key.
54 | data stu type table of ty_struct with default key.
55 |
56 | types: begin of type1,
57 | vwx type standard table of ty_struct with non-unique key comp2,
58 | yza type standard table of i with default key,
59 | bcd type standard table of string with empty key,
60 | end of type1.
61 | endmethod.
62 |
63 |
64 | method static_findings.
65 | statics memo type standard table of string with default key. "#EC DEFAULT_KEY
66 | statics mamo type standard table of string with default key.
67 | endmethod.
68 | ENDCLASS.
69 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#bp_test_rap_unamanaged.clas.locals_imp.abap:
--------------------------------------------------------------------------------
1 | class lhc_test_rap_unamanaged definition inheriting from cl_abap_behavior_handler.
2 | private section.
3 |
4 | methods get_instance_authorizations for instance authorization
5 | importing keys request requested_authorizations for /cc4a/test_rap_unamanaged result result.
6 |
7 | methods create for modify
8 | importing entities for create /cc4a/test_rap_unamanaged
9 | changing mapped type data
10 | failed type data
11 | reported type data.
12 |
13 | methods update for modify
14 | importing entities for update /cc4a/test_rap_unamanaged
15 | changing mapped type data
16 | failed type data
17 | reported type data.
18 |
19 | methods delete for modify
20 | importing keys for delete /cc4a/test_rap_unamanaged.
21 |
22 | methods read for read
23 | importing keys for read /cc4a/test_rap_unamanaged result result
24 | changing failed type data
25 | reported type data.
26 |
27 | methods lock for lock
28 | importing keys for lock /cc4a/test_rap_unamanaged
29 | changing failed type data
30 | reported type data.
31 |
32 | methods this_is_a_custom_method
33 | changing mapped type data
34 | failed type data
35 | reported type data.
36 |
37 | endclass.
38 |
39 | class lhc_test_rap_unamanaged implementation.
40 |
41 | method get_instance_authorizations.
42 | endmethod.
43 |
44 | method create.
45 | endmethod.
46 |
47 | method update.
48 | endmethod.
49 |
50 | method delete.
51 | endmethod.
52 |
53 | method read.
54 | endmethod.
55 |
56 | method lock.
57 | endmethod.
58 |
59 | method this_is_a_custom_method.
60 |
61 | endmethod.
62 |
63 | endclass.
64 |
65 | class lsc_test_rap_unamanaged definition inheriting from cl_abap_behavior_saver.
66 | protected section.
67 |
68 | methods finalize redefinition.
69 |
70 | methods check_before_save redefinition.
71 |
72 | methods save redefinition.
73 |
74 | methods cleanup redefinition.
75 |
76 | methods cleanup_finalize redefinition.
77 |
78 | endclass.
79 |
80 | class lsc_test_rap_unamanaged implementation.
81 |
82 | method finalize.
83 | endmethod.
84 |
85 | method check_before_save.
86 | endmethod.
87 |
88 | method save.
89 | endmethod.
90 |
91 | method cleanup.
92 | endmethod.
93 |
94 | method cleanup_finalize.
95 | endmethod.
96 |
97 | endclass.
98 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#scope_of_variable.clas.locals_imp.abap:
--------------------------------------------------------------------------------
1 | class block_finder implementation.
2 | method constructor.
3 | me->first_valid_block = first_valid_block.
4 | me->blocks = blocks.
5 | endmethod.
6 |
7 | method find_parent_branch.
8 | result-block = block.
9 | while result-block <> first_valid_block.
10 | data(current_block) = blocks[ result-block ].
11 | case current_block-type.
12 | when if_ci_atc_source_code_provider=>block_type-alternation
13 | or if_ci_atc_source_code_provider=>block_type-iteration
14 | or if_ci_atc_source_code_provider=>block_type-condition.
15 | return.
16 |
17 | when others.
18 | if current_block-statement_type = if_ci_atc_source_code_provider=>statement_type-inject.
19 | result-inside_injection = abap_true.
20 | endif.
21 | result-block = current_block-parent.
22 |
23 | endcase.
24 | endwhile.
25 | endmethod.
26 |
27 | method find_outer_block.
28 | if line_exists( blocks[ table_line = first_valid_block ] ).
29 | result = first_valid_block.
30 | return.
31 | endif.
32 | result = blocks[ 1 ].
33 | loop at blocks from 2 into data(block_no).
34 | result = least_common_parent( block_1 = result block_2 = block_no ).
35 | if result = first_valid_block.
36 | return.
37 | endif.
38 | endloop.
39 | if me->blocks[ result ]-type = if_ci_atc_source_code_provider=>block_type-sequence.
40 | result = me->blocks[ result ]-parent.
41 | endif.
42 | endmethod.
43 |
44 | method least_common_parent.
45 | if block_1 = first_valid_block or block_2 = first_valid_block.
46 | result = first_valid_block.
47 | elseif block_1 = block_2.
48 | result = block_1.
49 | elseif blocks[ block_1 ]-parent = blocks[ block_2 ]-parent.
50 | result = blocks[ block_1 ]-parent.
51 | else.
52 | if is_parent( parent = block_1 child = block_2 ) = abap_true.
53 | result = block_1.
54 | elseif is_parent( parent = block_2 child = block_1 ) = abap_true.
55 | result = block_2.
56 | else.
57 | result = least_common_parent( block_1 = value #( blocks[ block_1 ]-parent )
58 | block_2 = value #( blocks[ block_2 ]-parent ) ).
59 | endif.
60 | endif.
61 | endmethod.
62 |
63 | method is_parent.
64 | result = abap_false.
65 | if parent = first_valid_block.
66 | result = abap_true.
67 | else.
68 | data(p) = blocks[ child ]-parent.
69 | while p <> first_valid_block and p <> parent.
70 | p = blocks[ p ]-parent.
71 | endwhile.
72 | if p = parent.
73 | result = abap_true.
74 | endif.
75 | endif.
76 | endmethod.
77 | endclass.
78 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#avoid_test_seam.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/avoid_test_seam definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | interfaces if_ci_atc_check.
8 |
9 | constants:
10 | begin of finding_codes,
11 | test_seam type if_ci_atc_check=>ty_finding_code value 'TESTSEAMUS',
12 | end of finding_codes.
13 |
14 | methods constructor.
15 |
16 | protected section.
17 | private section.
18 | constants pseudo_comment type string value 'TEST_SEAM_USAGE'.
19 |
20 | data code_provider type ref to if_ci_atc_source_code_provider.
21 | data assistant_factory type ref to cl_ci_atc_assistant_factory.
22 | data meta_data type ref to /cc4a/if_check_meta_data.
23 |
24 | methods analyze_procedure
25 | importing procedure type if_ci_atc_source_code_provider=>ty_procedure
26 | returning value(findings) type if_ci_atc_check=>ty_findings.
27 | ENDCLASS.
28 |
29 |
30 |
31 | CLASS /CC4A/AVOID_TEST_SEAM IMPLEMENTATION.
32 |
33 |
34 | method analyze_procedure.
35 | loop at procedure-statements assigning field-symbol() where keyword eq 'TEST-SEAM' ##PRIMKEY[KEYWORD].
36 | insert value #( code = finding_codes-test_seam
37 | location = code_provider->get_statement_location( )
38 | checksum = code_provider->get_statement_checksum( )
39 | has_pseudo_comment = meta_data->has_valid_pseudo_comment(
40 | statement =
41 | finding_code = finding_codes-test_seam )
42 | ) into table findings.
43 | endloop.
44 | endmethod.
45 |
46 |
47 | method if_ci_atc_check~get_meta_data.
48 | meta_data = me->meta_data.
49 | endmethod.
50 |
51 | method constructor.
52 | meta_data = /cc4a/check_meta_data=>create(
53 | value #( checked_types = /cc4a/check_meta_data=>checked_types-abap_programs
54 | description = 'Usage of TEST-SEAM'(des)
55 | remote_enablement = /cc4a/check_meta_data=>remote_enablement-unconditional
56 | finding_codes = value #(
57 | ( code = finding_codes-test_seam pseudo_comment = pseudo_comment text = 'Usage of TEST-SEAM'(uot) ) ) ) ).
58 | endmethod.
59 |
60 |
61 | method if_ci_atc_check~run.
62 | code_provider = data_provider->get_code_provider( ).
63 | data(procedures) = code_provider->get_procedures( code_provider->object_to_comp_unit( object ) ).
64 | loop at procedures->* assigning field-symbol().
65 | insert lines of analyze_procedure( ) into table findings.
66 | endloop.
67 | endmethod.
68 |
69 |
70 | method if_ci_atc_check~set_assistant_factory.
71 | assistant_factory = factory.
72 | endmethod.
73 |
74 |
75 | method if_ci_atc_check~verify_prerequisites.
76 |
77 | endmethod.
78 | ENDCLASS.
79 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_avoid_self_ref.clas.locals_imp.abap:
--------------------------------------------------------------------------------
1 | *"* use this source file for the definition and implementation of
2 | *"* local helper classes, interface definitions and type
3 | *"* declarations
4 | class lz_self_reference definition
5 | create public .
6 |
7 | public section.
8 | data att1 type i.
9 | data att2 type string.
10 | data att3 type c.
11 | methods m1 importing att1 type i.
12 | methods m2 changing att3 type c.
13 | methods m3 returning value(att4) type string.
14 | protected section.
15 | data att5 type string.
16 | private section.
17 | data att4 type i.
18 | endclass.
19 |
20 |
21 |
22 | class lz_self_reference implementation.
23 | method m1.
24 |
25 | endmethod.
26 |
27 | method m2.
28 | data att2 type f.
29 | me->att2 = 'Hugo'.
30 | att2 = '1.2'.
31 | me->att3 = 'Hugo'.
32 | me->att4 = 7.
33 | endmethod.
34 |
35 | method m3.
36 | me->att4 = 5.
37 | me->att1 = 2.
38 | att4 = 'HUHU'.
39 | endmethod.
40 |
41 | endclass.
42 |
43 | class lz_self_reference2 definition inheriting from lz_self_reference.
44 | public section.
45 | methods m2 redefinition.
46 | methods m3 redefinition.
47 | private section.
48 | data att7 type c.
49 |
50 | endclass.
51 |
52 | class lz_self_reference2 implementation.
53 |
54 | method m2.
55 | data att2 type f.
56 | me->att2 = 'Hugo'.
57 | att2 = '1.2'.
58 | me->att3 = 'Hugo'.
59 | endmethod.
60 |
61 | method m3.
62 | data att7 type string.
63 | me->att5 = 5.
64 | me->att1 = 2.
65 | att4 = 'HUHU'.
66 |
67 | final(att8) = 5.
68 |
69 | endmethod.
70 |
71 | endclass.
72 |
73 | class impl_interface definition.
74 | public section.
75 | interfaces /cc4a/if_test_avoid_self_ref.
76 | private section.
77 | data var_1 type i.
78 | endclass.
79 |
80 | class impl_interface implementation.
81 |
82 | method /cc4a/if_test_avoid_self_ref~meth_1.
83 | me->var_1 = var_1.
84 | endmethod.
85 |
86 | endclass.
87 |
88 | class inheriting_from_global definition inheriting from /cc4a/test_avoid_self_ref_sup.
89 | public section.
90 | methods super_meth redefinition.
91 | private section.
92 | data imp type i.
93 | endclass.
94 |
95 | CLASS inheriting_from_global IMPLEMENTATION.
96 |
97 | METHOD super_meth.
98 | me->imp = imp.
99 | ENDMETHOD.
100 |
101 | ENDCLASS.
102 |
103 | interface local_interface.
104 | methods meth_1
105 | importing par_1 type i.
106 | methods meth_2.
107 | endinterface.
108 |
109 | class impl_local_interface definition.
110 | public section.
111 | interfaces local_interface.
112 | endclass.
113 |
114 | CLASS impl_local_interface IMPLEMENTATION.
115 |
116 | METHOD local_interface~meth_1.
117 |
118 | ENDMETHOD.
119 |
120 | METHOD local_interface~meth_2.
121 |
122 | ENDMETHOD.
123 |
124 | ENDCLASS.
125 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_rap.tabl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TEST_RAP
7 | E
8 | TRANSP
9 | X
10 | Database Table for Root Entity of RAP BO
11 | E
12 | X
13 | A
14 | 1
15 |
16 |
17 | /CC4A/TEST_RAP
18 | A
19 | 0
20 | APPL0
21 | N
22 | Q
23 |
24 |
25 |
26 | CLIENT
27 | X
28 | MANDT
29 | 0
30 | X
31 | E
32 |
33 |
34 | KEY_FIELD
35 | X
36 | 0
37 | X
38 | 000004
39 | X
40 | INT4
41 | 000010
42 | INT4
43 |
44 |
45 | DATA_FIELD
46 | 0
47 | g
48 | 000008
49 | STRG
50 | STRG
51 |
52 |
53 | CHAR_FIELD
54 | 0
55 | C
56 | 000050
57 | CHAR
58 | 000025
59 | CHAR
60 |
61 |
62 | CHAR_FIELD_2
63 | 0
64 | C
65 | 000050
66 | CHAR
67 | 000025
68 | CHAR
69 |
70 |
71 | DEC_FIELD
72 | 0
73 | P
74 | 000008
75 | DEC
76 | 000015
77 | 000002
78 | DEC
79 |
80 |
81 | CREA_DATE_TIME
82 | TIMESTAMPL
83 | 0
84 | E
85 |
86 |
87 | LCHG_DATE_TIME
88 | TIMESTAMPL
89 | 0
90 | E
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#check_constant_interface.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 | class ltcl_ definition final for testing
2 | duration short
3 | risk level harmless.
4 |
5 | private section.
6 | constants:
7 | begin of co_test_object,
8 | object_type_1 type if_ci_atc_check=>ty_object-type value 'CLAS',
9 | object_name_1 type if_ci_atc_check=>ty_object-name value '/CC4A/TEST_CHECK_CONSTANT_IF1',
10 | object_type_2 type if_ci_atc_check=>ty_object-type value 'INTF',
11 | object_name_2 type if_ci_atc_check=>ty_object-name value '/CC4A/TEST_CHECK_CONSTANT_IF2',
12 | end of co_test_object.
13 |
14 | methods:
15 | run_test_local_intf for testing raising cx_static_check,
16 | run_test_global_intf for testing raising cx_static_check.
17 |
18 | endclass.
19 |
20 |
21 | class ltcl_ implementation.
22 |
23 | method run_test_global_intf.
24 |
25 | " Location of expected findings
26 | data(finding_1_loc) = value if_ci_atc_check=>ty_location(
27 | object = value #( name = '/CC4A/TEST_CHECK_CONSTANT_IF2=IU' type = 'PROG' )
28 | position = value #( line = 1 column = 0 ) ).
29 |
30 | cl_ci_atc_unit_driver=>create_asserter( )->check_and_assert(
31 | check = new /cc4a/check_constant_interface( )
32 | object = value #( name = co_test_object-object_name_2
33 | type = co_test_object-object_type_2 )
34 | asserter_config = value #( quickfixes = abap_false
35 | remove_findings_with_pcoms = abap_true )
36 | expected_findings = value #( ( code = /cc4a/check_constant_interface=>finding_codes-cons_intf
37 | location = finding_1_loc ) ) ).
38 |
39 | endmethod.
40 |
41 |
42 | method run_test_local_intf.
43 |
44 | " Location of expected findings
45 | data(finding_1_loc) = value if_ci_atc_check=>ty_location(
46 | object = value #( name = '/CC4A/TEST_CHECK_CONSTANT_IF1=CCIMP' type = 'PROG' )
47 | position = value #( line = 4 column = 0 ) ).
48 | data(finding_2_loc) = value if_ci_atc_check=>ty_location(
49 | object = value #( name = '/CC4A/TEST_CHECK_CONSTANT_IF1=CCIMP' type = 'PROG' )
50 | position = value #( line = 17 column = 0 ) ).
51 | " Finding 3 should not appear due to the pseudo comment
52 |
53 | cl_ci_atc_unit_driver=>create_asserter( )->check_and_assert(
54 | check = new /cc4a/check_constant_interface( )
55 | object = value #( name = co_test_object-object_name_1
56 | type = co_test_object-object_type_1 )
57 | asserter_config = value #( quickfixes = abap_false
58 | remove_findings_with_pcoms = abap_true )
59 | expected_findings = value #( ( code = /cc4a/check_constant_interface=>finding_codes-cons_intf
60 | location = finding_1_loc )
61 | ( code = /cc4a/check_constant_interface=>finding_codes-cons_intf
62 | location = finding_2_loc ) ) ).
63 |
64 | endmethod.
65 |
66 | endclass.
67 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_check_in_iteration.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_check_in_iteration definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | protected section.
8 | private section.
9 | methods without_pseudo_comments.
10 | methods with_pseudo_comments.
11 |
12 | types: begin of ty_table,
13 | delflag type abap_bool,
14 | end of ty_table.
15 |
16 | data itab_range type range of ty_table.
17 | ENDCLASS.
18 |
19 |
20 |
21 | CLASS /CC4A/TEST_CHECK_IN_ITERATION IMPLEMENTATION.
22 |
23 |
24 | method without_pseudo_comments.
25 | " Checks with do
26 | do 10 times.
27 | check 1 = 1.
28 | enddo.
29 |
30 | data(a) = 125.
31 | data(b) = 250.
32 |
33 | do 10 times.
34 | if abap_true = abap_true.
35 | if 1 = 3.
36 | check a = b.
37 | else.
38 | check b = 3.
39 | endif.
40 | endif.
41 | enddo.
42 |
43 | " Checks with while
44 | data(x) = 5.
45 | data(y) = 15.
46 |
47 | while abap_true = abap_false.
48 | check x = y.
49 |
50 | if 3 = 3.
51 | check x <> 150.
52 | endif.
53 | endwhile.
54 |
55 | " Check with loop
56 | types: begin of ty_table,
57 | delflag type abap_bool,
58 | end of ty_table.
59 |
60 | data itab type table of ty_table with empty key.
61 | loop at itab assigning field-symbol().
62 | check -delflag = abap_true.
63 | if a = x.
64 | check -delflag <= abap_false.
65 | endif.
66 | endloop.
67 |
68 | " Checks that shouldn't show quickfixes
69 | check a = a.
70 |
71 | if a = 3.
72 | check b = a.
73 | endif.
74 |
75 | " Some special cases
76 |
77 | loop at itab into data(tab).
78 | check abap_false = tab-delflag.
79 | endloop.
80 |
81 | loop at itab assigning .
82 | check -delflag = abap_true.
83 | check xsdbool( 1 > 3 ) = abap_true.
84 | endloop.
85 |
86 |
87 | loop at itab assigning .
88 | check in itab_range.
89 | endloop.
90 |
91 | endmethod.
92 |
93 |
94 | method with_pseudo_comments.
95 |
96 | data(a) = 55.
97 |
98 | if 3 = 2.
99 | while 3 = a * 2.
100 | check a = a. "#EC CHECK_IN_ITERATION
101 | endwhile.
102 | endif.
103 |
104 | do a times.
105 | if a = 3.
106 | check 55 = a. "#EC CHECK_IN_ITERATION
107 | endif.
108 | enddo.
109 |
110 | types: begin of ty_table,
111 | delflag type string,
112 | end of ty_table.
113 |
114 | data itab type table of ty_table with empty key.
115 | while a = 1.
116 | do a times.
117 | loop at itab assigning field-symbol().
118 | check -delflag = abap_true. "#EC CHECK_IN_ITERATION
119 | if a = a / 2.
120 | check -delflag = abap_false. "#EC CHECK_IN_ITERATION
121 | endif.
122 | endloop.
123 | enddo.
124 | endwhile.
125 | endmethod.
126 | ENDCLASS.
127 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#avoid_test_seam.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 | class test definition final for testing
2 | duration short
3 | risk level harmless.
4 |
5 | private section.
6 | constants test_class type c length 30 value '/CC4A/TEST_AVOID_TEST_SEAM'.
7 | constants:
8 | begin of test_class_methods,
9 | without_pseudo_comments type c length 30 value 'WITHOUT_PSEUDO_COMMENTS',
10 | with_pseudo_comments type c length 30 value 'WITH_PSEUDO_COMMENTS',
11 | end of test_class_methods.
12 |
13 | methods execute_test_class for testing raising cx_static_check.
14 | endclass.
15 |
16 | class test implementation.
17 | method execute_test_class.
18 |
19 | data(without_pseudo_comment_1) = value if_ci_atc_check=>ty_location(
20 | object = cl_ci_atc_unit_driver=>get_method_object(
21 | value #( class = test_class method = test_class_methods-without_pseudo_comments ) )
22 | position = value #( line = 2 column = 4 ) ).
23 | data(without_pseudo_comment_2) = value if_ci_atc_check=>ty_location(
24 | object = cl_ci_atc_unit_driver=>get_method_object(
25 | value #( class = test_class method = test_class_methods-without_pseudo_comments ) )
26 | position = value #( line = 10 column = 8 ) ).
27 | data(without_pseudo_comment_3) = value if_ci_atc_check=>ty_location(
28 | object = cl_ci_atc_unit_driver=>get_method_object(
29 | value #( class = test_class method = test_class_methods-without_pseudo_comments ) )
30 | position = value #( line = 18 column = 10 ) ).
31 |
32 | data(with_pseudo_comment_1) = value if_ci_atc_check=>ty_location(
33 | object = cl_ci_atc_unit_driver=>get_method_object(
34 | value #( class = test_class method = test_class_methods-with_pseudo_comments ) )
35 | position = value #( line = 2 column = 4 ) ).
36 | data(with_pseudo_comment_2) = value if_ci_atc_check=>ty_location(
37 | object = cl_ci_atc_unit_driver=>get_method_object(
38 | value #( class = test_class method = test_class_methods-with_pseudo_comments ) )
39 | position = value #( line = 10 column = 8 ) ).
40 | data(with_pseudo_comment_3) = value if_ci_atc_check=>ty_location(
41 | object = cl_ci_atc_unit_driver=>get_method_object(
42 | value #( class = test_class method = test_class_methods-with_pseudo_comments ) )
43 | position = value #( line = 18 column = 10 ) ).
44 |
45 | cl_ci_atc_unit_driver=>create_asserter( )->check_and_assert(
46 | check = new /cc4a/avoid_test_seam( )
47 | object = value #( type = 'CLASS' name = test_class )
48 | expected_findings = value #( code = /cc4a/avoid_test_seam=>finding_codes-test_seam
49 | ( location = without_pseudo_comment_1 )
50 | ( location = without_pseudo_comment_2 )
51 | ( location = without_pseudo_comment_3 )
52 | ( location = with_pseudo_comment_1 )
53 | ( location = with_pseudo_comment_2 )
54 | ( location = with_pseudo_comment_3 ) )
55 | asserter_config = value #( quickfixes = abap_false ) ).
56 | endmethod.
57 |
58 | endclass.
59 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#modern_language.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/MODERN_LANGUAGE
7 | E
8 | check for modern language
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 | -
17 | I
18 | 001
19 | MOVE is obsolete
20 | 26
21 |
22 | -
23 | I
24 | 002
25 | TRANSLATE TO UPPER/LOWERCASE is obsolete
26 | 80
27 |
28 | -
29 | I
30 | 003
31 | Prefer LINE_EXISTS/LINE_INDEX
32 | 50
33 |
34 | -
35 | I
36 | 004
37 | Prefer NEW instead of CREATE OBJECT
38 | 70
39 |
40 | -
41 | I
42 | 005
43 | Prefer functional call instead of CALL METHOD
44 | 90
45 |
46 | -
47 | I
48 | 006
49 | Omit EXPORTING in functional Method Call if possible
50 | 104
51 |
52 | -
53 | I
54 | 007
55 | Do not use RECEIVING in functional Method Call if possible
56 | 116
57 |
58 | -
59 | I
60 | 008
61 | Use string templates instead of &&
62 | 68
63 |
64 | -
65 | I
66 | DES
67 | Modern Language
68 | 25
69 |
70 | -
71 | I
72 | QF1
73 | Replace MOVE statement
74 | 44
75 |
76 | -
77 | I
78 | QF2
79 | Replace TRANSLATE statement
80 | 54
81 |
82 | -
83 | I
84 | QF3
85 | Use LINE_EXISTS/LINE_INDEX
86 | 52
87 |
88 | -
89 | I
90 | QF4
91 | Use NEW instead of CREATE OBJECT
92 | 64
93 |
94 | -
95 | I
96 | QF5
97 | Use functional call instead of CALL METHOD
98 | 84
99 |
100 | -
101 | I
102 | QF6
103 | Omit EXPORTING
104 | 24
105 |
106 | -
107 | I
108 | QF7
109 | Do not use EXPORTING/RECEIVING
110 | 60
111 |
112 | -
113 | I
114 | QF8
115 | Replace && by string templates
116 | 60
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_modern_language.clas.locals_imp.abap:
--------------------------------------------------------------------------------
1 | CLASS lcx_error DEFINITION FINAL
2 | INHERITING FROM cx_static_check.
3 | ENDCLASS.
4 |
5 | CLASS lcx_error IMPLEMENTATION.
6 | ENDCLASS.
7 |
8 | CLASS lcl_test DEFINITION FINAL.
9 | PUBLIC SECTION.
10 | METHODS constructor
11 | IMPORTING param1 TYPE i
12 | param2 TYPE i ##NEEDED.
13 | METHODS test1
14 | IMPORTING param1 TYPE i
15 | RETURNING VALUE(result) TYPE i.
16 | METHODS test2
17 | IMPORTING param1 TYPE string
18 | EXPORTING param2 TYPE string
19 | CHANGING param3 TYPE string.
20 | METHODS test3
21 | IMPORTING param1 TYPE i
22 | RETURNING VALUE(result) TYPE i
23 | EXCEPTIONS error1 error2 ##NEEDED.
24 | METHODS test4
25 | IMPORTING param1 TYPE i
26 | param2 TYPE i
27 | param3 TYPE i
28 | EXPORTING param4 TYPE i.
29 | METHODS test5
30 | IMPORTING param1 TYPE string
31 | param2 TYPE string
32 | RETURNING VALUE(result) TYPE string.
33 | methods test6
34 | importing param type string
35 | returning value(result) type string.
36 | METHODS test7
37 | IMPORTING param1 TYPE i
38 | EXPORTING param2 TYPE i
39 | RETURNING VALUE(result) TYPE i.
40 | ENDCLASS.
41 |
42 | CLASS lcl_test IMPLEMENTATION.
43 | METHOD test1.
44 | result = param1.
45 | ENDMETHOD.
46 | METHOD test2.
47 | param2 = |{ param1 }{ param3 }|.
48 | CLEAR param3.
49 | ENDMETHOD.
50 | METHOD test3.
51 | IF param1 > 10.
52 | RAISE error1.
53 | ENDIF.
54 | result = param1 + 5.
55 | IF result < 0.
56 | RAISE error2.
57 | ENDIF.
58 | ENDMETHOD.
59 | METHOD test4.
60 | param4 = param1 + param2 + param3.
61 | ENDMETHOD.
62 | METHOD test5.
63 | result = |{ param1 } { param2 }|.
64 | ENDMETHOD.
65 | METHOD test6.
66 | result = |{ param } end|.
67 | ENDMETHOD.
68 | METHOD test7.
69 | result = param1 + 3.
70 | param2 = param1 + 5.
71 | ENDMETHOD.
72 | METHOD constructor ##NEEDED.
73 | ENDMETHOD.
74 | ENDCLASS.
75 |
76 | CLASS lcl_test1 DEFINITION FINAL.
77 | PUBLIC SECTION.
78 | METHODS constructor
79 | IMPORTING param1 TYPE i
80 | RAISING lcx_error.
81 | ENDCLASS.
82 | CLASS lcl_test1 IMPLEMENTATION.
83 | METHOD constructor.
84 | IF param1 <= 0.
85 | RAISE EXCEPTION TYPE lcx_error.
86 | ENDIF.
87 | ENDMETHOD.
88 | ENDCLASS.
89 |
90 |
91 | CLASS lcl_test2 DEFINITION FINAL.
92 | PUBLIC SECTION.
93 | METHODS constructor
94 | IMPORTING param1 TYPE i
95 | EXCEPTIONS error.
96 | ENDCLASS.
97 | CLASS lcl_test2 IMPLEMENTATION.
98 | METHOD constructor.
99 | IF param1 <= 0.
100 | RAISE error.
101 | ENDIF.
102 | ENDMETHOD.
103 | ENDCLASS.
104 |
105 | CLASS lcl_test3 DEFINITION FINAL.
106 | PUBLIC SECTION.
107 | METHODS constructor
108 | IMPORTING param1 TYPE string
109 | param2 TYPE string ##NEEDED.
110 | ENDCLASS.
111 | CLASS lcl_test3 IMPLEMENTATION.
112 | METHOD constructor ##NEEDED.
113 | ENDMETHOD.
114 | ENDCLASS.
115 |
116 | CLASS lcl_test_selfish DEFINITION FINAL.
117 | PUBLIC SECTION.
118 | METHODS constructor
119 | IMPORTING val TYPE i ##NEEDED.
120 | DATA my_val TYPE i.
121 | ENDCLASS.
122 |
123 | CLASS lcl_test_selfish IMPLEMENTATION.
124 | METHOD constructor ##NEEDED.
125 | ENDMETHOD.
126 | ENDCLASS.
127 |
128 | CLASS lcl_test4 DEFINITION FINAL.
129 | PUBLIC SECTION.
130 | METHODS test
131 | IMPORTING param TYPE abap_bool ##NEEDED.
132 | ENDCLASS.
133 |
134 | CLASS lcl_test4 IMPLEMENTATION.
135 | METHOD test ##NEEDED.
136 | ENDMETHOD.
137 | ENDCLASS.
138 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#prefer_methods.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/prefer_methods definition
2 | public
3 | final
4 | create public .
5 | public section.
6 | interfaces if_ci_atc_check.
7 |
8 | constants:
9 | begin of pseudo_comment,
10 | avoid_form type string value 'CI_FORM',
11 | end of pseudo_comment.
12 |
13 | constants:
14 | begin of finding_codes,
15 | avoid_form type if_ci_atc_check=>ty_finding_code value 'C_FORM',
16 | prefer_methods type if_ci_atc_check=>ty_finding_code value 'C_METHODS',
17 | end of finding_codes.
18 |
19 | methods constructor.
20 | protected section.
21 | private section.
22 | data code_provider type ref to if_ci_atc_source_code_provider.
23 | data assistant_factory type ref to cl_ci_atc_assistant_factory.
24 | data meta_data type ref to /cc4a/if_check_meta_data.
25 |
26 | methods analyze_procedure
27 | importing procedure type if_ci_atc_source_code_provider=>ty_procedure
28 | returning value(findings) type if_ci_atc_check=>ty_findings.
29 |
30 | methods function_is_rfc_enabled
31 | importing function_module type ref to if_xco_function_module
32 | returning value(is_rfc_enabled) type abap_bool.
33 |
34 | endclass.
35 |
36 | class /cc4a/prefer_methods implementation.
37 |
38 | method function_is_rfc_enabled.
39 | data(rfc_contract) = function_module->content( )->get_rfc_interface_contract( ).
40 | is_rfc_enabled = xsdbool( rfc_contract is not initial ).
41 | endmethod.
42 |
43 | method analyze_procedure.
44 | loop at procedure-statements assigning field-symbol() where keyword = `FORM` or keyword = `FUNCTION`.
45 | case -keyword.
46 | when `FUNCTION`.
47 | data(finding_code) = finding_codes-prefer_methods.
48 | data(function_module) = xco_cp_abap=>function_module( iv_name = |{ -tokens[ 2 ]-lexeme }| ).
49 | if function_is_rfc_enabled( function_module = function_module ).
50 | continue.
51 | endif.
52 | when `FORM`.
53 | finding_code = finding_codes-avoid_form.
54 | data(findings_pseudo_comment) = pseudo_comment-avoid_form.
55 | endcase.
56 | insert value #( code = finding_code
57 | location = code_provider->get_statement_location( )
58 | checksum = code_provider->get_statement_checksum( )
59 | has_pseudo_comment = meta_data->has_valid_pseudo_comment( statement = finding_code = finding_code )
60 | parameters = value #( param_1 = -tokens[ 2 ]-lexeme )
61 | ) into table findings.
62 | endloop.
63 | endmethod.
64 |
65 | method if_ci_atc_check~run.
66 | code_provider = data_provider->get_code_provider( ).
67 | data(procedures) = code_provider->get_procedures( code_provider->object_to_comp_unit( object ) ).
68 | loop at procedures->* assigning field-symbol().
69 | insert lines of analyze_procedure( ) into table findings.
70 | endloop.
71 | endmethod.
72 |
73 | method constructor.
74 | meta_data = /cc4a/check_meta_data=>create(
75 | value #( checked_types = /cc4a/check_meta_data=>checked_types-abap_programs
76 | description = 'Prefer methods over other procedures'(des)
77 | remote_enablement = /cc4a/check_meta_data=>remote_enablement-no
78 | finding_codes = value #(
79 | ( code = finding_codes-avoid_form pseudo_comment = pseudo_comment-avoid_form text = 'Definition of FORM routine &1'(ufr) )
80 | ( code = finding_codes-prefer_methods text = 'Definition of function module &1'(prm) ) )
81 | quickfix_codes = value #( ) ) ).
82 | endmethod.
83 |
84 | method if_ci_atc_check~get_meta_data.
85 | meta_data = me->meta_data.
86 | endmethod.
87 |
88 | method if_ci_atc_check~set_assistant_factory.
89 | assistant_factory = factory.
90 | endmethod.
91 |
92 | method if_ci_atc_check~verify_prerequisites.
93 |
94 | endmethod.
95 |
96 | endclass.
97 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Code Pal for ABAP - Cloud Edition
2 |
3 | [](https://api.reuse.software/info/github.com/SAP/code-pal-for-abap-cloud)
4 |
5 | ## About this Project
6 |
7 | Code Pal is a project that provides ATC checks to assist ABAP programmers in adhering to the [Clean ABAP style guide](https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md). This is a version of that project that provides ATC checks that can be executed in an ABAP Cloud (["Steampunk"](https://blogs.sap.com/2019/08/20/its-steampunk-now/)) environment. The legacy version for SAP_BASIS releases starting at 7.40 is [here](https://github.com/SAP/code-pal-for-abap).
8 |
9 |
10 | ## Requirements and Setup
11 |
12 | Install via [abapGit Eclipse plugin](https://github.com/abapGit/ADT_Frontend) on ABAP cloud systems and [abapGit for SAPGUI](https://docs.abapgit.org/guide-online-install.html) on systems with SAP_BASIS 7.58 or higher. Since Code Pal is developed in English, logon language EN is required during installation. In a Steampunk system, the abapGit plugin may report errors related to the object types NSPC and SCO2. These are caused by differences between the on Premise and cloud ABAP environments and can be ignored as these object types are only relevant when the project is imported into an on Premise environment.
13 |
14 | It's recommended to install the project into a package named `/CC4A/CODE_PAL`. You can choose the superpackage of this package arbitrarily, e.g. the default root package `ZLOCAL` for custom development. The namespace `/CC4A/` comes pre-installed in all Steampunk systems. It is currently unavailable in S/4 Public Cloud systems, but SAP is working on enabling it there, too.
15 |
16 | Compatibility of the most recent version is only guaranteed for the current version of ABAP for Cloud Development. For the SAP_BASIS 7.58-compatible version, use the `SAP_BASIS-7.58-compatible` branch.
17 |
18 | ## Features
19 |
20 | Our main functional goals that differ from the legacy version are:
21 |
22 | - Providing automated quick fixes for many findings in ADT
23 | - Enabling all checks to run in a [remote check scenario](https://blogs.sap.com/2016/12/12/remote-code-analysis-in-atc-one-central-check-system-for-multiple-systems-on-various-releases/).
24 | - All code lives in the `/CC4A/` (Clean Code for ABAP) namespace so collisions with Y*/Z* objects from other projects are avoided. You can get namespace keys at [SAP for Me]( https://me.sap.com/namespace/opensource) to use that namespace in an on Premise customer ABAP enviroment.
25 |
26 | The project contains an ABAP Test Cockpit variant called `/CC4A/CODE_PAL_FULL` that includes all currently available checks. For general information on how to use the ABAP Test Cockpit, see [the official SAP documentation](https://help.sap.com/docs/ABAP_PLATFORM_NEW/ba879a6e2ea04d9bb94c7ccd7cdac446/145568d2a3434ef5bf8352c74853c5eb.html?locale=en-US).
27 |
28 | The [check migration list](check_migration_list.md) shows the current migration status of checks from the legacy version. Use that list to navigate to the documentation of the checks.
29 |
30 | ## Feedback and Support
31 |
32 | Please submit feedback and bug reports as a [GitHub issue](https://github.com/SAP/code-pal-for-abap-cloud/issues) on this project.
33 |
34 | ## Contributing
35 |
36 | We welcome all contributions to this project, no matter whether you fixed a typo, repaired a bug or wrote a new check. See our [contributor guide](CONTRIBUTING.md) for details.
37 |
38 | ## Code of Conduct
39 |
40 | We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone. By participating in this project, you agree to abide by its [Code of Conduct](CODE_OF_CONDUCT.md) at all times.
41 |
42 | ## Licensing
43 |
44 | Copyright 2022 SAP SE or an SAP affiliate company and Code Pal for ABAP Cloud contributors. Please see our [license](LICENSES/Apache-2.0.txt) for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available [via the REUSE tool](https://api.reuse.software/info/github.com/SAP/code-pal-for-abap-cloud).
45 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#check_constant_interface.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/check_constant_interface definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | interfaces if_ci_atc_check.
8 |
9 | constants:
10 | begin of finding_codes,
11 | cons_intf type if_ci_atc_check=>ty_finding_code value 'CONS_INTF',
12 | end of finding_codes.
13 | constants:
14 | begin of pseudo_comments,
15 | cons_intf type string value 'CONS_INTF',
16 | end of pseudo_comments.
17 | methods constructor.
18 |
19 | protected section.
20 | private section.
21 | data code_provider type ref to if_ci_atc_source_code_provider.
22 | data meta_data type ref to /cc4a/if_check_meta_data.
23 | ENDCLASS.
24 |
25 |
26 |
27 | CLASS /CC4A/CHECK_CONSTANT_INTERFACE IMPLEMENTATION.
28 |
29 |
30 | method if_ci_atc_check~get_meta_data.
31 | meta_data = me->meta_data.
32 | endmethod.
33 |
34 | method constructor.
35 | meta_data = /cc4a/check_meta_data=>create( value #(
36 | checked_types = /cc4a/check_meta_data=>checked_types-abap_programs
37 | description = 'Constants in Interfaces'(des)
38 | finding_codes = value #(
39 | ( code = finding_codes-cons_intf
40 | pseudo_comment = pseudo_comments-cons_intf
41 | text = 'Interface contains only constants'(mc1) ) )
42 | remote_enablement = /cc4a/check_meta_data=>remote_enablement-unconditional ) ).
43 | endmethod.
44 |
45 | method if_ci_atc_check~run.
46 | code_provider = data_provider->get_code_provider( ).
47 | data(procedures) = code_provider->get_procedures( code_provider->object_to_comp_unit( object = object ) ).
48 |
49 | loop at procedures->* assigning field-symbol().
50 |
51 | data(has_something_else) = abap_false.
52 | data(if_definition) = abap_false.
53 |
54 | loop at -statements assigning field-symbol().
55 | case -keyword.
56 | when 'INTERFACE'.
57 | if lines( -tokens ) >= 3.
58 | " Ignore interface load and deferred statements, we are only interested in interface definitions
59 | check -tokens[ 3 ]-lexeme <> 'LOAD' and -tokens[ 3 ]-lexeme <> 'DEFERRED'.
60 | endif.
61 | if_definition = abap_true.
62 | data(at_least_one_constant) = abap_false.
63 | data(intf_decl_statement) = .
64 | continue.
65 |
66 | when 'ENDINTERFACE'.
67 | if has_something_else = abap_false and at_least_one_constant = abap_true.
68 | insert value #(
69 | code = finding_codes-cons_intf
70 | location = code_provider->get_statement_location( intf_decl_statement )
71 | checksum = code_provider->get_statement_checksum( intf_decl_statement )
72 | has_pseudo_comment = meta_data->has_valid_pseudo_comment(
73 | statement = intf_decl_statement
74 | finding_code = finding_codes-cons_intf )
75 | ) into table findings.
76 | else.
77 | has_something_else = abap_false.
78 | endif.
79 | if_definition = abap_false.
80 | continue.
81 | endcase.
82 |
83 | if if_definition = abap_true.
84 | " Only interfaces with at least one constant should be reported, we don't want to report empty interfaces
85 | if at_least_one_constant = abap_false and -tokens[ 1 ]-lexeme = 'CONSTANTS'.
86 | at_least_one_constant = abap_true.
87 | endif.
88 | " Check if there is anything else except constants
89 | if has_something_else = abap_false and -tokens[ 1 ]-lexeme <> 'CONSTANTS'.
90 | has_something_else = abap_true.
91 | endif.
92 | endif.
93 |
94 | endloop.
95 |
96 | endloop.
97 | endmethod.
98 |
99 |
100 | method if_ci_atc_check~set_assistant_factory.
101 |
102 | endmethod.
103 |
104 |
105 | method if_ci_atc_check~verify_prerequisites.
106 |
107 | endmethod.
108 | ENDCLASS.
109 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_avoid_self_ref.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_avoid_self_ref definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | protected section.
8 | private section.
9 | class-data string1 type string.
10 | class-data string2 type string.
11 | data number1 type i.
12 | data number2 type i.
13 |
14 | types:
15 | begin of ty_struct,
16 | comp type i,
17 | end of ty_struct.
18 |
19 | data struct type ty_struct.
20 |
21 | constants number3 type i value 0.
22 | constants string3 type string value 'abc'.
23 |
24 | methods without_pseudo_comments
25 | importing number type i
26 | string type string.
27 |
28 | methods with_pseudo_comments
29 | importing number type i
30 | string type string.
31 |
32 | methods importing_parameter
33 | importing number4 type i
34 | number5 type i
35 | string4 type string
36 | returning value(string5) type string.
37 |
38 | methods exporting_parameter
39 | exporting number4 type i
40 | string4 type string
41 | returning value(string5) type string.
42 | ENDCLASS.
43 |
44 |
45 |
46 | CLASS /CC4A/TEST_AVOID_SELF_REF IMPLEMENTATION.
47 |
48 |
49 | method exporting_parameter.
50 | data(string) = me->string1.
51 | final(second_string) = me->string2.
52 | final(string3) = me->string3.
53 | data(number1) = me->number1.
54 | data(struct) = me->struct-comp.
55 | struct = me->struct-comp.
56 | endmethod.
57 |
58 |
59 | method importing_parameter.
60 | data(string1) = me->string1.
61 | final(string) = me->string2.
62 | final(string3) = me->string3.
63 | data(number) = me->number1.
64 | data(structure) = me->struct-comp.
65 | structure = me->struct-comp.
66 | structure = struct-comp.
67 | assign me->(string4) to field-symbol().
68 | assign me->(string5) to field-symbol().
69 | endmethod.
70 |
71 |
72 | method without_pseudo_comments.
73 | data number1 type i.
74 | data number4 type i.
75 | data number5 type i.
76 |
77 | data string1 type string.
78 | data string4 type string.
79 | data string5 type string.
80 |
81 | number1 = me->number1 + me->number1.
82 | number1 = me->number1 + me->number2.
83 | number5 = me->number2 + me->number3.
84 | me->number2 = number4 + number5..
85 |
86 | string1 = me->string1 + me->string1.
87 | string1 = me->string1 + me->string2.
88 | string5 = me->string2 + me->string3.
89 | me->string2 = string4 + string5.
90 |
91 | me->without_pseudo_comments( number = me->number3 string = me->string3 ).
92 | me->with_pseudo_comments( number = me->number1 string = me->string3 ).
93 | me->with_pseudo_comments( number = number4 string = string4 ).
94 | me->with_pseudo_comments( number = number2 string = string5 ).
95 | endmethod.
96 |
97 |
98 | method with_pseudo_comments.
99 | data number1 type i.
100 | data number4 type i.
101 | data number5 type i.
102 |
103 | data string1 type string.
104 | data string4 type string.
105 | data string5 type string.
106 |
107 | number1 = me->number1 + me->number1.
108 | number1 = me->number1 + me->number2. "#EC SELF_REF
109 | number5 = me->number2 + me->number3. "#EC SELF_REF
110 | me->number2 = number4 + number5. "#EC SELF_REF
111 |
112 | string1 = me->string1 + me->string1.
113 | string1 = me->string1 + me->string2. "#EC SELF_REF
114 | string5 = me->string2 + me->string3. "#EC SELF_REF
115 | me->string2 = string4 + string5. "#EC SELF_REF
116 |
117 | me->without_pseudo_comments( number = me->number3 string = me->string3 ). "#EC SELF_REF
118 | me->with_pseudo_comments( number = me->number1 string = me->string3 ). "#EC SELF_RE
119 | me->with_pseudo_comments( number = number4 string = string4 ). "#EC SELF_REF
120 | me->with_pseudo_comments( number = number2 string = string5 ). "#EC SELF_REF
121 |
122 | endmethod.
123 | ENDCLASS.
124 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#equals_sign_chaining.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 | class ltcl_test definition final for testing
2 | duration short
3 | risk level harmless
4 | friends /cc4a/equals_sign_chaining.
5 |
6 | private section.
7 | constants:
8 | begin of co_test_object,
9 | object_type type if_ci_atc_check=>ty_object-type value 'CLAS',
10 | object_name type if_ci_atc_check=>ty_object-name value '/CC4A/TEST_EQUAL_SIGN_CHAINING',
11 | end of co_test_object.
12 | constants:
13 | begin of co_test_method_name,
14 | finding_1 type cl_ci_atc_unit_driver=>ty_method_name value 'FINDING_1',
15 | finding_2 type cl_ci_atc_unit_driver=>ty_method_name value 'FINDING_2',
16 | finding_3 type cl_ci_atc_unit_driver=>ty_method_name value 'FINDING_3',
17 | finding_4 type cl_ci_atc_unit_driver=>ty_method_name value 'FINDING_4',
18 | end of co_test_method_name.
19 |
20 |
21 | methods run_test_check_findings for testing raising cx_static_check.
22 |
23 | endclass.
24 |
25 |
26 | class ltcl_test implementation.
27 |
28 | method run_test_check_findings.
29 |
30 | " Location and quickfixes of expected findings
31 | data(finding_1_obj) = cl_ci_atc_unit_driver=>get_method_object(
32 | value #( class = co_test_object-object_name method = co_test_method_name-finding_1 ) ).
33 | data(finding_1_loc) = value if_ci_atc_check=>ty_location(
34 | object = finding_1_obj
35 | position = value #( line = 7 column = 4 ) ).
36 | data(qf1_finding_1) = value if_ci_atc_unit_asserter=>ty_expected_quickfixes(
37 | ( code = value #(
38 | ( |C = D.| )
39 | ( |B = C.| )
40 | ( |A = B.| ) )
41 | location = finding_1_loc
42 | quickfix_code = /cc4a/equals_sign_chaining=>quickfix_codes-break_chain ) ).
43 | data(finding_2_obj) = cl_ci_atc_unit_driver=>get_method_object(
44 | value #( class = co_test_object-object_name method = co_test_method_name-finding_2 ) ).
45 | data(finding_2_loc) = value if_ci_atc_check=>ty_location(
46 | object = finding_2_obj
47 | position = value #( line = 6 column = 4 ) ).
48 | data(qf1_finding_2) = value if_ci_atc_unit_asserter=>ty_expected_quickfixes(
49 | ( code = value #(
50 | ( |B = CONV #( c ).| )
51 | ( |A = B.| ) )
52 | location = finding_1_loc
53 | quickfix_code = /cc4a/equals_sign_chaining=>quickfix_codes-break_chain ) ).
54 | " Finding 3 should not appear due to the pseudo comment
55 | data(finding_4_obj) = cl_ci_atc_unit_driver=>get_method_object(
56 | value #( class = co_test_object-object_name method = co_test_method_name-finding_4 ) ).
57 | data(finding_4_loc) = value if_ci_atc_check=>ty_location(
58 | object = finding_4_obj
59 | position = value #( line = 7 column = 6 ) ).
60 | data(qf1_finding_4) = value if_ci_atc_unit_asserter=>ty_expected_quickfixes(
61 | ( code = value #(
62 | ( |B = C.| )
63 | ( |A = B.| ) )
64 | location = finding_4_loc
65 | quickfix_code = /cc4a/equals_sign_chaining=>quickfix_codes-break_chain ) ).
66 |
67 | cl_ci_atc_unit_driver=>create_asserter( )->check_and_assert(
68 | check = new /cc4a/equals_sign_chaining( )
69 | object = value #( name = co_test_object-object_name
70 | type = co_test_object-object_type )
71 | asserter_config = value #( quickfixes = abap_false
72 | remove_findings_with_pcoms = abap_true )
73 | expected_findings = value #( ( code = /cc4a/equals_sign_chaining=>finding_codes-equals_sign_chaining
74 | location = finding_1_loc
75 | quickfixes = qf1_finding_1 )
76 | ( code = /cc4a/equals_sign_chaining=>finding_codes-equals_sign_chaining
77 | location = finding_2_loc
78 | quickfixes = qf1_finding_2 )
79 | ( code = /cc4a/equals_sign_chaining=>finding_codes-equals_sign_chaining
80 | location = finding_4_loc
81 | quickfixes = qf1_finding_4 ) ) ).
82 |
83 | endmethod.
84 |
85 | endclass.
86 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_prefer_is_not.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_prefer_is_not definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | protected section.
8 | private section.
9 |
10 | types: begin of table_type,
11 | position type i,
12 | name type string,
13 | end of table_type.
14 |
15 | methods without_brackets.
16 | methods with_brackets.
17 | methods with_pseudo_comments.
18 | methods chained_method_call.
19 |
20 |
21 | methods getint
22 | importing zahl1 type i optional
23 | zahl2 type i optional
24 | returning value(int) type i.
25 | methods getbool
26 | importing true type abap_bool optional
27 | returning value(bool) type abap_bool.
28 | methods get_tester
29 | returning value(tester) type ref to tester.
30 |
31 | data x type i.
32 | data obj type ref to object.
33 | data int_tab type range of i.
34 | ENDCLASS.
35 |
36 |
37 |
38 | CLASS /CC4A/TEST_PREFER_IS_NOT IMPLEMENTATION.
39 |
40 |
41 | method chained_method_call.
42 | if not get_tester( )->check( 2 ).
43 | endif.
44 | endmethod.
45 |
46 |
47 | method getbool.
48 |
49 | endmethod.
50 |
51 |
52 | method getint.
53 |
54 | endmethod.
55 |
56 |
57 | method get_tester.
58 |
59 | endmethod.
60 |
61 |
62 | method without_brackets.
63 |
64 | assert not getint( ) = getbool( ).
65 |
66 | if not x > 1.
67 | endif.
68 |
69 | if not x <> getint( ).
70 | elseif not x < getint( zahl1 = 2 zahl2 = 3 ).
71 | endif.
72 |
73 | if not x in int_tab.
74 | endif.
75 |
76 | if not obj is initial.
77 | elseif not obj is bound.
78 | endif.
79 |
80 | if not x <= getbool( ).
81 | endif.
82 |
83 | if not x ne xsdbool( 1 = 2 ).
84 | endif.
85 |
86 | if not x lt 1 or not x ge getbool( xsdbool( 1 = 2 ) ).
87 | endif.
88 |
89 | if not x le 1 and not x eq 2 .
90 | endif.
91 |
92 | assert not 1 <> 2.
93 |
94 | if not getbool( true = abap_false ).
95 | endif.
96 |
97 | if not getbool( ).
98 | endif.
99 | endmethod.
100 |
101 |
102 | method with_brackets.
103 |
104 | assert not ( getint( ) = getbool( ) ).
105 |
106 | if not ( x = 1 ).
107 | endif.
108 |
109 | if not ( x <> getint( ) ).
110 | elseif not ( x < getint( zahl1 = 2 zahl2 = 3 ) ).
111 | endif.
112 |
113 | if not ( x in int_tab ).
114 | endif.
115 |
116 | if not ( obj is initial ).
117 | elseif not ( obj is bound ).
118 | endif.
119 |
120 | if not ( x <= getbool( ) ).
121 | endif.
122 |
123 | if not ( x ne xsdbool( 1 = xsdbool( 1 = 2 ) ) ).
124 | endif.
125 |
126 | if not ( x lt 1 or x ge getbool( xsdbool( 1 = 2 ) ) ).
127 | endif.
128 |
129 | if not ( x le 1 and not x eq 2 ).
130 | endif.
131 |
132 | assert not ( 1 <> 2 ).
133 |
134 | if not ( ( 1 + 2 ) = 3 ).
135 | endif.
136 |
137 | if not ( ( 1 + 2 ) + 3 = 3 ).
138 | endif.
139 |
140 | if not ( ( 1 + 2 ) + ( 3 + 3 ) = 3 ).
141 | endif.
142 |
143 | endmethod.
144 |
145 |
146 | method with_pseudo_comments.
147 |
148 | assert not getint( ) = getbool( ). "#EC PREFER_IS_NOT
149 |
150 | if not x = 1. "#EC PREFER_IS_NOT
151 | endif.
152 |
153 | if not x <> getint( ). "#EC PREFER_IS_NOT
154 | elseif not x < getint( zahl1 = 2 zahl2 = 3 ). "#EC PREFER_IS_NOT
155 | endif.
156 |
157 | if not x in int_tab. "#EC PREFER_IS_NOT
158 | endif.
159 |
160 | if not obj is initial. "#EC PREFER_IS_NOT
161 | elseif not obj is bound. "#EC PREFER_IS_NOT
162 | endif.
163 |
164 | if not ( x <= getbool( ) ). "#EC PREFER_IS_NOT
165 | endif.
166 |
167 | if not ( x ne xsdbool( 1 = xsdbool( 1 = 2 ) ) ). "#EC PREFER_IS_NOT
168 | endif.
169 |
170 | if not ( x lt 1 or x ge getbool( xsdbool( 1 = 2 ) ) ).
171 | endif.
172 |
173 | if not ( x le 1 and not x eq 2 ). "#EC PREFER_IS_NOT
174 | endif.
175 |
176 | assert not ( 1 <> 2 ). "#EC PREFER_IS_NOT
177 |
178 | endmethod.
179 | ENDCLASS.
180 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_proper_bool_expr.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_proper_bool_expr definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | constants: bool type abap_bool value 'X'.
8 | data a type abap_bool.
9 |
10 | types: begin of number_and_bool,
11 | number type i,
12 | boolean type abap_bool,
13 | end of number_and_bool.
14 |
15 | types: begin of struc_of_nab,
16 | nab type number_and_bool,
17 | end of struc_of_nab.
18 |
19 | types tabletype type table of number_and_bool with empty key.
20 |
21 | types: begin of struc_of_table,
22 | table type tabletype,
23 | end of struc_of_table.
24 |
25 | data table2 type table of struc_of_table.
26 | types j type table of struc_of_nab.
27 |
28 | data table type tabletype.
29 | data structure_of_table type struc_of_table.
30 | data abapboolean type abap_boolean.
31 |
32 | data number_bool_table type table of number_and_bool.
33 | data number_bool_structure type number_and_bool.
34 | data strc_nab_table type table of struc_of_nab.
35 | data test_struc_nab type struc_of_nab.
36 | methods test_method
37 | importing iparameter type i optional
38 | returning value(rparameter) type i.
39 |
40 | types:
41 | begin of enum ty_my_bool structure my_bool base type abap_bool,
42 | false value is initial,
43 | true value 'X',
44 | end of enum ty_my_bool structure my_bool.
45 |
46 | protected section.
47 | constants: not_a_bool type string value ' '.
48 | private section.
49 | methods test_if_then_else.
50 | methods test_correct_bool_usage.
51 | methods test_bool_initial.
52 | data int_tab type range of i.
53 | data x type i.
54 | data implicit.
55 | endclass.
56 |
57 |
58 |
59 | class /cc4a/test_proper_bool_expr implementation.
60 |
61 | method test_if_then_else.
62 | data(test) = 'test'.
63 | data(test_number) = 5.
64 | data(b) = abap_true.
65 | if test is initial.
66 | b = abap_true.
67 | else.
68 | b = abap_false.
69 | endif.
70 |
71 | if test is initial.
72 | b = abap_false.
73 | else.
74 | b = abap_true.
75 | endif.
76 |
77 | if test is not initial.
78 | b = abap_false.
79 | else.
80 | b = abap_true.
81 | endif.
82 |
83 | if x in int_tab.
84 | b = abap_false.
85 | else.
86 | b = abap_true.
87 | endif.
88 |
89 | if x not in int_tab.
90 | b = abap_false.
91 | else.
92 | b = abap_true.
93 | endif.
94 |
95 | if test_number lt 38.
96 | b = abap_false.
97 | else.
98 | b = abap_true.
99 | endif.
100 |
101 | if test_number <> 4 or test is not initial.
102 | b = abap_false.
103 | else.
104 | b = abap_true.
105 | endif.
106 |
107 | data(string) = 'teststring'.
108 | if 1 = 2 and 'test' ne substring( len = test_method( iparameter = 3 ) val = string ) and 5 gt 2.
109 | b = ' '.
110 | else.
111 | b = 'X'.
112 | endif.
113 |
114 | if a is not initial.
115 | number_bool_structure-boolean = abap_false.
116 | else.
117 | number_bool_structure-boolean = abap_true.
118 | endif.
119 |
120 | if a is initial.
121 | b = abap_true.
122 | else.
123 | b = abap_false.
124 | endif.
125 |
126 | if table2[ 4 ]-table[ 1 ]-boolean is initial.
127 | b = abap_false.
128 | else.
129 | b = abap_true.
130 | endif.
131 |
132 | if table2[ 4 ]-table[ 1 ]-boolean is initial.
133 | data(c) = abap_true.
134 | else.
135 | c = abap_false.
136 | endif.
137 |
138 | if test_method( 22 ) is initial.
139 | data(d) = abap_true.
140 | endif.
141 |
142 | endmethod.
143 |
144 |
145 | method test_correct_bool_usage.
146 | data t type abap_bool.
147 | t = 'X'.
148 | number_bool_structure-boolean = ' '.
149 | a = space.
150 | test_struc_nab-nab-boolean = 'X'.
151 |
152 |
153 | endmethod.
154 |
155 | method test_bool_initial.
156 | if a is initial.
157 | endif.
158 | if table2[ 4 ]-table[ 1 ]-boolean is initial.
159 | endif.
160 | if test_struc_nab-nab-boolean is initial.
161 | endif.
162 | endmethod.
163 |
164 |
165 | method test_method.
166 |
167 | endmethod.
168 |
169 | endclass.
170 |
171 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#tstflight1.tabl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /CC4A/TSTFLIGHT1
7 | TRANSP
8 | X
9 | D
10 | X
11 | A
12 | 1
13 |
14 |
15 | /CC4A/TSTFLIGHT1
16 | A
17 | 0
18 | APPL1
19 | N
20 |
21 |
22 |
23 | MANDT
24 | X
25 | 0
26 | C
27 | 000006
28 | X
29 | CLNT
30 | 000003
31 | CLNT
32 |
33 |
34 | CARRID
35 | X
36 | 0
37 | C
38 | 000006
39 | X
40 | CHAR
41 | 000003
42 | CHAR
43 |
44 |
45 | CONNID
46 | X
47 | 0
48 | N
49 | 000008
50 | X
51 | NUMC
52 | 000004
53 | NUMC
54 |
55 |
56 | FLDATE
57 | X
58 | 0
59 | D
60 | 000016
61 | X
62 | DATS
63 | 000008
64 | DATS
65 | T
66 |
67 |
68 | CURRENCY
69 | 0
70 | C
71 | 000010
72 | X
73 | CUKY
74 | 000005
75 | CUKY
76 |
77 |
78 | PLANETYPE
79 | 0
80 | C
81 | 000120
82 | X
83 | CHAR
84 | 000060
85 | CHAR
86 |
87 |
88 | QUANTITY
89 | 0
90 | X
91 | 000002
92 | X
93 | INT2
94 | 000005
95 | INT2
96 |
97 |
98 |
99 | D
100 |
101 |
102 | -
103 | D
104 | Test / Flug
105 |
106 |
107 |
108 | -
109 |
110 | TB
111 |
112 | D
113 | E
114 | 0002
115 | X
116 | 00002
117 | A
118 |
119 |
120 | DOKU
121 | /CC4A/TSTFLIGHT1
122 | TB
123 | D
124 | S_DOCU_SHOW
125 | S_DOCUS1
126 | 00002
127 | 072
128 |
129 |
130 |
131 | U1
132 | &USE&
133 |
134 |
135 | AS
136 | Diese Tabelle wird im Rahmen der ABAP/4-Schulungen verwendet. Sie ent-
137 |
138 |
139 | hält Informationen zu angebotenen Flügen.
140 |
141 |
142 | U1
143 | &MAINTENANCE&
144 |
145 |
146 | AS
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/src/core/#cc4a#check_meta_data.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/check_meta_data definition
2 | public
3 | final
4 | create private.
5 |
6 | public section.
7 | interfaces /cc4a/if_check_meta_data.
8 |
9 | types:
10 | begin of enum ty_checked_types structure checked_types,
11 | abap_programs,
12 | end of enum ty_checked_types structure checked_types.
13 | types:
14 | "! Remote enablement status of a check.
15 | "!
16 | "! Extend this enum with new variants if a check needs additional functionality in the target system
17 | "! besides the standard Code Inspector infrastructure to analyze ABAP code.
18 | begin of enum ty_remote_enablement structure remote_enablement,
19 | unconditional,
20 | no,
21 | end of enum ty_remote_enablement structure remote_enablement.
22 | types:
23 | begin of ty_finding_code,
24 | code type if_ci_atc_check=>ty_finding_code,
25 | text type if_ci_atc_check_meta_data=>ty_finding_code_info-text,
26 | pseudo_comment type if_ci_atc_check_meta_data=>ty_finding_code_info-pseudo_comment,
27 | end of ty_finding_code.
28 | types ty_finding_codes type hashed table of ty_finding_code with unique key code.
29 | types:
30 | begin of ty_meta_data,
31 | checked_types type ty_checked_types,
32 | description type string,
33 | remote_enablement type ty_remote_enablement,
34 | finding_codes type ty_finding_codes,
35 | quickfix_codes type if_ci_atc_check_meta_data=>ty_quickfix_code_infos,
36 | attributes type if_ci_atc_check_meta_data=>ty_attributes,
37 | end of ty_meta_data.
38 |
39 | class-methods create
40 | importing meta_data type ty_meta_data
41 | returning value(result) type ref to /cc4a/if_check_meta_data.
42 | methods constructor
43 | importing meta_data type ty_meta_data.
44 |
45 | protected section.
46 |
47 | private section.
48 | data meta_data type ty_meta_data.
49 | endclass.
50 |
51 |
52 |
53 | class /cc4a/check_meta_data implementation.
54 |
55 |
56 | method constructor.
57 | me->meta_data = meta_data.
58 | " Callers will usually pass references to the actual attributes of their check as the value.
59 | " This can lead to various unexpected phenomena when these references are then passed back in SET_ATTRIBUTES
60 | " to the checks. In order to isolate us againnst these errors we copy all the attribute references to freshly
61 | " allocated anonymous references on the heap that are used for nother else.
62 | loop at me->meta_data-attributes assigning field-symbol().
63 | data(type_handle) = cast cl_abap_datadescr( cl_abap_typedescr=>describe_by_data_ref( -value ) ).
64 | data value type ref to data.
65 | create data value type handle type_handle.
66 | value->* = -value->*.
67 | -value = value.
68 | endloop.
69 | loop at me->meta_data-finding_codes assigning field-symbol().
70 | -pseudo_comment = |CI_{ -pseudo_comment }|.
71 | endloop.
72 | endmethod.
73 |
74 |
75 | method create.
76 | result = new /cc4a/check_meta_data( meta_data ).
77 | endmethod.
78 |
79 |
80 | method if_ci_atc_check_meta_data~get_attributes.
81 | attributes = meta_data-attributes.
82 | endmethod.
83 |
84 |
85 | method if_ci_atc_check_meta_data~get_checked_object_types.
86 | types = switch #( meta_data-checked_types
87 | when checked_types-abap_programs then value #( ( 'PROG' ) ( 'CLAS' ) ( 'FUGR' ) ( 'INTF' ) ) ).
88 | endmethod.
89 |
90 |
91 | method if_ci_atc_check_meta_data~get_description.
92 | description = meta_data-description.
93 | endmethod.
94 |
95 |
96 | method if_ci_atc_check_meta_data~get_finding_code_infos.
97 | finding_code_infos = corresponding #( meta_data-finding_codes ).
98 | endmethod.
99 |
100 |
101 | method if_ci_atc_check_meta_data~get_quickfix_code_infos.
102 | quickfix_code_infos = meta_data-quickfix_codes.
103 | endmethod.
104 |
105 |
106 | method if_ci_atc_check_meta_data~is_remote_enabled.
107 | is_remote_enabled = switch #( meta_data-remote_enablement
108 | when remote_enablement-unconditional then abap_true
109 | when remote_enablement-no then abap_false ).
110 | endmethod.
111 |
112 |
113 | method if_ci_atc_check_meta_data~uses_checksums.
114 | uses_checksums = abap_true.
115 | endmethod.
116 |
117 |
118 | method /cc4a/if_check_meta_data~has_valid_pseudo_comment.
119 | data(pseudo_comment) = meta_data-finding_codes[ code = finding_code ]-pseudo_comment.
120 | has_valid_pseudo_comment = xsdbool(
121 | line_exists( statement-pseudo_comments[ table_line = pseudo_comment ] ) or
122 | line_exists( statement-pseudo_comments[ table_line = pseudo_comment+3 ] ) ).
123 | endmethod.
124 |
125 | endclass.
126 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#avoid_default_key.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/avoid_default_key definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | interfaces if_ci_atc_check.
8 |
9 | constants:
10 | begin of finding_codes,
11 | default_key type if_ci_atc_check=>ty_finding_code value 'DEFAULTKEY',
12 | end of finding_codes.
13 | constants:
14 | begin of quickfix_codes,
15 | empty_key type cl_ci_atc_quickfixes=>ty_quickfix_code value 'EMPTYKEY',
16 | end of quickfix_codes.
17 |
18 | methods constructor.
19 |
20 | protected section.
21 | private section.
22 | constants pseudo_comment type string value 'DEFAULT_KEY'.
23 |
24 | data code_provider type ref to if_ci_atc_source_code_provider.
25 | data assistant_factory type ref to cl_ci_atc_assistant_factory.
26 | data meta_data type ref to /cc4a/if_check_meta_data.
27 |
28 | methods analyze_procedure
29 | importing procedure type if_ci_atc_source_code_provider=>ty_procedure
30 | returning value(findings) type if_ci_atc_check=>ty_findings.
31 | methods replace_empty_key
32 | importing statement type if_ci_atc_source_code_provider=>ty_statement
33 | key_word_position type i
34 | returning value(modified_statement) type if_ci_atc_quickfix=>ty_code.
35 |
36 | ENDCLASS.
37 |
38 |
39 |
40 | CLASS /CC4A/AVOID_DEFAULT_KEY IMPLEMENTATION.
41 |
42 |
43 | method analyze_procedure.
44 | loop at procedure-statements assigning field-symbol()
45 | where keyword = 'DATA' or keyword = 'TYPES'
46 | or keyword = 'CLASS-DATA' or keyword = 'CONSTANTS' or keyword = 'STATICS'.
47 |
48 | data(found_at_position) = /cc4a/abap_analyzer=>create( )->find_key_words(
49 | key_words = value #( ( `WITH` ) ( `DEFAULT` ) ( `KEY` ) )
50 | statement = ).
51 |
52 | if found_at_position > 0.
53 | data(available_quickfixes) = assistant_factory->create_quickfixes( ).
54 | available_quickfixes->create_quickfix( quickfix_codes-empty_key )->replace(
55 | context = assistant_factory->create_quickfix_context(
56 | value #( procedure_id = procedure-id statements = value #( from = sy-tabix to = sy-tabix ) ) )
57 | code = replace_empty_key( statement = key_word_position = found_at_position ) ).
58 | insert value #(
59 | code = finding_codes-default_key
60 | location = code_provider->get_statement_location( )
61 | checksum = code_provider->get_statement_checksum( )
62 | has_pseudo_comment = meta_data->has_valid_pseudo_comment(
63 | statement =
64 | finding_code = finding_codes-default_key )
65 | details = assistant_factory->create_finding_details( )->attach_quickfixes( available_quickfixes )
66 | ) into table findings.
67 | endif.
68 | endloop.
69 |
70 | endmethod.
71 |
72 |
73 | method if_ci_atc_check~get_meta_data.
74 | meta_data = me->meta_data.
75 | endmethod.
76 |
77 | method constructor.
78 | meta_data = /cc4a/check_meta_data=>create(
79 | value #( checked_types = /cc4a/check_meta_data=>checked_types-abap_programs
80 | description = 'Avoid default keys'(des)
81 | remote_enablement = /cc4a/check_meta_data=>remote_enablement-unconditional
82 | finding_codes = value #(
83 | ( code = finding_codes-default_key
84 | pseudo_comment = pseudo_comment text = 'Usage of default table key'(dtk) ) )
85 | quickfix_codes = value #(
86 | ( code = quickfix_codes-empty_key short_text = 'Replace WITH DEFAULT KEY with WITH EMPTY KEY'(qek) ) ) ) ).
87 | endmethod.
88 |
89 |
90 | method if_ci_atc_check~run.
91 | code_provider = data_provider->get_code_provider( ).
92 | data(procedures) = code_provider->get_procedures( code_provider->object_to_comp_unit( object ) ).
93 | loop at procedures->* assigning field-symbol().
94 | insert lines of analyze_procedure( ) into table findings.
95 | endloop.
96 | endmethod.
97 |
98 |
99 | method if_ci_atc_check~set_assistant_factory.
100 | assistant_factory = factory.
101 | endmethod.
102 |
103 |
104 | method if_ci_atc_check~verify_prerequisites.
105 |
106 | endmethod.
107 |
108 |
109 | method replace_empty_key.
110 | data(new_statement) = statement.
111 | loop at new_statement-tokens from key_word_position assigning field-symbol().
112 | if -lexeme eq 'DEFAULT'.
113 | -lexeme = 'EMPTY'.
114 | endif.
115 | endloop.
116 | data(flat_new_statement) = /cc4a/abap_analyzer=>create( )->flatten_tokens( new_statement-tokens ) && `.`.
117 | modified_statement = /cc4a/abap_analyzer=>create( )->break_into_lines( flat_new_statement ).
118 | endmethod.
119 | ENDCLASS.
120 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_method_signature.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS /cc4a/test_method_signature DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION. "#EC INTF_IN_CLASS
7 | INTERFACES /cc4a/test_method_signature_if.
8 |
9 | METHODS public_inst_not_interface_meth.
10 |
11 | PROTECTED SECTION.
12 |
13 | PRIVATE SECTION.
14 | METHODS multi_ouput_params_types_1
15 | EXPORTING param1 TYPE c
16 | CHANGING param2 TYPE c
17 | RETURNING VALUE(result) TYPE string.
18 |
19 | METHODS multi_ouput_params_types_2
20 | EXPORTING param1 TYPE c
21 | param2 TYPE c
22 | CHANGING param3 TYPE c
23 | RETURNING VALUE(result) TYPE string.
24 |
25 | METHODS multi_ouput_params_types_3
26 | EXPORTING param1 TYPE c
27 | CHANGING param2 TYPE c
28 | RETURNING VALUE(result) TYPE string. "#EC PARAMETER_OUT
29 |
30 | METHODS multi_ouput_params_1
31 | EXPORTING param1 TYPE c
32 | param2 TYPE c.
33 |
34 | METHODS multi_ouput_params_2
35 | CHANGING param1 TYPE c
36 | param2 TYPE c.
37 |
38 | METHODS multi_ouput_params_3
39 | IMPORTING param1 TYPE abap_boolean
40 | param2 TYPE c
41 | CHANGING param3 TYPE c
42 | param4 TYPE c.
43 |
44 | METHODS multi_ouput_params_4
45 | IMPORTING param1 TYPE c
46 | param2 TYPE c
47 | CHANGING param3 TYPE c.
48 |
49 | METHODS multi_ouput_params_5
50 | EXPORTING param1 TYPE c
51 | param2 TYPE c. "#EC NUM_OUTPUT_PARA
52 |
53 | METHODS single_export_param
54 | EXPORTING param1 TYPE abap_bool.
55 |
56 | METHODS input_param_bool_1
57 | IMPORTING param1 TYPE abap_bool.
58 |
59 | METHODS input_param_bool_2
60 | IMPORTING param1 TYPE abap_bool
61 | param2 TYPE c.
62 |
63 | METHODS input_param_bool_3
64 | IMPORTING param1 TYPE abap_bool
65 | RETURNING VALUE(result) TYPE string.
66 |
67 | METHODS get_result
68 | RETURNING VALUE(not_result) TYPE string.
69 |
70 | METHODS input_param_bool_4
71 | IMPORTING param1 TYPE abap_bool. "#EC BOOL_PARAM
72 |
73 | METHODS set_param
74 | IMPORTING param TYPE abap_bool.
75 |
76 | METHODS do_one_or_the_other
77 | IMPORTING what_i_need TYPE string OPTIONAL
78 | something_else TYPE i OPTIONAL.
79 |
80 | METHODS do_one_or_the_other_prag
81 | IMPORTING
82 | what_i_need TYPE string OPTIONAL
83 | something_else TYPE i OPTIONAL. "#EC OPTL_PARAM
84 |
85 | ENDCLASS.
86 |
87 |
88 |
89 | CLASS /cc4a/test_method_signature IMPLEMENTATION.
90 |
91 |
92 | METHOD multi_ouput_params_types_1.
93 | "only signature is relevant for this test
94 | ENDMETHOD.
95 |
96 |
97 | METHOD multi_ouput_params_types_2.
98 | "only signature is relevant for this test
99 | ENDMETHOD.
100 |
101 |
102 | METHOD multi_ouput_params_types_3.
103 | "only signature is relevant for this test
104 | ENDMETHOD.
105 |
106 |
107 | METHOD multi_ouput_params_1.
108 | "only signature is relevant for this test
109 | ENDMETHOD.
110 |
111 |
112 | METHOD multi_ouput_params_2.
113 | "only signature is relevant for this test
114 | ENDMETHOD.
115 |
116 |
117 | METHOD multi_ouput_params_3.
118 | "only signature is relevant for this test
119 | ENDMETHOD.
120 |
121 |
122 | METHOD multi_ouput_params_4.
123 | "only signature is relevant for this test
124 | ENDMETHOD.
125 |
126 |
127 | METHOD multi_ouput_params_5.
128 | "only signature is relevant for this test
129 | ENDMETHOD.
130 |
131 |
132 | METHOD input_param_bool_1.
133 | "only signature is relevant for this test
134 | ENDMETHOD.
135 |
136 |
137 | METHOD input_param_bool_2.
138 | "only signature is relevant for this test
139 | ENDMETHOD.
140 |
141 |
142 | METHOD input_param_bool_3.
143 | "only signature is relevant for this test
144 | ENDMETHOD.
145 |
146 |
147 | METHOD input_param_bool_4.
148 | "only signature is relevant for this test
149 | ENDMETHOD.
150 |
151 |
152 | METHOD do_one_or_the_other.
153 | "only signature is relevant for this test
154 | ENDMETHOD.
155 |
156 |
157 | METHOD do_one_or_the_other_prag.
158 | "only signature is relevant for this test
159 | ENDMETHOD.
160 |
161 |
162 | METHOD set_param.
163 | "only signature is relevant for this test
164 | ENDMETHOD.
165 |
166 |
167 | METHOD public_inst_not_interface_meth.
168 | "only signature is relevant for this test
169 | ENDMETHOD.
170 |
171 |
172 | METHOD /cc4a/test_method_signature_if~public_inst_interface_meth.
173 | "only signature is relevant for this test
174 | ENDMETHOD.
175 |
176 |
177 | METHOD single_export_param.
178 | "only signature is relevant for this test
179 | ENDMETHOD.
180 |
181 | METHOD get_result.
182 | "only signature is relevant for this test
183 | ENDMETHOD.
184 |
185 | ENDCLASS.
186 |
--------------------------------------------------------------------------------
/src/core/#cc4a#if_abap_analyzer.intf.abap:
--------------------------------------------------------------------------------
1 | "! Shared functionality to analyze ABAP code.
2 | "!
3 | "! Any logic that processes ABAP code information (e.g. parsing a specific assignment) should be located here
4 | "! so it can be accessed by any check that needs it.
5 | interface /cc4a/if_abap_analyzer
6 | public .
7 | constants max_line_length type i value 255.
8 | types:
9 | begin of enum ty_bracket_type structure bracket_type,
10 | no_bracket,
11 | opening,
12 | closing,
13 | "! Closed and opening. Due to quirks in the ABAP tokenizer, a chained method call like
14 | "! obj->method_1( )->method_2( ) produces a single token `)->method_2(` that is both a closing and an
15 | "! opening bracket.
16 | clopening,
17 | end of enum ty_bracket_type structure bracket_type.
18 | types:
19 | begin of ty_db_statement,
20 | is_db type abap_bool,
21 | dbtab type string,
22 | dbtab_subquery type string,
23 | end of ty_db_statement.
24 | types:
25 | begin of enum ty_parameter_kind structure parameter_kind,
26 | importing,
27 | exporting,
28 | changing,
29 | returning,
30 | end of enum ty_parameter_kind structure parameter_kind.
31 | types:
32 | begin of ty_method_parameter,
33 | name type string,
34 | kind type ty_parameter_kind,
35 | end of ty_method_parameter.
36 | types ty_method_parameters type hashed table of ty_method_parameter with unique key name.
37 | types:
38 | begin of ty_method_definition,
39 | name type string,
40 | is_redefinition type abap_bool,
41 | parameters type ty_method_parameters,
42 | end of ty_method_definition.
43 | types:
44 | begin of enum ty_logical_connective structure logical_connective,
45 | none,
46 | and,
47 | or,
48 | equiv,
49 | not,
50 | end of enum ty_logical_connective structure logical_connective.
51 |
52 |
53 | methods find_key_words
54 | importing
55 | key_words type string_table
56 | statement type if_ci_atc_source_code_provider=>ty_statement
57 | returning
58 | value(position) type i .
59 | methods break_into_lines
60 | importing code type string
61 | returning value(code_lines) type if_ci_atc_quickfix=>ty_code
62 | raising /cc4a/cx_line_break_impossible.
63 | methods flatten_tokens
64 | importing
65 | tokens type if_ci_atc_source_code_provider=>ty_tokens
66 | returning
67 | value(flat_statement) type string .
68 | methods is_bracket
69 | importing
70 | token type if_ci_atc_source_code_provider=>ty_token
71 | returning
72 | value(bracket_type) type ty_bracket_type .
73 | methods calculate_bracket_end
74 | importing
75 | statement type if_ci_atc_source_code_provider=>ty_statement
76 | bracket_position type i
77 | returning
78 | value(end_of_bracket) type i
79 | raising
80 | /cc4a/cx_token_is_no_bracket .
81 | "! The method analyze the given token whether this is an comparison operator or not.
82 | "! Operators like +, -, * and / does not count as comparison operator.
83 | "! The following operators are currently supported: is, in, >, gt, <, lt, >=, ge, <=, le, =, eq, <>, ne
84 | methods token_is_comparison_operator
85 | importing
86 | token type if_ci_atc_source_code_provider=>ty_token
87 | returning
88 | value(is_operator) type abap_bool .
89 | methods negate_comparison_operator
90 | importing
91 | comparison_operator type string
92 | returning
93 | value(negated_comparison_operator) type string
94 | raising
95 | /cc4a/cx_token_is_no_operator .
96 | methods negate_logical_expression
97 | importing
98 | tokens type if_ci_atc_source_code_provider=>ty_tokens
99 | returning
100 | value(negated_expression) type string.
101 | methods is_db_statement
102 | importing
103 | statement type if_ci_atc_source_code_provider=>ty_statement
104 | get_dbtab_name type abap_bool default abap_false
105 | include_subqueries type abap_bool default abap_true
106 | returning
107 | value(result) type ty_db_statement.
108 |
109 | "! The method checks if clause is contained in tokens
110 | "! if so it returns the index of the first token of the first occurrence of the clause
111 | "! otherwise token_index = 0
112 | methods find_clause_index
113 | importing
114 | tokens type if_ci_atc_source_code_provider=>ty_tokens
115 | clause type string
116 | start_index type i default 1
117 | returning
118 | value(token_index) type i
119 | raising
120 | /cc4a/cx_clause_is_initial .
121 | methods is_token_keyword
122 | importing
123 | token type if_ci_atc_source_code_provider=>ty_token
124 | keyword type string
125 | returning
126 | value(result) type abap_bool .
127 | methods is_logical_connective
128 | importing token type if_ci_atc_source_code_provider=>ty_token
129 | returning value(is_logical_connective) type ty_logical_connective.
130 | methods parse_method_definition
131 | importing statement type if_ci_atc_source_code_provider=>ty_statement
132 | returning value(method_definition) type ty_method_definition.
133 | endinterface.
134 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_for_db_statements.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS /cc4a/test_for_db_statements DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 | PROTECTED SECTION.
8 | PRIVATE SECTION.
9 | METHODS no_db.
10 | METHODS dyn.
11 | METHODS mixed.
12 | ENDCLASS.
13 |
14 |
15 |
16 | CLASS /CC4A/TEST_FOR_DB_STATEMENTS IMPLEMENTATION.
17 |
18 |
19 | METHOD dyn.
20 | CONSTANTS c_name TYPE tabname VALUE '/CC4A/DB_TEST2'.
21 | DATA: itab TYPE TABLE OF i,
22 | entry TYPE i,
23 | single TYPE /cc4a/db_test1.
24 | DELETE FROM (`/CC4A/DB_TEST1`)
25 | WHERE obj_name = 'BLABLA'.
26 | LOOP AT itab INTO entry.
27 | SELECT SINGLE * FROM ('/CC4A/DB_TEST2') INTO @entry.
28 | ENDLOOP.
29 | DO.
30 | SELECT SINGLE * FROM (c_name) INTO @entry.
31 | ENDDO.
32 | SELECT SINGLE * FROM ('/CC4A/DB_TEST1') INTO @entry.
33 | SELECT * FROM ('/CC4A/DB_TEST1') INTO @entry.
34 | ENDSELECT.
35 | SELECT * FROM ('/CC4A/DB_TEST1') INTO TABLE @itab.
36 | INSERT ('/CC4A/DB_TEST1') FROM @entry.
37 | INSERT INTO ('/CC4A/DB_TEST1') VALUES @entry.
38 | UPDATE ('/CC4A/DB_TEST1') FROM @entry.
39 | UPDATE ('/CC4A/DB_TEST1') SET pgmid = 'BLAB'.
40 | MODIFY ('/CC4A/DB_TEST1') FROM @entry.
41 | DELETE FROM ('/CC4A/DB_TEST1'). "
42 | DELETE FROM ('/CC4A/DB_TEST1')
43 | WHERE pgmid = 'BLAB'.
44 | DELETE ('/CC4A/DB_TEST1') FROM @entry.
45 | ENDMETHOD.
46 |
47 |
48 | METHOD mixed.
49 | DATA: dbcur TYPE cursor,
50 | entry TYPE /cc4a/db_test1,
51 | itab TYPE TABLE OF /cc4a/db_test1.
52 | * OPEN CURSOR dbcur FOR SELECT * FROM /cc4a/db_test1.
53 | * OPEN CURSOR WITH HOLD dbcur FOR SELECT * FROM /cc4a/db_test1.
54 |
55 | SELECT SINGLE * FROM /cc4a/db_test1 INTO @entry.
56 | SELECT FROM /cc4a/db_test1 INNER JOIN /cc4a/db_test2 ON /cc4a/db_test2~object = /cc4a/db_test1~object
57 | FIELDS * INTO @DATA(dummy).
58 | ENDSELECT.
59 |
60 | DELETE FROM /cc4a/db_test1.
61 | DELETE FROM /cc4a/db_test2 WHERE object NOT IN ( SELECT object FROM /cc4a/db_test1 WHERE pgmid = 'R3TR' ).
62 | DELETE FROM /cc4a/db_test1
63 | WHERE obj_name = 'BLABLA'.
64 | DELETE FROM /cc4a/db_test1.
65 | DELETE FROM /cc4a/db_test1
66 | WHERE pgmid = 'BLAB'.
67 | * DELETE /cc4a/db_test1 FROM entry.
68 | * DELETE FROM DATABASE demo_indx_blob(sc) ID 'DEMO'.
69 |
70 | INSERT /cc4a/db_test2 FROM ( SELECT * FROM /cc4a/db_test1 ) ##LOGGING_VERSUS_FROM_SELECT[/CC4A/DB_TEST2].
71 | INSERT entry INTO TABLE itab. "no db
72 | LOOP AT itab INTO entry.
73 | INSERT entry INTO itab. "no db
74 | ENDLOOP.
75 |
76 | UPDATE /cc4a/db_test2 SET object = '1' WHERE object NOT IN ( SELECT object FROM /cc4a/db_test1 WHERE pgmid = 'R3TR' ).
77 | UPDATE /cc4a/db_test1 FROM @entry.
78 | UPDATE /cc4a/db_test1 SET pgmid = 'BLAB'.
79 |
80 | MODIFY /cc4a/db_test1 FROM @entry.
81 |
82 | * EXPORT scarr = itab TO DATABASE demo_indx_blob(sc) ID 'DEMO'.
83 | * IMPORT scarr = itab FROM DATABASE demo_indx_blob(sc) ID 'DEMO'.
84 |
85 | * EXEC
86 | * SQL
87 | * .
88 | * COMMIT WORK.
89 | * ENDEXEC.
90 |
91 | DATA from_id TYPE /cc4a/testflight-carrid VALUE 'AA'.
92 | DATA to_id TYPE /cc4a/testflight-carrid VALUE 'UA'.
93 | WITH
94 | +connections AS (
95 | SELECT /cc4a/testflight~carrid, /cc4a/testflight~planetype, /cc4a/tstflight1~connid
96 | FROM /cc4a/testflight
97 | INNER JOIN /cc4a/tstflight1
98 | ON /cc4a/tstflight1~carrid = /cc4a/testflight~carrid
99 | WHERE /cc4a/testflight~carrid BETWEEN @from_id AND @to_id ),
100 | +sum_seats AS (
101 | SELECT carrid, connid, SUM( quantity ) AS sum_seats
102 | FROM /cc4a/tstflight1
103 | WHERE carrid BETWEEN @from_id AND @to_id
104 | GROUP BY carrid, connid ),
105 | +result( name, connection, departure ) AS (
106 | SELECT planetype, c~connid, sum_seats
107 | FROM +connections AS c
108 | INNER JOIN +sum_seats AS s
109 | ON c~carrid = s~carrid AND
110 | c~connid = s~connid )
111 | SELECT *
112 | FROM +result
113 | ORDER BY name, connection
114 | INTO TABLE @DATA(result).
115 |
116 | ENDMETHOD.
117 |
118 |
119 | METHOD no_db.
120 | DATA: itab TYPE TABLE OF /cc4a/db_test1,
121 | entry TYPE /cc4a/db_test1,
122 | include TYPE TABLE OF string,
123 | * texts TYPE TABLE OF textpool,
124 | * report TYPE t100,
125 | where TYPE string,
126 | itab2 TYPE TABLE OF /cc4a/db_test1.
127 |
128 | INSERT entry INTO TABLE itab.
129 | LOOP AT itab INTO entry.
130 | INSERT entry INTO itab.
131 | ENDLOOP.
132 | DELETE itab INDEX 1.
133 | * MODIFY CURRENT LINE.
134 | * INSERT REPORT sy-repid FROM include.
135 | * DELETE REPORT sy-repid.
136 | DELETE ADJACENT DUPLICATES FROM itab.
137 | * INSERT TEXTPOOL sy-repid LANGUAGE sy-langu FROM texts.
138 | * DELETE TEXTPOOL sy-repid LANGUAGE sy-langu.
139 | DELETE TABLE itab FROM entry.
140 | DELETE itab FROM 5.
141 | DELETE itab TO 7.
142 | DELETE itab WHERE pgmid = 'R3TR'.
143 | DELETE itab WHERE (where).
144 | INSERT entry INTO TABLE itab.
145 | INSERT entry INTO itab INDEX 5.
146 | ENDMETHOD.
147 | ENDCLASS.
148 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#avoid_default_key.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 | class test definition final for testing
2 | duration short
3 | risk level harmless.
4 |
5 | private section.
6 | constants test_class type c length 30 value '/CC4A/TEST_AVOID_DEFAULT_KEY'.
7 | constants:
8 | begin of test_class_methods,
9 | with_pseudo_comments type c length 30 value 'WITH_PSEUDO_COMMENTS',
10 | without_pseudo_comments type c length 30 value 'WITHOUT_PSEUDO_COMMENTS',
11 | static_findings type c length 30 value 'STATIC_FINDINGS',
12 | end of test_class_methods.
13 |
14 | methods execute_test_class for testing raising cx_static_check.
15 | endclass.
16 |
17 | class test implementation.
18 |
19 | method execute_test_class.
20 |
21 | data(psuedo_comment_1) = value if_ci_atc_check=>ty_location(
22 | object = cl_ci_atc_unit_driver=>get_class_section_object(
23 | value #( class = test_class kind = cl_ci_atc_unit_driver=>class_section_kind-private ) )
24 | position = value #( line = 14 column = 4 ) ).
25 | data(psuedo_comment_2) = value if_ci_atc_check=>ty_location(
26 | object = cl_ci_atc_unit_driver=>get_method_object(
27 | value #( class = test_class method = test_class_methods-with_pseudo_comments ) )
28 | position = value #( line = 4 column = 4 ) ).
29 | data(psuedo_comment_3) = value if_ci_atc_check=>ty_location(
30 | object = cl_ci_atc_unit_driver=>get_method_object(
31 | value #( class = test_class method = test_class_methods-with_pseudo_comments ) )
32 | position = value #( line = 8 column = 4 ) ).
33 | data(finding_1) = value if_ci_atc_check=>ty_location(
34 | object = cl_ci_atc_unit_driver=>get_class_section_object(
35 | value #( class = test_class kind = cl_ci_atc_unit_driver=>class_section_kind-private ) )
36 | position = value #( line = 12 column = 4 ) ).
37 | data(finding_2) = value if_ci_atc_check=>ty_location(
38 | object = cl_ci_atc_unit_driver=>get_method_object(
39 | value #( class = test_class method = test_class_methods-without_pseudo_comments ) )
40 | position = value #( line = 4 column = 4 ) ).
41 | data(finding_3) = value if_ci_atc_check=>ty_location(
42 | object = cl_ci_atc_unit_driver=>get_method_object(
43 | value #( class = test_class method = test_class_methods-without_pseudo_comments ) )
44 | position = value #( line = 8 column = 4 ) ).
45 | data(static_finding_1) = value if_ci_atc_check=>ty_location(
46 | object = cl_ci_atc_unit_driver=>get_method_object(
47 | value #( class = test_class method = test_class_methods-static_findings ) )
48 | position = value #( line = 2 column = 4 ) ).
49 | data(static_finding_2) = value if_ci_atc_check=>ty_location(
50 | object = cl_ci_atc_unit_driver=>get_method_object(
51 | value #( class = test_class method = test_class_methods-static_findings ) )
52 | position = value #( line = 3 column = 4 ) ).
53 |
54 | cl_ci_atc_unit_driver=>create_asserter( )->check_and_assert(
55 | check = new /cc4a/avoid_default_key( )
56 | object = value #( type = 'CLAS' name = test_class )
57 | expected_findings = value #(
58 | ( code = /cc4a/avoid_default_key=>finding_codes-default_key
59 | location = psuedo_comment_1
60 | quickfixes = value #( (
61 | quickfix_code = /cc4a/avoid_default_key=>quickfix_codes-empty_key
62 | location = psuedo_comment_1
63 | code = value #(
64 | ( `CLASS-DATA GHI TYPE TABLE OF TY_STRUCT WITH EMPTY KEY .` ) ) ) ) )
65 | ( code = /cc4a/avoid_default_key=>finding_codes-default_key
66 | location = psuedo_comment_2
67 | quickfixes = value #( (
68 | quickfix_code = /cc4a/avoid_default_key=>quickfix_codes-empty_key
69 | location = psuedo_comment_2
70 | code = value #(
71 | ( `DATA STU TYPE TABLE OF TY_STRUCT WITH EMPTY KEY .` ) ) ) ) )
72 | ( code = /cc4a/avoid_default_key=>finding_codes-default_key
73 | location = psuedo_comment_3 )
74 | ( code = /cc4a/avoid_default_key=>finding_codes-default_key
75 | location = finding_1
76 | quickfixes = value #( (
77 | quickfix_code = /cc4a/avoid_default_key=>quickfix_codes-empty_key
78 | location = finding_1
79 | code = value #(
80 | ( `CLASS-DATA ABC TYPE TABLE OF TY_STRUCT WITH EMPTY KEY .` ) ) ) ) )
81 | ( code = /cc4a/avoid_default_key=>finding_codes-default_key
82 | location = finding_2
83 | quickfixes = value #( (
84 | quickfix_code = /cc4a/avoid_default_key=>quickfix_codes-empty_key
85 | location = finding_2
86 | code = value #(
87 | ( `DATA STU TYPE TABLE OF TY_STRUCT WITH EMPTY KEY .` ) ) ) ) )
88 | ( code = /cc4a/avoid_default_key=>finding_codes-default_key
89 | location = finding_3 )
90 | ( code = /cc4a/avoid_default_key=>finding_codes-default_key
91 | location = static_finding_1
92 | quickfixes = value #( (
93 | quickfix_code = /cc4a/avoid_default_key=>quickfix_codes-empty_key
94 | location = static_finding_1
95 | code = value #(
96 | ( `STATICS MEMO TYPE STANDARD TABLE OF STRING WITH EMPTY KEY .` ) ) ) ) )
97 | ( code = /cc4a/avoid_default_key=>finding_codes-default_key
98 | location = static_finding_2
99 | quickfixes = value #( (
100 | quickfix_code = /cc4a/avoid_default_key=>quickfix_codes-empty_key
101 | location = static_finding_2
102 | code = value #(
103 | ( `STATICS MAMO TYPE STANDARD TABLE OF STRING WITH EMPTY KEY .` ) ) ) ) ) )
104 | asserter_config = value #( quickfixes = abap_false ) ).
105 |
106 | endmethod.
107 | endclass.
108 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, caste, color, religion, or sexual
10 | identity and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the overall
26 | community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or advances of
31 | any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email address,
35 | without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | [INSERT CONTACT METHOD].
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series of
86 | actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or permanent
93 | ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within the
113 | community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.1, available at
119 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
120 |
121 | Community Impact Guidelines were inspired by
122 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
123 |
124 | For answers to common questions about this code of conduct, see the FAQ at
125 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
126 | [https://www.contributor-covenant.org/translations][translations].
127 |
128 | [homepage]: https://www.contributor-covenant.org
129 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
130 | [Mozilla CoC]: https://github.com/mozilla/diversity
131 | [FAQ]: https://www.contributor-covenant.org/faq
132 | [translations]: https://www.contributor-covenant.org/translations
133 |
--------------------------------------------------------------------------------
/src/checks/#cc4a#equals_sign_chaining.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/equals_sign_chaining definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | interfaces if_ci_atc_check.
8 |
9 | constants:
10 | begin of finding_codes,
11 | equals_sign_chaining type if_ci_atc_check=>ty_finding_code value 'EQ_CHAIN',
12 | end of finding_codes.
13 | constants:
14 | begin of pseudo_comments,
15 | eqals_sign_chaining type string value 'EQUALS_CHAINING',
16 | end of pseudo_comments.
17 | constants:
18 | begin of quickfix_codes,
19 | break_chain type cl_ci_atc_quickfixes=>ty_quickfix_code value 'BRK_CHAIN',
20 | end of quickfix_codes.
21 | methods constructor.
22 |
23 | protected section.
24 | private section.
25 | types:
26 | begin of ty_qf_data,
27 | replacement type if_ci_atc_quickfix=>ty_code,
28 | insert_after type if_ci_atc_quickfix=>ty_code,
29 | token_tabix_last_eq_sign type i,
30 | end of ty_qf_data.
31 |
32 | data code_provider type ref to if_ci_atc_source_code_provider.
33 | data assistant_factory type ref to cl_ci_atc_assistant_factory.
34 | data meta_data type ref to /cc4a/if_check_meta_data.
35 |
36 | methods calculate_quickfix_data importing statement type if_ci_atc_source_code_provider=>ty_statement
37 | returning value(qf_data) type ty_qf_data.
38 |
39 | ENDCLASS.
40 |
41 |
42 |
43 | CLASS /CC4A/EQUALS_SIGN_CHAINING IMPLEMENTATION.
44 |
45 |
46 | method calculate_quickfix_data.
47 | data(line_offset) = statement-tokens[ 1 ]-position-column.
48 |
49 | " Find last relevant equal sign of statement
50 | loop at statement-tokens assigning field-symbol().
51 |
52 | if sy-tabix mod 2 <> 0.
53 | continue.
54 | else.
55 | if -lexeme <> '='.
56 | exit.
57 | endif.
58 | qf_data-token_tabix_last_eq_sign = sy-tabix.
59 | endif.
60 |
61 | endloop.
62 |
63 | " Calculate replacement code
64 | data(line_of_code) = |{ statement-tokens[ qf_data-token_tabix_last_eq_sign - 1 ]-lexeme } = |.
65 | insert line_of_code into table qf_data-replacement.
66 |
67 | " Calculate insert after code
68 | data(token_tabix) = qf_data-token_tabix_last_eq_sign.
69 | clear line_of_code.
70 | data(offset) = |{ '' width = line_offset pad = ` ` }|.
71 | do ( qf_data-token_tabix_last_eq_sign / 2 ) - 1 times.
72 | token_tabix -= 2.
73 | line_of_code =
74 | |{ offset }{ statement-tokens[ token_tabix - 1 ]-lexeme } = { statement-tokens[ token_tabix + 1 ]-lexeme }.|.
75 | insert line_of_code into table qf_data-insert_after.
76 | enddo.
77 |
78 | endmethod.
79 |
80 |
81 | method if_ci_atc_check~get_meta_data.
82 |
83 | meta_data = me->meta_data.
84 |
85 | endmethod.
86 |
87 | method constructor.
88 | meta_data = /cc4a/check_meta_data=>create( value #(
89 | checked_types = /cc4a/check_meta_data=>checked_types-abap_programs
90 | description = 'Assignment Chaining'(des)
91 | finding_codes = value #( (
92 | code = finding_codes-equals_sign_chaining
93 | pseudo_comment = pseudo_comments-eqals_sign_chaining
94 | text = 'Values are allocated more than once within one statement'(mc1) ) )
95 | quickfix_codes = value #( (
96 | code = quickfix_codes-break_chain
97 | short_text = 'Break assignment chain into multiple rows'(q1s) ) )
98 | remote_enablement = /cc4a/check_meta_data=>remote_enablement-unconditional ) ).
99 | endmethod.
100 |
101 |
102 | method if_ci_atc_check~run.
103 |
104 | code_provider = data_provider->get_code_provider( ).
105 | data(procedures) = code_provider->get_procedures( code_provider->object_to_comp_unit( object = object ) ).
106 |
107 | loop at procedures->* assigning field-symbol().
108 |
109 | " Access with primary key needed to receive correct sy-tabix in loop
110 | loop at -statements assigning field-symbol() where keyword = 'COMPUTE' ##PRIMKEY[KEYWORD].
111 |
112 | data(nr_of_tokens) = lines( -tokens ).
113 | check nr_of_tokens > 3.
114 | if -tokens[ 2 ]-lexeme = '=' and -tokens[ 4 ]-lexeme = '='.
115 |
116 | " Create quickfix BRK_CHAIN
117 | data(qf_data) = calculate_quickfix_data( ).
118 | data(quickfixes) = assistant_factory->create_quickfixes( ).
119 | data(quickfix_1) = quickfixes->create_quickfix( quickfix_codes-break_chain ).
120 | quickfix_1->replace( context = assistant_factory->create_quickfix_context(
121 | value #(
122 | procedure_id = -id
123 | statements = value #( from = sy-tabix to = sy-tabix )
124 | tokens = value #( from = 1 to = qf_data-token_tabix_last_eq_sign ) ) )
125 | code = qf_data-replacement ).
126 | quickfix_1->insert_after(
127 | context = assistant_factory->create_quickfix_context( value #(
128 | procedure_id = -id
129 | statements = value #( from = sy-tabix to = sy-tabix ) ) )
130 | code = qf_data-insert_after ).
131 |
132 | insert value #(
133 | code = finding_codes-equals_sign_chaining
134 | location = code_provider->get_statement_location( )
135 | checksum = code_provider->get_statement_checksum( )
136 | has_pseudo_comment = meta_data->has_valid_pseudo_comment(
137 | statement =
138 | finding_code = finding_codes-equals_sign_chaining )
139 | details = assistant_factory->create_finding_details( )->attach_quickfixes( quickfixes )
140 | ) into table findings.
141 | endif.
142 |
143 | endloop.
144 |
145 | endloop.
146 |
147 | endmethod.
148 |
149 |
150 | method if_ci_atc_check~set_assistant_factory.
151 |
152 | assistant_factory = factory.
153 |
154 | endmethod.
155 |
156 |
157 | method if_ci_atc_check~verify_prerequisites.
158 |
159 | " Nothing to check
160 |
161 | endmethod.
162 | ENDCLASS.
163 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_scope_of_variable.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_scope_of_variable definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | methods test1.
8 | methods test2.
9 | methods test3.
10 | methods test4.
11 | methods test5.
12 | methods test6.
13 | methods test7.
14 | methods test8.
15 | methods test9.
16 | methods test10.
17 | methods test11.
18 | protected section.
19 | private section.
20 | types ty_char2 type c length 2.
21 | methods my_method1
22 | importing val type ty_char2
23 | num type i
24 | lexeme type string.
25 | methods my_method2
26 | importing par_1 type i
27 | exporting par_2 type i.
28 | endclass.
29 |
30 |
31 |
32 | class /cc4a/test_scope_of_variable implementation.
33 | method test1.
34 | data(a) = 14.
35 | if 1 = 2.
36 | data(var1) = 5.
37 | else.
38 | var1 = 6.
39 | endif.
40 | endmethod.
41 | method test2.
42 | do.
43 | case sy-subrc.
44 | when 0.
45 | data(var2) = 'blabla'.
46 | when 1.
47 | var2 = 'x'.
48 | data(varx) = 15.
49 | when 15.
50 | varx += 1.
51 | endcase.
52 | if 1 = 2.
53 | var2 += 1.
54 | endif.
55 | enddo.
56 | varx += 1.
57 | endmethod.
58 | method test3.
59 | if 1 = 2.
60 | data(new) = 'hallo'.
61 | else.
62 | data(var) = 15.
63 | if sy-subrc = 0.
64 | var += 1.
65 | else.
66 | data(bla) = var + 1.
67 | endif.
68 | endif.
69 | endmethod.
70 | method test4.
71 | types: ty_range type range of i.
72 | data itab type table of string.
73 | data itab1 type table of string.
74 | if sy-subrc = 0.
75 | data(var) = value ty_range( for in itab ( low = sign = 'I' option = 'EQ' ) ).
76 | else.
77 | var = value ty_range( for in itab1 ( low = sign = 'I' option = 'EQ' ) ).
78 | endif.
79 | if sy-subrc = 0.
80 | field-symbols type string.
81 | assign `blabla` to .
82 | else.
83 | assign `blub` to .
84 | endif.
85 | if 1 = 2.
86 | data(test) = value #( itab1[ 1 ] ).
87 | else.
88 | test = `blabla`.
89 | endif.
90 | endmethod.
91 | method test5.
92 | data number type i.
93 | case number.
94 | when 1.
95 | if sy-subrc = 0.
96 | data(condition) = ` AND `.
97 | else.
98 | condition = ` OR `.
99 | endif.
100 | data(new) = condition.
101 | when 2.
102 | data(result) = 0.
103 | endcase.
104 | endmethod.
105 | method test6.
106 | case sy-subrc.
107 | when 1.
108 | if sy-subrc = 0.
109 | types t_itab type standard table of string with default key.
110 | data itab type t_itab.
111 | data condition type ref to t_itab.
112 | data condition1 like ref to itab.
113 | data flag.
114 | else.
115 | loop at condition->* assigning field-symbol().
116 | endloop.
117 | if is initial or condition1 is initial.
118 | endif.
119 | endif.
120 | when 2.
121 | types: begin of t_test,
122 | a type i,
123 | b type i,
124 | end of t_test.
125 | field-symbols type t_test.
126 | flag = 'a'.
127 | endcase.
128 | data test type t_test.
129 | assign test to .
130 | endmethod.
131 | method test7.
132 | if sy-subrc = 0.
133 | data: begin of line,
134 | format type i,
135 | text type string,
136 | end of line.
137 | clear line.
138 | else.
139 | data(new) = line.
140 | line-format = 15.
141 | line-text = 'blabla'.
142 | endif.
143 | endmethod.
144 | method test8.
145 | types: begin of t_line,
146 | val(2) type c,
147 | num type i,
148 | end of t_line.
149 | data itab type standard table of t_line.
150 | data num type i.
151 | if sy-subrc = 0.
152 | data(entry) = itab[ val = `a` && `b` ].
153 | data(idx) = line_index( itab[ val = `a` && `b` ] ).
154 | data(test) = 'ab'.
155 | data(test_string) = | blabla { test }|.
156 | else.
157 | data(new) = entry.
158 | my_method1( val = test num = idx lexeme = test_string ).
159 | endif.
160 | endmethod.
161 |
162 | method test9.
163 | data itab type standard table of i.
164 | data number type i.
165 | data data(30) type c.
166 | if sy-subrc = 0.
167 | data a(1) value 'F'.
168 | data b type string value `blabla`.
169 | data c value 0 like sy-tabix.
170 | data(2) = 'AB'.
171 | data: begin of d,
172 | one type string,
173 | two type string,
174 | end of d.
175 | data: begin of d_1,
176 | a type i,
177 | begin of d_2,
178 | x type i,
179 | y type i,
180 | end of d_2,
181 | end of d_1.
182 | else.
183 | a = 'B'.
184 | data(new) = |{ b }1|.
185 | c += 1.
186 | data(3) = 'ABC'.
187 | data(new1) = d_1.
188 | d-one = `blabla`.
189 | endif.
190 | if number > 1.
191 | number = lines( itab ). "COMPUTE number = lines( itab ).
192 | else.
193 | number = 5.
194 | endif.
195 |
196 | endmethod.
197 | method test10.
198 | data var_1 type i.
199 | data itab type table of i.
200 | if var_1 = 2.
201 | data(var_2) = var_1.
202 | my_method2( exporting par_1 = var_2 importing par_2 = data(var_3) ).
203 | select from i_custabapobjdirectoryentry fields * into table @data(var_4).
204 | read table itab index 5 assigning field-symbol().
205 | else.
206 | var_2 = 3.
207 | var_3 = 3.
208 | select from i_custabapobjdirectoryentry fields * into table @var_4.
209 | = 13.
210 | endif.
211 | endmethod.
212 | method test11.
213 | select * from i_custabapobjdirectoryentry into @data(stuff).
214 | data(var_1) = stuff-abapobjectresponsibleuser.
215 | endselect.
216 | data(var_2) = stuff-abapobjectresponsibleuser.
217 | var_2 = var_1.
218 | endmethod.
219 | method my_method1.
220 |
221 | endmethod.
222 | method my_method2.
223 | endmethod.
224 | endclass.
225 |
--------------------------------------------------------------------------------
/src/test_objects/#cc4a#test_chain_declaration.clas.abap:
--------------------------------------------------------------------------------
1 | class /cc4a/test_chain_declaration definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 | protected section.
8 | private section.
9 | class-methods test_statics.
10 | methods without_pseudo_comments.
11 | methods with_pseudo_comments.
12 |
13 | constants: q type i value 0, w type i value 0. "#EC CHAIN_DECL_USAG
14 |
15 | constants: begin of ty_constants,
16 | first type i value 0,
17 | second type i value 0,
18 | end of ty_constants.
19 |
20 | class-data: begin of ty_class_data,
21 | abcde type i,
22 | abcd type i,
23 | end of ty_class_data.
24 |
25 | class-data: o type i,
26 | p type i.
27 |
28 | data: asd type d, fdg type d.
29 | ENDCLASS.
30 |
31 |
32 |
33 | CLASS /CC4A/TEST_CHAIN_DECLARATION IMPLEMENTATION.
34 |
35 |
36 | method test_statics.
37 | statics: third type i,
38 | fourth type i.
39 |
40 | statics: dsgz type i, asg type i. "#EC CHAIN_DECL_USAG
41 |
42 | statics: begin of ty_statics,
43 | kelvin type i,
44 | watt type i,
45 | end of ty_statics.
46 | endmethod.
47 |
48 |
49 | method without_pseudo_comments.
50 | data: z type i, k type i, b type i, d type i.
51 |
52 | types: begin of ty_types,
53 | type1 type i,
54 | type2 type i,
55 | end of ty_types.
56 |
57 | types ty_type1 type ty_types.
58 |
59 | types: ty_type2 type ty_types,
60 | ty_type3 type ty_types.
61 |
62 | types: ty_type11 type ty_types.
63 |
64 | types:
65 | ty_exemptions type standard table of string with empty key,
66 | begin of ty_object_with_exemptions,
67 | begin of key,
68 | obj_name type c length 40,
69 | obj_type type c length 4,
70 | end of key,
71 | end of ty_object_with_exemptions,
72 | begin of current_dlvunit_t,
73 | dlvunit type ty_types,
74 | range type range of ty_type1,
75 | end of current_dlvunit_t,
76 | begin of current_chkid_t,
77 | module_id type ty_type11,
78 | chkid type ty_type3,
79 | range type range of ty_type1,
80 | exemption_granularity type ty_object_with_exemptions-key-obj_type,
81 | check_is_unknown type abap_bool,
82 | end of current_chkid_t,
83 | begin of current_chkmsgid_t,
84 | chkmsgid type xstring,
85 | range type range of xstring,
86 | end of current_chkmsgid_t.
87 |
88 | constants:
89 | begin of c_cfg_param2,
90 | display_load type ty_object_with_exemptions-key-obj_name value 'DISPLAY_LOAD',
91 | object_provider_id type ty_object_with_exemptions-key-obj_name value 'OBJECT_PROVIDER',
92 | restart_memento type ty_object_with_exemptions-key-obj_name value 'RESTART_MEMENTO',
93 | worklist_id type ty_object_with_exemptions-key-obj_name value 'WORKLIST_ID',
94 | end of c_cfg_param2,
95 | c_module_id2 type xstring value '005056A7004E1EE682F6E8FEE661C090'.
96 | endmethod.
97 |
98 |
99 | method with_pseudo_comments.
100 | data: q type i, "#EC CHAIN_DECL_USAG
101 | w type i,
102 | e type i,
103 | r type i.
104 | types: begin of ty_types,
105 | type1 type i,
106 | type2 type i,
107 | end of ty_types.
108 |
109 | types: ty_type10 type ty_types, "#EC CHAIN_DECL_USAG
110 | ty_type13 type ty_types.
111 |
112 | types: ty_type11 type ty_types.
113 |
114 | types: begin of ty_structure,
115 | a type string,
116 | b type string,
117 | c type string,
118 | end of ty_structure.
119 |
120 | types: begin of st_out.
121 | types: begin of sadasd,
122 | sts_chg type ty_structure,
123 | lock_exs type c length 2,
124 | status type ty_type10,
125 | sub_status type ty_type13,
126 | msgguid type ty_type10.
127 | include type ty_structure.
128 | types end of sadasd.
129 | types:
130 | create_date type ty_types,
131 | create_time type ty_structure.
132 | types: end of st_out.
133 |
134 | constants: "#EC CHAIN_DECL_USAG
135 | begin of c_cfg_param,
136 | display_load type c length 40 value 'DISPLAY_LOAD',
137 | object_provider_id type c length 40 value 'OBJECT_PROVIDER',
138 | restart_memento type c length 40 value 'RESTART_MEMENTO',
139 | worklist_id type c length 40 value 'WORKLIST_ID',
140 | end of c_cfg_param,
141 |
142 | begin of c_set_param,
143 | object type c length 40 value 'OBJECT',
144 | failure type c length 40 value 'FAILURE',
145 | gen_failure type c length 40 value 'GEN_FAILURE',
146 | finding type c length 40 value 'FINDING',
147 | object_context type c length 40 value 'OBJCTX',
148 | dyntest_object type c length 40 value 'DYNTEST_OBJECT',
149 | end of c_set_param.
150 |
151 | data(asd) = c_cfg_param-display_load.
152 |
153 | types: "#EC CHAIN_DECL_USAG
154 | ty_exemptions type standard table of string with empty key,
155 | begin of ty_object_with_exemptions,
156 | begin of key,
157 | obj_type type c length 4,
158 | obj_name type c length 40,
159 | end of key,
160 | end of ty_object_with_exemptions,
161 | begin of current_dlvunit_t,
162 | dlvunit type ty_type10,
163 | range type range of ty_type10,
164 | end of current_dlvunit_t,
165 | begin of current_chkid_t,
166 | module_id type xstring,
167 | chkid type xstring,
168 | range type range of ty_type10,
169 | exemption_granularity type ty_object_with_exemptions-key,
170 | check_is_unknown type abap_bool,
171 | end of current_chkid_t,
172 | begin of current_chkmsgid_t,
173 | chkmsgid type xstring,
174 | range type range of xstring,
175 | end of current_chkmsgid_t.
176 | endmethod.
177 | ENDCLASS.
178 |
--------------------------------------------------------------------------------