ABAP Cleaner est un outil open source qui nettoie, formate et modernise automatiquement le code ABAP. Il applique plus de 60 regles de nettoyage et aide a appliquer des standards de code uniformes dans toute l’equipe.
Qu’est-ce que ABAP Cleaner ?
ABAP Cleaner analyse le code ABAP et le transforme automatiquement selon des regles configurables. Contrairement au Pretty Printer, ABAP Cleaner va bien au-dela du simple formatage et modernise egalement les constructions du langage.
| Aspect | Pretty Printer | ABAP Cleaner |
|---|---|---|
| Focus | Indentation, majuscules/minuscules | Modernisation complete du code |
| Regles | ~5 regles de base | 60+ regles configurables |
| Constructions du langage | Aucun changement | Modernisation (p.ex. NEW au lieu de CREATE OBJECT) |
| Lignes vides | Regles simples | Regroupement intelligent |
| Commentaires | Aucun changement | Alignement et formatage |
| Performance | - | Suppression des instructions inutiles |
| Profils | Fixes | Configurables individuellement |
Avantages
- Coherence : Style de code uniforme dans toute l’equipe
- Productivite : Le nettoyage automatique economise le travail manuel
- Modernisation : L’ancienne syntaxe est automatiquement mise a jour
- Lisibilite : Meilleure structuration et formatage
- Revue de code : Moins de discussions sur les questions de style
- Onboarding : Les nouveaux membres de l’equipe ecrivent immediatement du code conforme
Installation dans ADT
Prerequis
- Eclipse avec ADT (ABAP Development Tools)
- Eclipse version 2022-03 ou plus recente
- Java 11 ou plus recent
Installation via Eclipse Marketplace
- Ouvrir Eclipse et naviguer vers Help - Eclipse Marketplace
- Rechercher “ABAP Cleaner”
- Cliquer sur Install et suivre les instructions
- Redemarrer Eclipse
Installation manuelle via Update Site
Si le Marketplace n’est pas disponible :
Help → Install New Software...
URL Update Site :https://sap.github.io/abap-cleaner/updatesite
Fonctionnalites disponibles :☑ ABAP Cleaner
→ Next → Accept License → Finish → Restart EclipseVerifier l’installation
Apres le redemarrage, ABAP Cleaner devrait etre disponible :
┌──────────────────────────────────────────────────────────────┐│ Barre d'outils ADT │├──────────────────────────────────────────────────────────────┤│ ││ [📁] [💾] [↩️] [↪️] ... [🧹 ABAP Cleaner] ││ ││ Ou : Source → Clean Up With Interactive ABAP Cleaner... ││ Raccourci : Ctrl+4 (configurable) ││ │└──────────────────────────────────────────────────────────────┘Regles de nettoyage principales
ABAP Cleaner regroupe ses regles en categories. Voici les plus importantes :
1. Empty Lines - Optimiser les lignes vides
Regroupement intelligent des blocs de code :
Avant :
METHOD process_order.
DATA lv_status TYPE string. DATA lv_amount TYPE p DECIMALS 2.
SELECT SINGLE status FROM zorders INTO lv_status WHERE order_id = iv_order_id.
IF lv_status = 'OPEN'. lv_amount = calculate_total( ).
update_order( lv_amount ). ENDIF.
ENDMETHOD.Apres :
METHOD process_order. DATA lv_status TYPE string. DATA lv_amount TYPE p DECIMALS 2.
SELECT SINGLE status FROM zorders INTO lv_status WHERE order_id = iv_order_id.
IF lv_status = 'OPEN'. lv_amount = calculate_total( ). update_order( lv_amount ). ENDIF.ENDMETHOD.2. Declarations - Moderniser les declarations
Avant :
DATA: lv_count TYPE i, lt_items TYPE TABLE OF zitem, ls_item TYPE zitem, lo_processor TYPE REF TO zcl_processor.
CREATE OBJECT lo_processor.CLEAR lt_items.Apres :
DATA lv_count TYPE i.DATA lt_items TYPE TABLE OF zitem.DATA ls_item TYPE zitem.DATA lo_processor TYPE REF TO zcl_processor.
lo_processor = NEW #( ).CLEAR lt_items.3. Syntax - Utiliser la syntaxe ABAP moderne
Avant :
CALL METHOD lo_service->get_data EXPORTING iv_id = lv_id RECEIVING rt_data = lt_data.
IF lt_data IS INITIAL. " ...ENDIF.
LOOP AT lt_data INTO ls_data. MOVE-CORRESPONDING ls_data TO ls_result. APPEND ls_result TO lt_result.ENDLOOP.Apres :
lt_data = lo_service->get_data( iv_id = lv_id ).
IF lt_data IS INITIAL. " ...ENDIF.
LOOP AT lt_data INTO DATA(ls_data). lt_result = VALUE #( BASE lt_result ( CORRESPONDING #( ls_data ) ) ).ENDLOOP.4. Commands - Supprimer les commandes superflues
Avant :
CLEAR lv_result.lv_result = calculate_value( ).
IF sy-subrc = 0. " SuccesENDIF.
MOVE lv_source TO lv_target.Apres :
lv_result = calculate_value( ).
IF sy-subrc = 0. " SuccesENDIF.
lv_target = lv_source.5. Alignment - Ameliorer l’alignement
Avant :
ls_order-order_id = lv_id.ls_order-customer = lv_customer.ls_order-status = 'NEW'.ls_order-created_at = sy-datum.ls_order-created_by = sy-uname.ls_order-amount = lv_amount.Apres :
ls_order-order_id = lv_id.ls_order-customer = lv_customer.ls_order-status = 'NEW'.ls_order-created_at = sy-datum.ls_order-created_by = sy-uname.ls_order-amount = lv_amount.6. Pretty Print - Formatage
Avant :
IF LV_STATUS='OPEN'AND LV_AMOUNT>100. CALL METHOD LO_SERVICE->PROCESS(EXPORTING IV_ID=LV_ID CHANGING CT_DATA=LT_DATA).ENDIF.Apres :
IF lv_status = 'OPEN' AND lv_amount > 100. lo_service->process( EXPORTING iv_id = lv_id CHANGING ct_data = lt_data ).ENDIF.7. Inline Declarations - Utiliser VALUE et NEW
Avant :
DATA lt_orders TYPE TABLE OF zorder.DATA ls_order TYPE zorder.DATA lo_service TYPE REF TO zcl_order_service.
CREATE OBJECT lo_service EXPORTING iv_client = sy-mandt.
ls_order-order_id = '12345'.ls_order-status = 'NEW'.APPEND ls_order TO lt_orders.Apres :
DATA(lo_service) = NEW zcl_order_service( iv_client = sy-mandt ).
DATA(lt_orders) = VALUE zorders_t( ( order_id = '12345' status = 'NEW' )).8. Comments - Formater les commentaires
Avant :
"Cette methode calcule le prix total"TVA et remise incluses."Parametre: iv_net_price - Prix net" iv_discount - Remise en pourcentage"Retour: Prix brutMETHOD calculate_gross_price.Apres :
" Cette methode calcule le prix total" TVA et remise incluses." Parametre: iv_net_price - Prix net" iv_discount - Remise en pourcentage" Retour: Prix brutMETHOD calculate_gross_price.Configuration et profils
Concept de profil
ABAP Cleaner utilise des profils pour la configuration. Un profil definit quelles regles sont actives et comment elles sont appliquees.
┌──────────────────────────────────────────────────────────────┐│ Gestionnaire de profils │├──────────────────────────────────────────────────────────────┤│ ││ Profils : ││ ┌────────────────────────────────────────────────────────┐ ││ │ [★] Default │ ││ │ [ ] Team Standard │ ││ │ [ ] Strict Modernization │ ││ │ [ ] Minimal Changes │ ││ │ [ ] + Creer un nouveau profil... │ ││ └────────────────────────────────────────────────────────┘ ││ ││ [ Edit ] [ Copy ] [ Delete ] [ Export ] [ Import ] ││ │└──────────────────────────────────────────────────────────────┘Creer et configurer un profil
- Window - Preferences - ABAP Cleaner ouvrir
- Profiles selectionner
- Create new profile cliquer
Configuration des regles
Chaque regle peut etre configuree individuellement :
┌──────────────────────────────────────────────────────────────┐│ Configuration de regle : "Use inline declarations" │├──────────────────────────────────────────────────────────────┤│ ││ ☑ Regle activee ││ ││ Options : ││ ┌────────────────────────────────────────────────────────┐ ││ │ Convertir les declarations DATA : │ ││ │ ○ Uniquement si utilise une fois │ ││ │ ● Si utilise dans le meme bloc │ ││ │ ○ Toujours (agressif) │ ││ │ │ ││ │ ☑ Convertir FIELD-SYMBOLS │ ││ │ ☑ Garder les declarations pour les types complexes │ ││ │ ☐ Convertir meme si le type est perdu │ ││ └────────────────────────────────────────────────────────┘ ││ ││ Apercu : ││ ┌─────────────────────┐ ┌─────────────────────┐ ││ │ DATA lv_name TYPE │ │ DATA(lv_name) = │ ││ │ string. │→│ get_name( ). │ ││ │ lv_name = get_name( │ │ │ ││ └─────────────────────┘ └─────────────────────┘ ││ │└──────────────────────────────────────────────────────────────┘Exporter et partager un profil
Les profils peuvent etre exportes en fichier JSON et partages dans l’equipe :
{ "profileName": "Team Standard", "rules": { "EmptyLinesInClassDefinition": { "enabled": true, "maxEmptyLines": 1 }, "UseInlineDeclaration": { "enabled": true, "convertFieldSymbols": true, "onlyIfUsedOnce": false }, "ReplaceCreateObject": { "enabled": true }, "RemoveUnusedVariables": { "enabled": false } }}Distribution dans l’equipe :
1. Exporter le profil : Preferences → ABAP Cleaner → Export Profile2. Placer le fichier JSON dans le depot Git : /config/abap-cleaner-profile.json3. Les membres de l'equipe importent : Preferences → ABAP Cleaner → Import ProfileUtilisation au quotidien
Mode interactif
Le mode interactif montre tous les changements avant l’application :
Raccourci : Ctrl+4 (ou Source → Clean Up With Interactive ABAP Cleaner...)┌──────────────────────────────────────────────────────────────┐│ ABAP Cleaner interactif │├──────────────────────────────────────────────────────────────┤│ ││ Regle : "Replace obsolete ADD with modern syntax" ││ ││ ┌─────────────────────────────┬─────────────────────────┐ ││ │ Avant │ Apres │ ││ ├─────────────────────────────┼─────────────────────────┤ ││ │ ADD 1 TO lv_count. │ lv_count += 1. │ ││ │ ADD lv_amount TO lv_total. │ lv_total += lv_amount. │ ││ └─────────────────────────────┴─────────────────────────┘ ││ ││ [✓ Appliquer] [✗ Ignorer] [Tout appliquer] [Tout ignorer] ││ ││ Changements : 2 sur 15 appliques | Profil : Team Standard ││ │└──────────────────────────────────────────────────────────────┘Mode automatique
Appliquer toutes les regles sans confirmation :
Raccourci : Ctrl+Shift+4 (ou Source → Clean Up With Automatic ABAP Cleaner)Nettoyage a la sauvegarde
ABAP Cleaner peut etre execute automatiquement a chaque sauvegarde :
Preferences → ABAP Cleaner → Clean-up on save
☑ Activer le nettoyage a la sauvegarde Profil : [Team Standard ▼]
Portee : ○ Methode courante uniquement ● Blocs de code modifies ○ Tout le code source
☑ Afficher une notification apres le nettoyageConfigurer les raccourcis clavier
Window → Preferences → General → Keys
Recherche : "ABAP Cleaner"
Resultats :- Clean Up With Interactive ABAP Cleaner : Ctrl+4- Clean Up With Automatic ABAP Cleaner : Ctrl+Shift+4- Open ABAP Cleaner Preferences : Ctrl+Shift+Alt+4Exemple complet avant/apres
Avant : Code legacy
CLASS zcl_order_processor DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS: process_order IMPORTING iv_order_id TYPE zorder_id RETURNING VALUE(rv_success) TYPE abap_bool RAISING zcx_order_error.
PRIVATE SECTION.
DATA: mv_client TYPE mandt. DATA: mo_logger TYPE REF TO zcl_logger.
ENDCLASS.
CLASS zcl_order_processor IMPLEMENTATION.
METHOD process_order.
DATA: lv_status TYPE zorder_status, lt_items TYPE TABLE OF zorder_item, ls_item TYPE zorder_item, lv_total TYPE p DECIMALS 2, lo_validator TYPE REF TO zcl_order_validator.
CREATE OBJECT lo_validator.
CLEAR lv_total.
SELECT SINGLE status FROM zorders INTO lv_status WHERE order_id EQ iv_order_id.
IF sy-subrc NE 0. RAISE EXCEPTION TYPE zcx_order_error. ENDIF.
IF lv_status EQ 'CLOSED'. rv_success = abap_false. RETURN. ENDIF.
SELECT * FROM zorder_items INTO TABLE lt_items WHERE order_id EQ iv_order_id.
LOOP AT lt_items INTO ls_item. ADD ls_item-amount TO lv_total. ENDLOOP.
CALL METHOD lo_validator->validate EXPORTING iv_order_id = iv_order_id iv_total = lv_total RECEIVING rv_valid = DATA(lv_valid).
IF lv_valid EQ abap_true. UPDATE zorders SET status = 'PROCESSING' WHERE order_id = iv_order_id. rv_success = abap_true. ELSE. rv_success = abap_false. ENDIF.
ENDMETHOD.
ENDCLASS.Apres : Code modernise
CLASS zcl_order_processor DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. METHODS process_order IMPORTING iv_order_id TYPE zorder_id RETURNING VALUE(rv_success) TYPE abap_bool RAISING zcx_order_error.
PRIVATE SECTION. DATA mv_client TYPE mandt. DATA mo_logger TYPE REF TO zcl_logger.ENDCLASS.
CLASS zcl_order_processor IMPLEMENTATION. METHOD process_order. DATA(lo_validator) = NEW zcl_order_validator( ).
SELECT SINGLE status FROM zorders INTO @DATA(lv_status) WHERE order_id = @iv_order_id.
IF sy-subrc <> 0. RAISE EXCEPTION TYPE zcx_order_error. ENDIF.
IF lv_status = 'CLOSED'. rv_success = abap_false. RETURN. ENDIF.
SELECT * FROM zorder_items INTO TABLE @DATA(lt_items) WHERE order_id = @iv_order_id.
DATA(lv_total) = REDUCE #( INIT sum = 0 FOR ls_item IN lt_items NEXT sum += ls_item-amount ).
DATA(lv_valid) = lo_validator->validate( iv_order_id = iv_order_id iv_total = lv_total ).
IF lv_valid = abap_true. UPDATE zorders SET status = 'PROCESSING' WHERE order_id = iv_order_id. rv_success = abap_true. ELSE. rv_success = abap_false. ENDIF. ENDMETHOD.ENDCLASS.Resume des changements
| Categorie | Changement |
|---|---|
| Lignes vides | Lignes vides superflues supprimees, regroupement logique |
| Declarations | Declarations DATA: chainees separees |
| CREATE OBJECT | Remplace par NEW #( ) |
| CLEAR | CLEAR inutile supprime (variable assignee directement) |
| CALL METHOD | Ecriture fonctionnelle utilisee |
| EQ/NE | Remplace par =/<> |
| Inline DATA | Declarations inline ou pertinentes |
| REDUCE | LOOP AT avec ADD remplace par REDUCE |
| Alignment | Alignement coherent des parametres |
Integration dans CI/CD
ABAP Cleaner peut etre utilise comme partie du pipeline CI/CD pour verifier les standards de code :
name: ABAP Style Check
on: pull_request: paths: - 'src/**.abap"
jobs: style-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Setup Java uses: actions/setup-java@v4 with: java-version: '11" distribution: 'temurin"
- name: Run ABAP Cleaner Check run: | # Telecharger ABAP Cleaner CLI wget https://github.com/SAP/abap-cleaner/releases/latest/download/abap-cleaner-cli.jar
# Verifier si des modifications de nettoyage seraient necessaires java -jar abap-cleaner-cli.jar \ --profile config/abap-cleaner-profile.json \ --check-only \ --source src/
- name: Upload Report if: failure() uses: actions/upload-artifact@v4 with: name: cleanup-report path: cleanup-report.txtBonnes pratiques
| Theme | Recommandation |
|---|---|
| Selection du profil | Commencer avec le profil par defaut, ajuster progressivement |
| Standard d’equipe | Definir un profil commun pour toute l’equipe |
| Cleanup on Save | Activer pour un code coherent |
| Mode interactif | Verifier d’abord de maniere interactive pour le code legacy |
| Revue de code | Effectuer le nettoyage avant la revue |
| Nouvelles regles | Verifier les nouvelles regles lors des mises a jour d’ABAP Cleaner |
| Exceptions | Regles desactivables pour des fichiers specifiques |
| CI/CD | Integrer comme verification de style dans le pipeline |
| Migration | Nettoyer le code legacy progressivement, pas tout a la fois |
| Documentation | Documenter les decisions de profil d’equipe |
Sujets connexes
- gCTS - Gestion des transports basee sur Git
- CI/CD avec ABAP Cloud - Pipelines automatises
- Conseils et astuces ADT - Developpement efficace dans Eclipse