├── LICENSE ├── README.md ├── autocompletion.png ├── configs ├── clean │ └── abaplint.json └── full │ └── abaplint.json └── rules.md /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # abaplint-clean-code 2 | 3 | Abaplint rule overview and definitions according to ABAP clean code guidelines and best practices. 4 | 5 | [Clean config](./configs/clean/abaplint.json) - rules are picked in an attempt to match the Clean ABAP styleguide. 6 | 7 | [Full config](./configs/full/abaplint.json) - example of config with every rule included 8 | 9 | Rule documentation can be found on https://rules.abaplint.org/. 10 | 11 | You can also find about the list of rules interactively by editing your `abaplint.json` using vscode. The [abaplint](https://marketplace.visualstudio.com/items?itemName=larshp.vscode-abaplint) plugin provides validation and autocompletion according to the [schema](https://schema.abaplint.org/schema.json) which is generated automatically from docstrings in the code. 12 | 13 | ![vscode schema autocomplete](./autocompletion.png) 14 | 15 | ## about abaplint 16 | 17 | abaplint is an open source reimplementation of the ABAP parser written in Typescript. It works without a SAP system and is meant to be used on code serialized using abapGit. It is meant to be used in addition to, not instead of other checks such as ATC. 18 | 19 | Make sure to visit https://github.com/abaplint/abaplint for more information about how to get it running and https://abaplint.org/ for some cool stuff like statistics of open source ABAP projects, an interactive abaplint playground or diagrams of ABAP syntax. 20 | -------------------------------------------------------------------------------- /autocompletion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreHu/abaplint-clean-code/c8a74671a1de725b855c93e26d80a4e107944726/autocompletion.png -------------------------------------------------------------------------------- /configs/clean/abaplint.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "files": "/src/**/*.*", 4 | "skipGeneratedGatewayClasses": true, 5 | "skipGeneratedPersistentClasses": true, 6 | "skipGeneratedFunctionGroups": true 7 | }, 8 | "syntax": { 9 | "version": "v753", 10 | "errorNamespace": "", 11 | "globalConstants": [], 12 | "globalMacros": [] 13 | }, 14 | "dependencies": [ 15 | { 16 | "url": "https://github.com/abaplint/deps", 17 | "folder": "/deps", 18 | "files": "/src/**/*.*" 19 | } 20 | ], 21 | "rules": { 22 | "avoid_use": { 23 | "define": true, 24 | "endselect": true, 25 | "execSQL": true, 26 | "kernelCall": true, 27 | "communication": true, 28 | "statics": true, 29 | "systemCall": true, 30 | "break": true, 31 | "defaultKey": true 32 | }, 33 | "commented_code": true, 34 | "constructor_visibility_public": true, 35 | "description_empty": true, 36 | "empty_statement": true, 37 | "empty_structure": { 38 | "loop": true, 39 | "if": true, 40 | "while": true, 41 | "case": true, 42 | "select": true, 43 | "do": true, 44 | "at": true, 45 | "try": true 46 | }, 47 | "exporting": true, 48 | "functional_writing": { 49 | "ignoreExceptions": true 50 | }, 51 | "global_class": true, 52 | "identical_form_names": true, 53 | "if_in_if": true, 54 | "inline_data_old_versions": true, 55 | "line_length": { 56 | "length": 120 57 | }, 58 | "max_one_statement": true, 59 | "message_exists": true, 60 | "method_length": { 61 | "statements": 25, 62 | "ignoreTestClasses": false, 63 | "errorWhenEmpty": true 64 | }, 65 | "mix_returning": true, 66 | "msag_consistency": true, 67 | "nesting": { 68 | "depth": 5 69 | }, 70 | "obsolete_statement": { 71 | "refresh": true, 72 | "compute": true, 73 | "add": true, 74 | "subtract": true, 75 | "multiply": true, 76 | "move": true, 77 | "divide": true, 78 | "requested": true, 79 | "occurs": true, 80 | "setExtended": true, 81 | "withHeaderLine": true, 82 | "fieldSymbolStructure": true 83 | }, 84 | "parser_error": true, 85 | "preferred_compare_operator": { 86 | "badOperators": [ 87 | "EQ", 88 | "NE", 89 | "GE", 90 | "GT", 91 | "LT", 92 | "LE" 93 | ] 94 | }, 95 | "short_case": { 96 | "length": 1, 97 | "allow": [] 98 | }, 99 | "superclass_final": true, 100 | "unreachable_code": true, 101 | "use_new": true, 102 | "when_others_last": true, 103 | "ambiguous_statement": true, 104 | "begin_end_names": true, 105 | "check_transformation_exists": true, 106 | "check_syntax": true, 107 | "form_tables_obsolete": true, 108 | "tabl_enhancement_category": true, 109 | "implement_methods": true, 110 | "local_testclass_location": true, 111 | "main_file_contents": true, 112 | "rfc_error_handling": true, 113 | "indentation": { 114 | "alignTryCatch": false, 115 | "ignoreExceptions": false, 116 | "globalClassSkipFirst": false, 117 | "ignoreGlobalClassDefinition": false, 118 | "ignoreGlobalInterface": false 119 | }, 120 | "sequential_blank": { 121 | "lines": 3 122 | }, 123 | "empty_line_in_statement": { 124 | "allowChained": true 125 | }, 126 | "check_abstract": true, 127 | "no_public_attributes": { 128 | "allowReadOnly": true 129 | }, 130 | "abapdoc": true, 131 | "prefer_returning_to_exporting": true, 132 | "keep_single_parameter_on_one_line": { 133 | "length": 120 134 | }, 135 | "allowed_object_naming": true, 136 | "fully_type_constants": true, 137 | "check_comments": { 138 | "allowEndOfLine": true 139 | }, 140 | "check_text_elements": true, 141 | "newline_between_methods": { 142 | "logic": "less", 143 | "count": 3 144 | }, 145 | "check_include": true, 146 | "xml_consistency": true, 147 | "prefix_is_current_class": { 148 | "omitMeInstanceCalls": true 149 | }, 150 | "check_no_handler_pragma": true, 151 | "line_break_multiple_parameters": true, 152 | "prefer_inline": true, 153 | "reduce_string_templates": true, 154 | "sicf_consistency": true, 155 | "sql_escape_host_variables": true, 156 | "try_without_catch": true, 157 | "names_no_dash": true, 158 | "unknown_types": true, 159 | "unused_variables": true, 160 | "unused_types": true, 161 | "use_bool_expression": true, 162 | "use_line_exists": true, 163 | "check_subrc": true, 164 | "cyclomatic_complexity": { 165 | "max": 6 166 | }, 167 | "parser_missing_space": true, 168 | "identical_conditions": true, 169 | "prefer_is_not": true 170 | } 171 | } -------------------------------------------------------------------------------- /configs/full/abaplint.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "files": "/src/**/*.*", 4 | "skipGeneratedGatewayClasses": true, 5 | "skipGeneratedPersistentClasses": true, 6 | "skipGeneratedFunctionGroups": true 7 | }, 8 | "syntax": { 9 | "version": "v753", 10 | "errorNamespace": "", 11 | "globalConstants": [], 12 | "globalMacros": [] 13 | }, 14 | "dependencies": [ 15 | { 16 | "url": "https://github.com/abaplint/deps", 17 | "folder": "/deps", 18 | "files": "/src/**/*.*" 19 | } 20 | ], 21 | "rules": { 22 | "7bit_ascii": true, 23 | "avoid_use": { 24 | "define": true, 25 | "endselect": true, 26 | "execSQL": true, 27 | "kernelCall": true, 28 | "communication": true, 29 | "statics": true, 30 | "systemCall": true, 31 | "break": true, 32 | "defaultKey": true 33 | }, 34 | "check_syntax": true, 35 | "class_attribute_names": { 36 | "ignoreExceptions": true, 37 | "statics": "^G._.*$", 38 | "instance": "^M._.*$", 39 | "constants": "^C._.*$", 40 | "ignoreLocal": false, 41 | "ignoreInterfaces": false 42 | }, 43 | "cloud_types": true, 44 | "colon_missing_space": true, 45 | "commented_code": true, 46 | "constructor_visibility_public": true, 47 | "contains_tab": true, 48 | "definitions_top": true, 49 | "description_empty": true, 50 | "double_space": { 51 | "keywords": true, 52 | "startParen": true, 53 | "endParen": true, 54 | "afterColon": true 55 | }, 56 | "empty_line_in_statement": { 57 | "allowChained": false 58 | }, 59 | "empty_statement": true, 60 | "empty_structure": { 61 | "loop": true, 62 | "if": true, 63 | "while": true, 64 | "case": true, 65 | "select": true, 66 | "do": true, 67 | "at": true, 68 | "try": true 69 | }, 70 | "exit_or_check": true, 71 | "exporting": true, 72 | "functional_writing": { 73 | "ignoreExceptions": true 74 | }, 75 | "global_class": true, 76 | "identical_form_names": true, 77 | "if_in_if": true, 78 | "in_statement_indentation": { 79 | "ignoreExceptions": true 80 | }, 81 | "indentation": { 82 | "ignoreExceptions": true, 83 | "alignTryCatch": false, 84 | "globalClassSkipFirst": false, 85 | "ignoreGlobalClassDefinition": false, 86 | "ignoreGlobalInterface": false 87 | }, 88 | "inline_data_old_versions": true, 89 | "keyword_case": { 90 | "style": "upper", 91 | "ignoreExceptions": true, 92 | "ignoreLowerClassImplmentationStatement": true, 93 | "ignoreGlobalClassDefinition": false, 94 | "ignoreGlobalInterface": false, 95 | "ignoreFunctionModuleName": false, 96 | "ignoreGlobalClassBoundaries": true, 97 | "ignoreKeywords": [] 98 | }, 99 | "line_length": { 100 | "length": 120 101 | }, 102 | "line_only_punc": { 103 | "ignoreExceptions": true 104 | }, 105 | "local_class_naming": { 106 | "local": "^LCL_.*$", 107 | "test": "^LTCL_.*$", 108 | "exception": "^LCX_.*$" 109 | }, 110 | "local_variable_names": { 111 | "expectedData": "^L._.*$", 112 | "expectedConstant": "^LC_.*$", 113 | "expectedFS": "^$" 114 | }, 115 | "max_one_statement": true, 116 | "message_exists": true, 117 | "method_length": { 118 | "statements": 100, 119 | "ignoreTestClasses": false, 120 | "errorWhenEmpty": true 121 | }, 122 | "method_parameter_names": { 123 | "ignoreExceptions": true, 124 | "importing": "^I._.*$", 125 | "returning": "^R._.*$", 126 | "changing": "^C._.*$", 127 | "exporting": "^E._.*$", 128 | "ignoreNames": [ 129 | "P_TASK" 130 | ] 131 | }, 132 | "mix_returning": true, 133 | "msag_consistency": true, 134 | "nesting": { 135 | "depth": 5 136 | }, 137 | "no_public_attributes": { 138 | "allowReadOnly": true 139 | }, 140 | "object_naming": { 141 | "clas": "^ZC(L|X)\\_", 142 | "intf": "^ZIF\\_", 143 | "prog": "^Z", 144 | "fugr": "^Z", 145 | "tabl": "^Z", 146 | "ttyp": "^Z", 147 | "dtel": "^Z", 148 | "doma": "^Z", 149 | "msag": "^Z", 150 | "tran": "^Z", 151 | "enqu": "^EZ", 152 | "auth": "^Z", 153 | "pinf": "^Z", 154 | "idoc": "^Z", 155 | "xslt": "^Z", 156 | "shlp": "^Z", 157 | "ssfo": "^Z", 158 | "ssst": "^Z" 159 | }, 160 | "obsolete_statement": { 161 | "refresh": true, 162 | "compute": true, 163 | "add": true, 164 | "subtract": true, 165 | "multiply": true, 166 | "move": true, 167 | "divide": true, 168 | "requested": true, 169 | "occurs": true, 170 | "setExtended": true, 171 | "withHeaderLine": true, 172 | "fieldSymbolStructure": true 173 | }, 174 | "parser_error": true, 175 | "preferred_compare_operator": { 176 | "badOperators": [ 177 | "EQ", 178 | "><", 179 | "NE", 180 | "GE", 181 | "GT", 182 | "LT", 183 | "LE" 184 | ] 185 | }, 186 | "remove_descriptions": { 187 | "ignoreExceptions": false, 188 | "ignoreWorkflow": true 189 | }, 190 | "sequential_blank": { 191 | "lines": 4 192 | }, 193 | "short_case": { 194 | "length": 1, 195 | "allow": [] 196 | }, 197 | "space_before_colon": true, 198 | "space_before_dot": { 199 | "ignoreGlobalDefinition": true, 200 | "ignoreExceptions": true 201 | }, 202 | "start_at_tab": true, 203 | "superclass_final": true, 204 | "tabl_enhancement_category": true, 205 | "unreachable_code": true, 206 | "use_new": true, 207 | "when_others_last": true, 208 | "whitespace_end": true, 209 | "ambiguous_statement": true, 210 | "allowed_object_types": { 211 | "allowed": [ 212 | "PROG", 213 | "CLAS", 214 | "INTF", 215 | "DEVC" 216 | ] 217 | }, 218 | "begin_end_names": true, 219 | "check_transformation_exists": true, 220 | "form_tables_obsolete": true, 221 | "implement_methods": true, 222 | "local_testclass_location": true, 223 | "main_file_contents": true, 224 | "type_form_parameters": true, 225 | "rfc_error_handling": true, 226 | "abapdoc": true, 227 | "release_idoc": true, 228 | "prefer_returning_to_exporting": true, 229 | "keep_single_parameter_on_one_line": { 230 | "length": 120 231 | }, 232 | "allowed_object_naming": true, 233 | "chain_mainly_declarations": true, 234 | "fully_type_constants": true, 235 | "check_abstract": true, 236 | "check_comments": { 237 | "allowEndOfLine": true 238 | }, 239 | "selection_screen_naming": { 240 | "selectOption": "^s_.+$", 241 | "parameter": "^p_.+$", 242 | "patternKind": "required" 243 | }, 244 | "check_text_elements": true, 245 | "check_ddic": true, 246 | "newline_between_methods": { 247 | "logic": "less", 248 | "count": 3 249 | }, 250 | "check_include": true, 251 | "xml_consistency": true, 252 | "prefix_is_current_class": { 253 | "omitMeInstanceCalls": true 254 | }, 255 | "check_no_handler_pragma": true, 256 | "line_break_multiple_parameters": true, 257 | "forbidden_identifier": { 258 | "check": [], 259 | "exclude": [] 260 | }, 261 | "forbidden_void_type": true, 262 | "prefer_inline": true, 263 | "reduce_string_templates": true, 264 | "sicf_consistency": true, 265 | "sql_escape_host_variables": true, 266 | "try_without_catch": true, 267 | "types_naming": { 268 | "pattern": "^T._.*$" 269 | }, 270 | "unknown_types": true, 271 | "unused_variables": true, 272 | "begin_single_include": true, 273 | "check_subrc": true, 274 | "cyclomatic_complexity":{ 275 | "max": 6 276 | }, 277 | "forbidden_pseudo_and_pragma": { 278 | "ignoreGlobalClassDefinition": false, 279 | "ignoreGlobalInterface": false, 280 | "pragmas": ["##NO_TEXT"], 281 | "pseudo": ["#EC NOTEXT"] 282 | }, 283 | "identical_conditions": true, 284 | "line_break_style": true, 285 | "names_no_dash": true, 286 | "parser_missing_space": true, 287 | "prefer_is_not": true, 288 | "unused_types":true, 289 | "use_bool_expression": true, 290 | "use_line_exists": true 291 | } 292 | } -------------------------------------------------------------------------------- /rules.md: -------------------------------------------------------------------------------- 1 | # Rule descriptions 2 | - [Rule descriptions](#rule-descriptions) 3 | - [Code structure](#code-structure) 4 | - [nesting](#nesting) 5 | - [definitions_top](#definitionstop) 6 | - [no_public_attributes](#nopublicattributes) 7 | - [unreachable code](#unreachable-code) 8 | - [when_others_last](#whenotherslast) 9 | - [exit_or_check](#exitorcheck) 10 | - [constructor_visibility_public](#constructorvisibilitypublic) 11 | - [short_case](#shortcase) 12 | - [max_one_statement](#maxonestatement) 13 | - [method_length](#methodlength) 14 | - [if_in_if](#ifinif) 15 | - [line_length](#linelength) 16 | - [prefer_returning_to_exporting](#preferreturningtoexporting) 17 | - [prefix_is_current_class](#prefixiscurrentclass) 18 | - [Documentation](#documentation) 19 | - [abapdoc](#abapdoc) 20 | - [check_comments](#checkcomments) 21 | - [Syntax/object usage](#syntaxobject-usage) 22 | - [obsolete_statement](#obsoletestatement) 23 | - [functional_writing](#functionalwriting) 24 | - [avoid_use](#avoiduse) 25 | - [breakpoint](#breakpoint) 26 | - [use_new](#usenew) 27 | - [preferred_compare_operators](#preferredcompareoperators) 28 | - [mix_returning](#mixreturning) 29 | - [superclass_final](#superclassfinal) 30 | - [cloud_types](#cloudtypes) 31 | - [allowed_object_types](#allowedobjecttypes) 32 | - [inline_data_old_versions](#inlinedataoldversions) 33 | - [form_tables_obsolete](#formtablesobsolete) 34 | - [type_form_parameters](#typeformparameters) 35 | - [chain_mainly_declarations](#chainmainlydeclarations) 36 | - [fully_type_constants](#fullytypeconstants) 37 | - [Redundant code](#redundant-code) 38 | - [commented_code](#commentedcode) 39 | - [empty_structure](#emptystructure) 40 | - [exporting](#exporting) 41 | - [Naming conventions](#naming-conventions) 42 | - [class_attribute_names](#classattributenames) 43 | - [local_class_naming](#localclassnaming) 44 | - [selection_screen_naming](#selectionscreennaming) 45 | - [local_variable_names](#localvariablenames) 46 | - [method_parameter_names](#methodparameternames) 47 | - [object_naming](#objectnaming) 48 | - [form_no_dash](#formnodash) 49 | - [allowed_object_naming](#allowedobjectnaming) 50 | - [Formatting](#formatting) 51 | - [keyword_case](#keywordcase) 52 | - [line_only_punc](#lineonlypunc) 53 | - [colon_missing_space](#colonmissingspace) 54 | - [contains_tab](#containstab) 55 | - [double_space](#doublespace) 56 | - [whitespace_end](#whitespaceend) 57 | - [in_statement_indentation](#instatementindentation) 58 | - [indentation](#indentation) 59 | - [sequential_blank](#sequentialblank) 60 | - [start_at_tab](#startattab) 61 | - [space_before_colon](#spacebeforecolon) 62 | - [space_before_dot](#spacebeforedot) 63 | - [empty_line_in_statement](#emptylineinstatement) 64 | - [empty_statement](#emptystatement) 65 | - [keep_single_parameter_on_one_line](#keepsingleparameterononeline) 66 | - [newline_between_methods](#newlinebetweenmethods) 67 | - [Other](#other) 68 | - [7bit_ascii](#7bitascii) 69 | - [check_syntax](#checksyntax) 70 | - [check_ddic](#checkddic) 71 | - [tabl_enhancement_category](#tablenhancementcategory) 72 | - [ambiguous_statement](#ambiguousstatement) 73 | - [message_exists](#messageexists) 74 | - [identical_form_names](#identicalformnames) 75 | - [msag_consistency](#msagconsistency) 76 | - [parser_error](#parsererror) 77 | - [description_empty](#descriptionempty) 78 | - [remove_descriptions](#removedescriptions) 79 | - [global_class](#globalclass) 80 | - [begin_end_names](#beginendnames) 81 | - [check_transformation_exists](#checktransformationexists) 82 | - [implement_methods](#implementmethods) 83 | - [local_testclass_location](#localtestclasslocation) 84 | - [main_file_contents](#mainfilecontents) 85 | - [rfc_error_handling](#rfcerrorhandling) 86 | - [release_idoc](#releaseidoc) 87 | - [check_abstract](#checkabstract) 88 | - [check_text_elements](#checktextelements) 89 | - [check_include](#checkinclude) 90 | - [xml_consistency](#xmlconsistency) 91 | 92 | ## Code structure 93 | 94 | ### nesting 95 | 96 | Checks for code exceeding a maximum nesting depth. 97 | 98 | An exact maximum is not defined in clean abap, but I believe 5 is used in ATC. Note that in most cases you shouldn't go above 2. 99 | 100 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#keep-the-nesting-depth-low 101 | 102 | Enabled. 103 | 104 | 105 | ### definitions_top 106 | 107 | Enforces that data and field-symbol definitions are on top of the method. While sometimes good for readability, it is an antipattern as variables should be declared inline or close to their first declaration. 108 | 109 | Disabled. 110 | 111 | ### no_public_attributes 112 | 113 | Checks for public attributes. 114 | 115 | Enabled (read-only is allowed). 116 | 117 | ### unreachable code 118 | 119 | Checks for unreachable code - lines after a `RETURN`, `EXIT` or `RAISE`. Raising exceptions might have a few false positives. 120 | 121 | Enabled, please report false positives. 122 | 123 | ### when_others_last 124 | 125 | Checks that `WHEN OTHERS` is the last case of a switch statement. 126 | 127 | Enabled. 128 | 129 | ### exit_or_check 130 | 131 | Checks for `EXIT` and `CHECK` statements outside of loops. There is no consensus on whether you should use CHECK or RETURN to exit a method if the input doesn't meet expectations. 132 | 133 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#check-vs-return 134 | 135 | Disabled. 136 | 137 | ### constructor_visibility_public 138 | 139 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#if-your-global-class-is-create-private-leave-the-constructor-public 140 | 141 | Enabled. 142 | 143 | 144 | ### short_case 145 | 146 | Checks for `case` statements which have fewer than `length` branches. At the very least, you shouldn't have one. 147 | 148 | `todo not sure what allow here does` 149 | 150 | Enabled, default 2. 151 | 152 | ### max_one_statement 153 | 154 | Checks that code only contains one statement per line. 155 | 156 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#no-more-than-one-statement-per-line 157 | 158 | Enabled. 159 | 160 | 161 | ### method_length 162 | 163 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#keep-methods-small says 3-5 statements, which would raise a lot of violations. The number 25 is also used often (fits within one screen), for now I am using it a a sane max limit. 164 | 165 | Can be configured to ignore test classes. 166 | 167 | Also checks for empty methods if `errorWhenEmpty` is set to true. 168 | 169 | Enabled. 170 | 171 | ### if_in_if 172 | 173 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#keep-the-nesting-depth-low 174 | 175 | 176 | ### line_length 177 | 178 | Enabled by default. 120 is the perscribed preferable length: 179 | 180 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#stick-to-a-reasonable-line-length 181 | 182 | ### prefer_returning_to_exporting 183 | 184 | Checks for `exporting` parameters which can be turned into `returning`. 185 | 186 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#prefer-returning-to-exporting 187 | 188 | Enabled. 189 | 190 | ### prefix_is_current_class 191 | 192 | Checks for unnecessary class prefixes, for example 193 | 194 | `zcl_foo=>` does not need to be specified inside of `zcl_foo`. 195 | 196 | The parameter `omitMeInstanceCalls` can be used to allow/prevent usage of `me->` for methods. 197 | 198 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#omit-the-self-reference-me-when-calling-an-instance-method 199 | 200 | ## Documentation 201 | 202 | ### abapdoc 203 | 204 | Require abapdoc comments for public methods and properties. 205 | 206 | ### check_comments 207 | 208 | Can be used to disallow end of line comments using the parameter `allowEndOfLine`. 209 | 210 | ## Syntax/object usage 211 | 212 | ### obsolete_statement 213 | 214 | I think it is the same thing as avoid_use. Includes `refresh`, `compute`, `add`, `subtract`, `multiply`, `move`, `divide`, `requested`. 215 | 216 | Enabled. 217 | 218 | ### functional_writing 219 | 220 | Checks that method calls use the functional `method()` style instead of `CALL METHOD method` if possible. 221 | 222 | Enabled. 223 | 224 | ### avoid_use 225 | 226 | Checks for usage of certain statements. 227 | 228 | Currently supported: 229 | 230 | - define (clean abap rule - no macros) 231 | - endselect 232 | - execSQL 233 | - kernel call 234 | - communication 235 | - statics (probably a clean abap rule) 236 | 237 | Enabled. 238 | 239 | ### breakpoint 240 | 241 | - checks for `BREAK` and `BREAK-POINT` statements. 242 | 243 | Should be part of clean variant, although this check could easily be merged with `avoid_use` 244 | 245 | Enabled. 246 | 247 | ### use_new 248 | 249 | Checks for `CREATE OBJECT` statements. You should replace these with `NEW`. 250 | 251 | Enabled. 252 | 253 | ### preferred_compare_operators 254 | 255 | Checks for usage of the operators listed in `badOperators`. 256 | 257 | Enabled for comparison operators. 258 | 259 | ### mix_returning 260 | 261 | Checks that only one returning/exporting/changing parameter is present per method in total. 262 | 263 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#use-either-returning-or-exporting-or-changing-but-not-a-combination 264 | 265 | Enabled. 266 | 267 | ### superclass_final 268 | 269 | Checks for final classes which are inherited from. This does not pass syntax checks, but possibly makes sense to check in serialized code. 270 | 271 | Enabled. 272 | 273 | ### cloud_types 274 | 275 | Checks for object types incompatible with Cloud ABAP. 276 | 277 | Types that are not 278 | 279 | Class 280 | Interface 281 | MessageClass 282 | Package 283 | Table 284 | TableType 285 | DataDefinition 286 | DataControl 287 | LockObject 288 | Transformation 289 | FunctionGroup 290 | DataElement 291 | Domain 292 | 293 | Are not allowed. 294 | 295 | `TODO make cloud ABAP variant as well` 296 | 297 | ### allowed_object_types 298 | 299 | Allows to specify a whitelist of object types allowed in your package. 300 | 301 | Disabled. 302 | 303 | ### inline_data_old_versions 304 | 305 | Checks for inline data declarations in releases which are unavailable. 306 | 307 | Enabled. 308 | 309 | ### form_tables_obsolete 310 | 311 | Looks for `TABLES` parameters in forms. Usage of both forms and tables parameters is strongly discouraged in clean ABAP. 312 | 313 | Enabled. 314 | 315 | ### type_form_parameters 316 | 317 | Looks for untyped form parameters. Usage of both forms and untyped parameters is strongly discouraged in clean ABAP. 318 | 319 | Enabled. 320 | 321 | ### chain_mainly_declarations 322 | 323 | Restricts the use of chaining to declarations. 324 | 325 | https://docs.abapopenchecks.org/checks/23/ 326 | 327 | ### fully_type_constants 328 | 329 | Checks that constants are fully typed. 330 | 331 | ``` 332 | " incorrectly typed - these are implicitly `type c length 1` 333 | CONSTANTS: tested_name1 VALUE `blah`. 334 | CONSTANTS: tested_name2 VALUE 'blah'. 335 | 336 | CONSTANTS: tested_name3 VALUE 1234. 337 | 338 | " correctly typed 339 | CONSTANTS: tested_name4 type string VALUE 'blah'. 340 | CONSTANTS: tested_name5 type i VALUE 1234. 341 | ``` 342 | 343 | Enabled. 344 | 345 | ## Redundant code 346 | 347 | ### commented_code 348 | 349 | Checks for commented out code. You should not generally leave commented out code so it is good that you are warned about it. 350 | 351 | Enabled. 352 | 353 | ### empty_structure 354 | 355 | Checks for certain empty code blocks. 356 | 357 | Can be extended: 358 | https://github.com/abaplint/abaplint//blob/8d29328ecc5e9c6df44b681504e6dd899abffc84/src/rules/empty_structure.ts#L16 359 | 360 | Enabled. 361 | 362 | ### exporting 363 | 364 | Checks for EXPORTING statements which can be omitted from method calls. 365 | 366 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#omit-the-optional-keyword-exporting 367 | 368 | Enabled. 369 | 370 | ## Naming conventions 371 | 372 | Enables you to enforce a pattern, such as a prefix, for class, member and variable names. 373 | Clean ABAP suggests that you eliminate prefixes, therefore this check is disabled by default. 374 | 375 | ### class_attribute_names 376 | 377 | Class and global variables 378 | 379 | Disabled. 380 | 381 | ### local_class_naming 382 | 383 | Clean ABAP suggests that you eliminate prefixes, but for local classes it is very common. 384 | 385 | This example has prefixes: 386 | https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#call-local-test-classes-by-their-purpose 387 | 388 | For now not enabled. 389 | 390 | ### selection_screen_naming 391 | 392 | Enables you to enforce a pattern, such as a prefix, for selection screen `paramters` and `select-options`. 393 | 394 | Clean ABAP suggests that you eliminate prefixes, therefore this check is disabled by default. 395 | 396 | ### local_variable_names 397 | 398 | Disabled. 399 | 400 | ### method_parameter_names 401 | 402 | Disabled. 403 | 404 | ### object_naming 405 | 406 | Allows to define prefixes for object types. This differs per project. 407 | 408 | Disabled. 409 | 410 | ### form_no_dash 411 | 412 | Checks for a dash `-` in form names. Usage of dashes in names is heavily discouraged. 413 | 414 | Enabled. 415 | 416 | ### allowed_object_naming 417 | 418 | Checks validity of object names (for example invalid characters, max length) 419 | 420 | Enabled. 421 | 422 | ## Formatting 423 | 424 | Warning: 425 | 426 | Enabling some of the formatting checks might lead to a lot of violations, as old editors reformat class headers and pretty printer only fixes most punctuation issues. 427 | Some of them can be draconic to maintain without proper tooling to fix the formatting, which might improve in the future. 428 | 429 | The clean code config enables by default the rules which shouldn't be common enough to cause too many violations. 430 | 431 | Enable more of them yourself according to your preferred conventions. 432 | 433 | ### keyword_case 434 | 435 | Checks that keywords are in a consistent case specified in `style`. Other parameters allow to skip certain parts of code such as class definitions, which can be reformatted by SE80. 436 | 437 | ### line_only_punc 438 | 439 | Checks for lines containing only . or ). 440 | 441 | ### colon_missing_space 442 | 443 | Checks for a missing space after a colon in chained statements. This is good indentation practice. 444 | 445 | Example: 446 | 447 | ```abap 448 | " incorrect 449 | WRITE:`abc`. 450 | 451 | "correct 452 | WRITE: `abc`. 453 | ``` 454 | 455 | ### contains_tab 456 | 457 | Checks for tabs in your code. Enable if you want to enforce usage of spaces. 458 | 459 | ### double_space 460 | 461 | I think this ensures that there is a `single` space after certain keywords and parentheses. This is good indentation practice. 462 | 463 | List of keywords can be extended, see 464 | https://github.com/abaplint/abaplint//blob/ba4c6f8d03eb8d1a31c277d06c9d9cb9e7ad86b8/src/rules/whitespace/double_space.ts#L42 465 | 466 | 467 | ### whitespace_end 468 | 469 | Checks for whitespace at the end of a line. This is good indentation practice, may lead to many errors. 470 | 471 | ### in_statement_indentation 472 | 473 | Checks alignment within block statement declarations which span multiple lines, such as multiple conditions in IF statements. 474 | 475 | Example violation: 476 | ``` abap 477 | IF 1 = 1 AND 478 | 2 = 2. 479 | ENDIF. 480 | ``` 481 | 482 | ### indentation 483 | 484 | Check indentation of nested blocks. Clean code should definitely be well indented. 485 | 486 | Example violation: 487 | 488 | ```abap 489 | IF 1 = 2. 490 | IF 3 = 4. 491 | ENDIF. 492 | ENDIF. 493 | ``` 494 | 495 | Enabled. 496 | 497 | ### sequential_blank 498 | 499 | Checks for multiple successive blank lines in code. The maximium allowed number is configurable. 500 | 501 | Enabled. 502 | 503 | ### start_at_tab 504 | 505 | Ensures code starts at tabstop positions. Enable if you want to enforce tabs. 506 | 507 | ### space_before_colon 508 | 509 | Checks that there are no spaces in front of colons in chained statements. 510 | 511 | Example violation: 512 | `write : 'a'` 513 | 514 | ### space_before_dot 515 | 516 | Checks for spaces before dots like `this .` These are quite common in class definitions generated by SE80. 517 | 518 | ### empty_line_in_statement 519 | 520 | Checks for empty lines in statements. Example violation: 521 | 522 | ```abap 523 | DATA(x) = y 524 | 525 | . 526 | ``` 527 | 528 | The `allowChained` parameter can be used to disable the check in chained statements. 529 | 530 | 531 | This should be a very rare formatting issue. 532 | 533 | Enabled for non-chained statements. 534 | 535 | ### empty_statement 536 | 537 | Checks for empty statements in your code. An empty statement is a single dot `.`. 538 | 539 | This should be a very rare formatting issue. 540 | 541 | Enabled. 542 | 543 | ### keep_single_parameter_on_one_line 544 | 545 | Checks for single parameter method calls which are not in a single line. 546 | 547 | The paramter `length` can be used to suppress the warning for long lines. 548 | 549 | Good example 550 | 551 | ``` 552 | cl_foo=>bar( x = 5 ). 553 | ``` 554 | 555 | Bad example 556 | 557 | ``` 558 | cl_foo=>bar( 559 | x = 5 ). 560 | ``` 561 | 562 | ### newline_between_methods 563 | 564 | Allows to enforce a certain number of newlines between methods. At least one line is required. 565 | 566 | Use the parameters `logic` (exact/less) and `count` to configure the rule. 567 | 568 | ## Other 569 | 570 | ### 7bit_ascii 571 | 572 | Checks that your code contains only characters from the 7bit ASCII set. This practice should not be required on modern systems with unicode support. 573 | 574 | Disabled. 575 | 576 | 577 | ### check_syntax 578 | 579 | Enables variable analysis (experimental). 580 | 581 | Enabled. 582 | 583 | ### check_ddic 584 | 585 | Checks that referenced ddic types can be resolved. If they are not part of your serialized package, they need to be included in a repository mentioned in the config's `dependencies`. 586 | 587 | Enabled. 588 | 589 | ### tabl_enhancement_category 590 | 591 | Checks that tables do not have the enhancement category *not classified*. 592 | 593 | Enabled. 594 | 595 | ### ambiguous_statement 596 | 597 | In some cases, the abaplint parser cannot tell whether a delete is performed on a database table or an internal table. Enabling the rule will force you to use more explicit syntax. 598 | 599 | Enabled. 600 | 601 | ### message_exists 602 | 603 | Checks that a message class and id exists. 604 | 605 | Enabled. 606 | 607 | ### identical_form_names 608 | 609 | Checks for identically named forms. Form usage is discouraged in general. 610 | 611 | Enabled. 612 | 613 | 614 | ### msag_consistency 615 | 616 | Checks serialized message classes. 617 | 618 | - id is 3 digit 619 | - text exists 620 | 621 | Enabled. 622 | 623 | ### parser_error 624 | 625 | Report abaplint failures. You should log these as issues on https://github.com/abaplint/abaplint/issues so that they can be fixed. 626 | 627 | Enabled 628 | 629 | ### description_empty 630 | 631 | Checks for empty descriptions in the abapGit xml metadata. While not part of abap, this helps ensure the consistency of your serialized files. 632 | 633 | Enabled. 634 | 635 | ### remove_descriptions 636 | 637 | Ensures you have no descriptions in your metadata. This relates to methods, parameters, etc. For class descriptions, see [description_empty](#description_empty). 638 | The descriptions originate either from the form-based SE80 editor or if you use `shorttext synchronized` in abapdoc. 639 | The abaplint philosophy is that you should just use `"!` because `shorttext synchronized` hurts readability. 640 | 641 | Disabled because SAP wants you to use shorttext synchronized (although I agree with the readability issue). 642 | 643 | ### global_class 644 | 645 | Mostly checks abapGit metadata for class names. The situations checked for are caused by code which can't be activated, but the rule is enabled for some extra validation. 646 | 647 | ### begin_end_names 648 | 649 | Checks that names in the `begin of ...` and `end of ...` match. Code violating this rule is invalid. 650 | 651 | Enabled. 652 | 653 | ### check_transformation_exists 654 | 655 | Validates that transformations called in your code exist. 656 | 657 | Enabled. 658 | 659 | ### implement_methods 660 | 661 | Looks for abstract methods which are not yet implemented. Code violating this rule is invalid. 662 | 663 | Enabled. 664 | 665 | ### local_testclass_location 666 | 667 | Validates that test classes are placed within the test include. 668 | 669 | Enabled. 670 | 671 | ### main_file_contents 672 | 673 | Validations related to report definitions. 674 | 675 | - a report must have a name 676 | - a report must begin with `REPORT` 677 | - report name and filename must match 678 | 679 | Enabled. 680 | 681 | 682 | ### rfc_error_handling 683 | 684 | Checks that exceptions 'resource_failure' 'system_failure' and 'communication_failure' are handled in RFC calls. 685 | 686 | Correct handling example: 687 | 688 | ```abap 689 | CALL FUNCTION 'FOO' DESTINATION 'BAR' 690 | EXCEPTIONS 691 | system_failure = 1 MESSAGE lv_msg 692 | communication_failure = 2 MESSAGE lv_msg 693 | resource_failure = 3. 694 | ``` 695 | 696 | ### release_idoc 697 | 698 | Checks idoc types and segments are set to status released 699 | 700 | ### check_abstract 701 | 702 | Checks that 703 | 704 | - no class is abstract + final 705 | - non-abstract classes do not contain abstract methods 706 | 707 | Enabled. 708 | 709 | ### check_text_elements 710 | 711 | Checks existence of text elements and they match their string literal values. 712 | 713 | Enabled. 714 | 715 | ### check_include 716 | 717 | Checks that referenced includes exist. 718 | 719 | ### xml_consistency 720 | 721 | Checks abapgit xml metadata consistency. --------------------------------------------------------------------------------