Giter Site home page Giter Site logo

abap-cleaner's Introduction

ABAP Cleaner

REUSE status

ABAP cleaner is a configurable tool with the ambition to automate
whatever can be automated
with respect to ABAP code style.

What the ABAP Cleaner Tool Offers

While there is no lack of guidelines and rules on what clean ABAP code should look like...

... these guidelines leave the work of writing clean code (or cleaning existing code) entirely to you.

The ABAP cleaner tool does a lot of this work for you by automating as many of these rules as possible, while giving you full control over which rules are used and how.

ABAP cleaner - code cleanup at a keystroke

With ABAP cleaner, you can clean any amount of code from a single statement to an entire code document with one keystroke. ABAP cleaner then applies 75+ different cleanup rules to your code section, cleaning approx. 1 MB of code per second.

Please don't get us wrong: Of course, an automated tool can NOT replace all other clean code efforts. Obviously, automation is only possible for a subset of the clean code rules - but for a significant one, including formatting, alignment, replacing obsolete commands, and even reducing some nesting depth. This saves you tedious work, leaving you more time to focus on more complex requirements, such as modularization, testability, and good naming.

ABAP cleaner is installed with two profiles:

  • in the 'default' profile, most available cleanup rules are activated with what we believe are good default settings in alignment with the Clean ABAP Styleguide (and even going beyond its demands);
  • in the 'essential' profile, only those cleanup rules are active which are explicitly demanded by the Clean ABAP Styleguide; this applies to approx. 40% of the available cleanup rules.

Additionally, you can create your own profiles: In each profile, you can select which cleanup rules shall be active, and configure options and thresholds for these rules. Your team may align on a common configuration and create a team profile from it.

Demo of ABAP Cleaner

How to install, use, and configure The open source journey of ABAP cleaner
For a demo of what ABAP cleaner offers, how it is installed, used and configured, you can watch this Devtoberfest session on YouTube: To hear about the story behind ABAP cleaner and its journey to open source, watch this webinar hosted by the SAP Open Source Program Office (slides):

How ABAP Cleaner is Used

Automated or Interactive Cleanup from ADT

Using ABAP cleaner from ADT, the cleanup can be done

  • either automatically with a single keystroke (Ctrl + 4 or menu 'Source Code / Clean Up With Automated ABAP Cleaner'),

  • or interactively by opening the ABAP cleaner UI (Ctrl + Shift + 4 or menu 'Source Code / Clean Up With Interactive ABAP Cleaner...') which allows you to check the changes, revert those that you don't like with a single mouse click, and finally apply (or discard) the result.

  • A third option shows a read-only preview of the cleanup result without locking or changing the code, e.g. if you don't have development authorization in the current system (Ctrl + Shift + 5 or menu 'Source Code / Show Read-Only Preview With ABAP Cleaner...')

    ABAP cleaner integration into ABAP Development Tools (ADT)

Using the Stand-alone App with SAP GUI

Using the stand-alone ABAP cleaner app, you may use the clipboard to copy the code from your IDE (i.e. SAP GUI) into ABAP cleaner, and to copy the cleaned code back to your IDE.

You can also make the ABAP cleaner app watch the clipboard and directly replace it with cleaned up code, allowing you to stay in SAP GUI and do the cleanup with Ctrl + C, Ctrl + V.

Scope of the Tool

ABAP cleaner can be used to clean up both existing and new code, both product code and test code, both with a "broadband" approach (simultaneously applying 75+ different rules) and a focused approach (cleaning with a limited selection of rules).

ABAP cleaner was implemented with object-oriented ABAP in mind, but it may also be used for code in reports and functions. EML statements are not yet supported (meaning that most cleanup rules simply leave them unchanged).

Requirements and Installation

To install and use the ABAP cleaner plug-in for ABAP Development Tools (ADT) on Windows or macOS,

  1. Install ABAP Development Tools as described in the Install ADT Tutorial (Step 1), using an Eclipse installation that is compatible with ADT.

  2. Start ADT, select menu 'Help / Install New Software...', copy the link https://sap.github.io/abap-cleaner/updatesite to the 'Work with' field, press Enter and follow the installation steps, confirming to install ABAP cleaner (content is currently unsigned). (Known issues)

    ABAP cleaner plug-in for ABAP Development Tools - installation

  3. After restarting ADT, open an ABAP code document in an editor, and use the menu 'Source Code / Clean Up With Interactive ABAP Cleaner...' (shortcuts Ctrl + 4 or Ctrl + Shift + 4), see usage.

The stand-alone version of ABAP cleaner (for Windows, macOS or Linux) requires Java 17 or 11 (e.g. SapMachine or Adoptium Temurin). To install the stand-alone version, please download and extract the latest Release and follow the installation instructions given there.

Engaging in Our Project

Reporting Issues and Ideas

If you come across any (suspected) bugs or issues, expect ABAP cleaner to behave differently than it does, miss an option to configure a cleanup rule, or have an idea for a great new cleanup rule, please create a GitHub issue, providing a small code snippet of both the original and the cleaned code, and explaining how the result differs from your expectations.

The general approach of ABAP cleaner is to only modify statements that match the expected syntax and leave statements unmodified if any unexpected syntax is found (e.g. comments in weird places inside a statement).

Contributing

You are welcome to contribute to ABAP cleaner development - implementing new cleanup rules, new UI features, bugfixes etc.!

Code of Conduct

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 at all times.

Limitations and Known Issues

The ABAP cleaner plug-in (as any other plug-in) can only be installed from extensible versions of ABAP Development Tools (ADT), in which menu 'Help / Install New Software...' is available.

Since ABAP cleaner does not perform additional backend calls, cleanup is restricted to what can be done within the current code document, without retrieving additional DDIC information, signatures, includes etc.

ABAP cleaner strives to offer cleanup rules that automatically detect what can be improved in the given ABAP code, so after some initial configuration, users shall be able to apply "everything everywhere" with just one keystroke. ABAP cleaner is therefore restricted to cleanup rules that keep functionality unchanged and can be applied without any additional user interaction, or need for subsequent inspection of changes.

At any given time, known and unresolved issues are shown as "Open" issues with label "bug" in the Issues section.

Upcoming Changes

As long as we do not run out of ideas for automatable cleanup (or contributors to implement these ideas), ABAP cleaner shall be enhanced with

  • further cleanup rules,
  • further configuration options,
  • further UI features,
  • possibly, support for code sections in other languages, esp. SQL Script.

As shown in the Profiles and Rules documentation, you can choose yourself whether or not to 'Automatically activate new features after updates' (per profile). New features will be listed in the Release notes.

Detailed Documentation

Licensing

Copyright 2023 SAP SE or an SAP affiliate company and ABAP cleaner contributors. Please see our LICENSE for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available via the REUSE tool.

Continue reading: How to use ABAP cleaner

abap-cleaner's People

Contributors

ajinkyapatil8190 avatar conjuringcoffee avatar jmgrassau avatar sratz avatar stockbal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

abap-cleaner's Issues

Align METHODS declarations unaligns method declarations

Before:

INTERFACE zabc_file_system PUBLIC.
  TYPES:
    file_info_tab TYPE STANDARD TABLE OF file_info WITH KEY filename,
    separator     TYPE c LENGTH 1,
    BEGIN OF connection_info,
      user     TYPE string,
      host     TYPE string,
      protocol TYPE string,
    END OF connection_info.
  METHODS:
    get_supported_methods RETURNING VALUE(result) TYPE zabc_fs_method_enum=>instances,
    get_description RETURNING VALUE(result) TYPE string,
    file_exists IMPORTING path          TYPE csequence
                RETURNING VALUE(result) TYPE abap_bool
                RAISING   zabc_fs_unsupp_operation
                          zabc_file_system_exception,
    read_file_bin IMPORTING path          TYPE csequence
                  RETURNING VALUE(result) TYPE xstring
                  RAISING   zabc_fs_unsupp_operation
                            zabc_file_system_exception,
    read_file_text IMPORTING path          TYPE csequence
                             codepage      TYPE cpcodepage
                   RETURNING VALUE(result) TYPE string
                   RAISING   zabc_fs_unsupp_operation
                             zabc_file_system_exception,
    write_file_bin IMPORTING path    TYPE csequence
                             content TYPE xsequence
                   RAISING   zabc_fs_unsupp_operation
                             zabc_file_system_exception,
    get_directory_contents IMPORTING path          TYPE csequence
                           RETURNING VALUE(result) TYPE file_info_tab
                           RAISING   zabc_fs_unsupp_operation
                                     zabc_file_system_exception,
    create_directory IMPORTING path TYPE csequence
                     RAISING   zabc_fs_unsupp_operation
                               zabc_file_system_exception,
    delete_directory IMPORTING path TYPE csequence
                     RAISING   zabc_fs_unsupp_operation
                               zabc_file_system_exception,
    get_default_codepage RETURNING VALUE(result) TYPE cpcodepage
                         RAISING   zabc_fs_unsupp_operation
                                   zabc_file_system_exception,
    get_separator RETURNING VALUE(result) TYPE separator
                  RAISING   zabc_fs_unsupp_operation
                            zabc_file_system_exception,
    get_connection_info RETURNING VALUE(result) TYPE connection_info
                        RAISING   zabc_fs_unsupp_operation
                                  zabc_file_system_exception.
ENDINTERFACE.

After:

INTERFACE zabc_file_system PUBLIC.
  TYPES:
    file_info_tab TYPE STANDARD TABLE OF file_info WITH KEY filename,
    separator     TYPE c LENGTH 1,
    BEGIN OF connection_info,
      user     TYPE string,
      host     TYPE string,
      protocol TYPE string,
    END OF connection_info.
  METHODS: get_supported_methods RETURNING VALUE(result) TYPE zabc_fs_method_enum=>instances,
           get_description       RETURNING VALUE(result) TYPE string,

    file_exists IMPORTING !path         TYPE csequence
                RETURNING VALUE(result) TYPE abap_bool
                RAISING   zabc_fs_unsupp_operation
                          zabc_file_system_exception,

    read_file_bin IMPORTING !path         TYPE csequence
                  RETURNING VALUE(result) TYPE xstring
                  RAISING   zabc_fs_unsupp_operation
                            zabc_file_system_exception,

    read_file_text IMPORTING !path         TYPE csequence
                             codepage      TYPE cpcodepage
                   RETURNING VALUE(result) TYPE string
                   RAISING   zabc_fs_unsupp_operation
                             zabc_file_system_exception,

    write_file_bin IMPORTING !path   TYPE csequence
                             content TYPE xsequence
                   RAISING   zabc_fs_unsupp_operation
                             zabc_file_system_exception,

    get_directory_contents IMPORTING !path         TYPE csequence
                           RETURNING VALUE(result) TYPE file_info_tab
                           RAISING   zabc_fs_unsupp_operation
                                     zabc_file_system_exception,

    create_directory IMPORTING !path TYPE csequence
                     RAISING   zabc_fs_unsupp_operation
                               zabc_file_system_exception,

    delete_directory IMPORTING !path TYPE csequence
                     RAISING   zabc_fs_unsupp_operation
                               zabc_file_system_exception,

    get_default_codepage RETURNING VALUE(result) TYPE cpcodepage
                         RAISING   zabc_fs_unsupp_operation
                                   zabc_file_system_exception,

    get_separator RETURNING VALUE(result) TYPE separator
                  RAISING   zabc_fs_unsupp_operation
                            zabc_file_system_exception,

    get_connection_info RETURNING VALUE(result) TYPE connection_info
                        RAISING   zabc_fs_unsupp_operation
                                  zabc_file_system_exception.
ENDINTERFACE.

This might resolve itself if the method definition are broken up into multiple statements, which doesn't seem to work currently for interfaces (#12).

ADT-Install seems not to work :-(

I try to install ABAP Cleaner to my ADT, as instructed:

ADT, select menu 'Help / Install New Software...', copy the link https://sap.github.io/abap-cleaner/updatesite to the 'Work with' field and follow the installation steps

However, then a I get an error[1]:

Unable to read repository at https://sap.github.io/abap-cleaner/updatesite/content.xml.
Unable to read repository at https://sap.github.io/abap-cleaner/updatesite/content.xml.
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

[1]
image

" TODO: variable is assigned but never used (ABAP cleaner) after checking whether a database entry exists

Sometimes I just want check, whether a database entry exists using the sy-subrc variable. I am forced to select the data into some table/structure, because a "SELECT" without "INTO" is not possible.

`" TODO: variable is assigned but never used (ABAP cleaner)
SELECT SINGLE * FROM pa0000 INTO @DaTa(ls_dummy) WHERE begda <= @sy-datum
AND endda >= @sy-datum.

IF sy-subrc = 0.
" further processing
ENDIF.`

Would it be possible to switch the message "TODO: variable is assigned but never used (ABAP cleaner)" off in such cases?

ABAP cleaner has encountered a problem: For input string: "fallback"

Hello,

thank you for the tool. It is great, we all installed it on our Eclipse :)

We are encountering on SAP systems with SAP_BASIS release 750 an error. On 756 and 757 it is working fine.

eclipse.buildId=4.24.0.I20220607-0700
java.version=11.0.11
java.vendor=Red Hat, Inc.
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=de_DE
Command-line arguments:  -os win32 -ws win32 -arch x86_64

com.sap.adt.abapcleaner.gui
Error
Wed May 24 11:07:37 CEST 2023
ABAP cleaner has encountered a problem

java.lang.NumberFormatException: For input string: "fallback"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.base/java.lang.Integer.parseInt(Integer.java:652)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
	at com.sap.adt.abapcleaner.rulebase.Rule.isCleanupAllowedFor(Rule.java:374)
	at com.sap.adt.abapcleaner.rulebase.Rule.executeIfAllowedOn(Rule.java:355)
	at com.sap.adt.abapcleaner.rulebase.Profile.executeRules(Profile.java:198)
	at com.sap.adt.abapcleaner.programbase.Task.run(Task.java:168)
	at com.sap.adt.abapcleaner.programbase.Task.run(Task.java:120)
	at com.sap.adt.abapcleaner.programbase.Job.runSingleCodeDocument(Job.java:109)
	at com.sap.adt.abapcleaner.programbase.Job.run(Job.java:98)
	at com.sap.adt.abapcleaner.gui.FrmMain$50.run(FrmMain.java:1311)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74)
	at com.sap.adt.abapcleaner.gui.FrmMain.runJobWithProgressUiIfNeeded(FrmMain.java:1308)
	at com.sap.adt.abapcleaner.gui.FrmMain.runJobWithProgressUiIfNeeded(FrmMain.java:1300)
	at com.sap.adt.abapcleaner.gui.FrmMain.refreshCode(FrmMain.java:1259)
	at com.sap.adt.abapcleaner.gui.FrmMain.open(FrmMain.java:345)
	at com.sap.adt.abapcleaner.gui.FrmMain.cleanInteractively(FrmMain.java:265)
	at com.sap.adt.abapcleaner.gui.eclipse.AbapCleanerHandlerBase.execute(AbapCleanerHandlerBase.java:96)
	at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:283)
	at org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:97)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:58)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:317)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:251)
	at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:173)
	at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:156)
	at org.eclipse.core.commands.Command.executeWithChecks(Command.java:488)
	at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:485)
	at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:213)
	at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.executeItem(HandledContributionItem.java:438)
	at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.handleWidgetSelection(AbstractContributionItem.java:449)
	at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.lambda$2(AbstractContributionItem.java:475)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4251)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1066)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4068)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3645)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1155)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1046)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:644)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:551)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:156)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:136)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:402)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:659)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:596)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1467)
 

Best regards,
Tim

Inexplicable behavior in "Align parameters and components"

I found an example with the rule "Align parameters and components" that doesn't make sense to me. Can someone please explain this behavior to me?

CLASS lcl_example DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.

  PROTECTED SECTION.

  PRIVATE SECTION.
    DATA:
      BEGIN OF variable,
        short_1 TYPE bapiret2,
        short_2 TYPE bapiret2,
        short_3 TYPE bapiret2,
        short_4 TYPE bapiret2,
        short_5 TYPE bapiret2,
      END OF variable.

    METHODS example.
ENDCLASS.


CLASS lcl_example IMPLEMENTATION.
  METHOD example.
    variable = VALUE #( short_1 = VALUE #(
        number     = '001'
        message_v1 = '1'
        message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1' )
                        short_2 = VALUE #(
                            number     = '002'
                            message_v1 = '2'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2' )
                        short_3 = VALUE #(
                            number     = '003'
                            message_v1 = '3'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3' )
                        short_4 = VALUE #(
                            number     = '004'
                            message_v4 = '4'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4' )
                        short_5 = VALUE #(
                            number     = '005'
                            message_v4 = '5'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5' ) ).
  ENDMETHOD.
ENDCLASS.

I would have expected this or a similar result. The content in message has the same length every time, so that can't be the reason....

  METHOD example.
    variable = VALUE #( short_1 = VALUE #(
                            number     = '001'
                            message_v1 = '1'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1' )
                        short_2 = VALUE #(
                            number     = '002'
                            message_v1 = '2'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2' )
                        short_3 = VALUE #(
                            number     = '003'
                            message_v1 = '3'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3' )
                        short_4 = VALUE #(
                            number     = '004'
                            message_v4 = '4'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4' )
                        short_5 = VALUE #(
                            number     = '005'
                            message_v4 = '5'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5' ) ).
  ENDMETHOD.

Here are my options:
image

Feature request: Order method implementations

I'd like to request a new rule to order the method implementations based on the order of the method definitions.

Example:

CLASS lcl_example DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS method_1.
    METHODS method_2.

  PROTECTED SECTION.

  PRIVATE SECTION.

ENDCLASS.


CLASS lcl_example IMPLEMENTATION.
  METHOD method_2.
  ENDMETHOD.

  METHOD method_1.
  ENDMETHOD.
ENDCLASS.

Expected result:

CLASS lcl_example DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS method_1.
    METHODS method_2.

  PROTECTED SECTION.

  PRIVATE SECTION.

ENDCLASS.


CLASS lcl_example IMPLEMENTATION.
  METHOD method_1.
  ENDMETHOD.

  METHOD method_2.
  ENDMETHOD.
ENDCLASS.

Feature Request: APPEND -> INSERT

A nice feature would be, to refactor the APPEND statements into the INSERT version, to be independant from table types.

" Old version
APPEND ls_structure TO lt_table.
APPEND VALUE #( field = '' ) TO lt_table.

" New version
INSERT ls_structure INTO TABLE lt_table.
INSERT VALUE #( field = '' ) INTO TABLE lt_table.

Should also be formatted with VALUE rules.

"Align parameters and components": Align assignments across multiple parenthesis in one VALUE

Hi Jörg-Michael, I'm sorry to open another issue for rule "Align parameters and components" - I hope I don't annoy with this... 😅

This issue is about the option "Align assignments" in a VALUE statement to create an internal table. Example:

  METHOD example.
    TYPES: BEGIN OF ly_type,
             short       TYPE i,
             medium      TYPE i,
             longer_name TYPE i,
           END OF ly_type.

    DATA lt_example TYPE TABLE OF ly_type WITH EMPTY KEY.

    lt_example = VALUE #( ( short       = 1
                            medium      = 1
                            longer_name = 3 )
                          ( short  = 2
                            medium = 2 )
                          ( short       = 3
                            longer_name = 3 ) ).
  ENDMETHOD.

The second table line is aligned based on its longest component name medium. Instead, I'd like it to be aligned to the longest component used (in this case longer_name):

  METHOD example.
    TYPES: BEGIN OF ly_type,
             short       TYPE i,
             medium      TYPE i,
             longer_name TYPE i,
           END OF ly_type.

    DATA lt_example TYPE TABLE OF ly_type WITH EMPTY KEY.

    lt_example = VALUE #( ( short       = 1
                            medium      = 1
                            longer_name = 3 )
                          ( short       = 2
                            medium      = 2 )
                          ( short       = 3
                            longer_name = 3 ) ).

    lt_example[ 1 ]-longer_name = 1.
  ENDMETHOD.

For completeness, here are my settings:
image

Feature Request: ABAP Cloud Readyness fixes for system fields

Hello Jörg,

when executing the ATC cloud readiness checks for our on-premise objects, I receive numerous warnings advising against the use of system fields (such as sy-datum, sy-uzeit, and so forth). It would be beneficial to incorporate a rule in the ABAP Cleaner that substitutes access to these system variables with the corresponding invocation of a CL_ABAP_CONTEXT_INFO method.

before:
IF end_date > sy-datum OR
( end_date = sy-datum AND end_time > sy-uzeit ).
...
ENDIF.

after:
IF end_date > CL_ABAP_CONTEXT_INFO=>get_system_date( ) OR
( end_date = CL_ABAP_CONTEXT_INFO=>get_system_date( ) AND end_time > CL_ABAP_CONTEXT_INFO=>get_system_time( ) ).
...
ENDIF.

sy-datum => CL_ABAP_CONTEXT_INFO=>get_system_date( )
sy-uzeit => CL_ABAP_CONTEXT_INFO=>get_system_time( )
sy-langu => CL_ABAP_CONTEXT_INFO=>get_user_language_abap_format( )
sy-zonlo => CL_ABAP_CONTEXT_INFO=>get_user_time_zone( )
sy-uname => CL_ABAP_CONTEXT_INFO=>get_user_technical_name( )

Best Regards,
Ben

"Align parameters and components": Consistent line breaks in nested VALUEs

This is a follow-up to #53.

Here's an example:

CLASS lcl_example DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.

  PROTECTED SECTION.

  PRIVATE SECTION.
    DATA:
      BEGIN OF variable,
        field_1 TYPE bapiret2,
        field_2 TYPE bapiret2,
        field_3 TYPE bapiret2,
        field_4 TYPE bapiret2,
        field_5 TYPE bapiret2,
      END OF variable.

    METHODS example.
ENDCLASS.


CLASS lcl_example IMPLEMENTATION.
  METHOD example.
    variable = VALUE #( field_1 = VALUE #(
                            number     = '001'
                            message_v1 = '1'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1' )
                        field_2 = VALUE #( number     = '002'
                                           message_v1 = '2'
                                           message    = '2' )
                        field_3 = VALUE #(
                            number     = '003'
                            message_v1 = '3'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3' )
                        field_4 = VALUE #( number     = '004'
                                           message_v4 = '4'
                                           message    = '4' )
                        field_5 = VALUE #(
                            number     = '005'
                            message_v4 = '5'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5' ) ).
  ENDMETHOD.
ENDCLASS.

Everything works as designed: The constructor expression for field_2 starts on the same line because the content in message is short enough. I'd like to see an option to keep the style of line-breaks consistent. If it there is a line-break for one of the fields, then there should be a line-break for all of the fields. Here's what I would expect:

  METHOD example.
    variable = VALUE #( field_1 = VALUE #(
                            number     = '001'
                            message_v1 = '1'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1' )
                        field_2 = VALUE #( 
                            number     = '002'
                            message_v1 = '2'
                            message    = '2' )
                        field_3 = VALUE #(
                            number     = '003'
                            message_v1 = '3'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3' )
                        field_4 = VALUE #( 
                            number     = '004'
                            message_v4 = '4'
                            message    = '4' )
                        field_5 = VALUE #(
                            number     = '005'
                            message_v4 = '5'
                            message    = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5' ) ).
  ENDMETHOD.

This might fall in the same category of this example from Jörg-Michael in #53:

P.S.: A non-ideal (but nevertheless correct) result is e.g. produced at maximum 86, where the additional ")." of the second inner VALUE constructor makes the difference:

    rs_result = VALUE #(
        comp_1 = VALUE #( num  = '001'
                          text = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1' )
        comp_2 = VALUE #(
            num  = '002'
            text = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2' ) ).

Would it be possible to create custom rules?

This is not an error but an enhancement.

I am in the middle of a project where we have to change many reports to adapt them to new personnel structures, and I was thinking that I could at the same time clean the code.

So, also add for example the rule to replace "bukrs = '1000'" with "bukrs = '1100'"

This rule could be setup very quickly and I wouldn't need to perform everything in two steps.

Thanks for the feedback and for the GREAT TOOL!

Kind regards,

"Delete unused variables": TODO comment not removed for exception

Hi Jörg-Michael,

I found an example in which the generated TODO comment is not removed after a use for the variable is added.

Before the variable is used:

  METHOD example.
    TRY.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      CATCH cx_sy_itab_line_not_found INTO DATA(exception).
*        MESSAGE exception TYPE 'E'.
    ENDTRY.
  ENDMETHOD.

The ABAP Cleaner correctly adds the comment:

  METHOD example.
    TRY.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      CATCH cx_sy_itab_line_not_found INTO DATA(exception). " TODO: variable is assigned but only used in commented-out code (ABAP cleaner)
*        MESSAGE exception TYPE 'E'.
    ENDTRY.
  ENDMETHOD.

However, actually using the variable afterwards doesn't remove the TODO comment again:

  METHOD example.
    TRY.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      CATCH cx_sy_itab_line_not_found INTO DATA(exception). " TODO: variable is assigned but only used in commented-out code (ABAP cleaner)
        MESSAGE exception TYPE 'E'.
    ENDTRY.
  ENDMETHOD.

Feature Request: Missing spaces

Similar to existing space rules, there should be rule (or perhaps include in "Close brackets at line end"?), where a space is expected between a ' and ( or ) for method calls and inside VALUE statements.

Before:

cl_abap_unit_assert=>assert_not_initial('some-string').

After:

cl_abap_unit_assert=>assert_not_initial( 'some-string' ).

VALUE Before:

var = VALUE #( ( field = '12345')
               ( field = '67890') ).

VALUE After:

var = VALUE #( ( field = '12345' )
               ( field = '67890' ) ).

Replace obsolete MOVE for chained fields

Replacing the obsolete MOVE command is a great rule! However it does not seem to work for multiple chained fields.

Before

MOVE:
  source1 TO destination1,
  source2 TO destination2.

After

destination1 = source1.
destination2 = source2.

Alignment differences in pretty printer versus abap cleaner

Hi,

are you supposed to disable alignments by pretty printer if you use abap cleaner? They correct each other for me in the default settings. Or maybe the pretty printer was adjusted in a higher release so they are the same there?

Pretty Printer:

CLASS zabc_fs_method_enum DEFINITION
  PUBLIC
  FINAL
  CREATE PRIVATE.

  PUBLIC SECTION.
    TYPES instances TYPE SORTED TABLE OF REF TO zabc_fs_method_enum WITH UNIQUE KEY table_line.

    CLASS-DATA:
      file_exists            TYPE REF TO zabc_fs_method_enum READ-ONLY,
      read_file_bin          TYPE REF TO zabc_fs_method_enum READ-ONLY,
      read_file_text         TYPE REF TO zabc_fs_method_enum READ-ONLY,
      write_file_bin         TYPE REF TO zabc_fs_method_enum READ-ONLY,
      get_directory_contents TYPE REF TO zabc_fs_method_enum READ-ONLY,
      create_directory       TYPE REF TO zabc_fs_method_enum READ-ONLY,
      delete_directory       TYPE REF TO zabc_fs_method_enum READ-ONLY,
      get_default_codepage   TYPE REF TO zabc_fs_method_enum READ-ONLY,
      get_separator          TYPE REF TO zabc_fs_method_enum READ-ONLY,
      get_connection_info    TYPE REF TO zabc_fs_method_enum READ-ONLY,
      BEGIN OF partial_reader READ-ONLY,
        read_file_to_buffer_bin  TYPE REF TO zabc_fs_method_enum,
        read_file_to_buffer_text TYPE REF TO zabc_fs_method_enum,
      END OF partial_reader,
      BEGIN OF partial_writer READ-ONLY,
        write_buffer_to_file_bin  TYPE REF TO zabc_fs_method_enum,
        write_buffer_to_file_text TYPE REF TO zabc_fs_method_enum,
      END OF partial_writer.

    DATA value TYPE abap_methname READ-ONLY.

    CLASS-METHODS class_constructor.
    CLASS-METHODS get_instances RETURNING VALUE(result) TYPE instances.

  PROTECTED SECTION.
  PRIVATE SECTION.
    CLASS-DATA:
      enum_instances TYPE instances.
    METHODS:
      constructor IMPORTING method_name TYPE abap_methname.
ENDCLASS.

ABAP Cleaner

CLASS zabc_fs_method_enum DEFINITION
  PUBLIC
  FINAL
  CREATE PRIVATE.

  PUBLIC SECTION.
    TYPES instances TYPE SORTED TABLE OF REF TO zabc_fs_method_enum WITH UNIQUE KEY table_line.

    CLASS-DATA:
      file_exists                 TYPE REF TO zabc_fs_method_enum READ-ONLY,
      read_file_bin               TYPE REF TO zabc_fs_method_enum READ-ONLY,
      read_file_text              TYPE REF TO zabc_fs_method_enum READ-ONLY,
      write_file_bin              TYPE REF TO zabc_fs_method_enum READ-ONLY,
      get_directory_contents      TYPE REF TO zabc_fs_method_enum READ-ONLY,
      create_directory            TYPE REF TO zabc_fs_method_enum READ-ONLY,
      delete_directory            TYPE REF TO zabc_fs_method_enum READ-ONLY,
      get_default_codepage        TYPE REF TO zabc_fs_method_enum READ-ONLY,
      get_separator               TYPE REF TO zabc_fs_method_enum READ-ONLY,
      get_connection_info         TYPE REF TO zabc_fs_method_enum READ-ONLY,
      BEGIN OF partial_reader READ-ONLY,
        read_file_to_buffer_bin   TYPE REF TO zabc_fs_method_enum,
        read_file_to_buffer_text  TYPE REF TO zabc_fs_method_enum,
      END OF partial_reader,
      BEGIN OF partial_writer READ-ONLY,
        write_buffer_to_file_bin  TYPE REF TO zabc_fs_method_enum,
        write_buffer_to_file_text TYPE REF TO zabc_fs_method_enum,
      END OF partial_writer.

    DATA value TYPE abap_methname READ-ONLY.

    CLASS-METHODS class_constructor.
    CLASS-METHODS get_instances RETURNING VALUE(result) TYPE instances.

  PROTECTED SECTION.
  PRIVATE SECTION.
    CLASS-DATA:
      enum_instances TYPE instances.
    METHODS:
      constructor IMPORTING method_name TYPE abap_methname.
ENDCLASS.

Profile creation box is not completely visible

Hi everyone,

When creating a new profile I'm experiencing some problems seeing the Profile creation box as show bellow, I mean, the buttons are not clearly visible.. Does this happen to anyone else?

image

Thanks!

"Delete unused variables" rule deletes variable which used in macros.

"Delete unused variables" rule deletes variable which used in macros.

For example:

In include f01
DATA: lv_tuna TYPE developer.

In include m01
DEFINE xxx.
&1 = lv_tuna + 'xxx'.
END-OF-DEFINITION.

when formatting include f01, it deletes the definition in include f01, so it cannot be activated.

Feature request: Remove end-of comments

Hi Jörg-Michael, I'd like to request a feature to remove end-of-comments.

This refers to a rule from Clean ABAP: Don't add method signature and end-of comments

Example, before:

FORM execute.
ENDFORM.              " EXECUTE

Expected result:

FORM execute.
ENDFORM.            

Below are some more examples.

METHOD execute.
ENDMETHOD. " execute
MODULE user_command_0600 INPUT.
ENDMODULE. " USER_COMMAND_0600  INPUT

Contribution guideline for newcomers

I'd like to be able to contribute to this project, but I don't really know how to get started. Would it be possible to provide some kind of architecture overview? I'd also love to see some recommendations on setting up the development environment and on how the changes are to be tested.

Replace "measure" by "action"

There's a bunch of places that use "measure" to mean "action" (probably a direct translation of the German Maßnahme), in particular this config UI for the "Delete unused variables" rule:
image

While measure can mean "action" (as in "We've taken measures to clean up our code"), the use of measure to denote a specific repeatable action in the context of a tool like this strikes me as unidiomatic.

(not a pull request because I'd like native speakers' input on this before changing it)

Feature request: Un-align declarations

The Clean ABAP style guide suggests to not use chaining and not to align type declarations.

ABAP Cleaner provides the rule "Unchain into multiple statements", but any previous alignment is not removed. Could this be an option or another rule?

Example:

PARAMETERS:
  p_short  TYPE i,
  p_longer TYPE char20.

Result:

PARAMETERS p_short  TYPE i.
PARAMETERS p_longer TYPE char20.

Expected:

PARAMETERS p_short TYPE i.
PARAMETERS p_longer TYPE char20.

Feature request: Use newer expressions

There are a number of newer expressions that seem like a good fit for a rule to replace the old syntax, such as:

  • 1. CORRESPONDING #( ) - refer to #266
  • 2. String templates - partially complete in 1.15.0
    refer to #116
  • 3. line_exists( ) 1.14.0
  • 4. lines( ) 1.14.0
  • 5. condense() 1.15.0
  • 6. translate( ) 1.0.0
  • 7. concat_lines_of( )
  • 8. shift_left( ) & shift_right( )
  • 9. to_upper( ) & to_lower( ) 1.0.0
  • 10. line_index( ) 1.14.0
  • 11. REF #( )

Keeping profiles the same for multiple developers?

When working in a team, each developer should use the same profile. Right now, each developer is responsible for the rules profile they use. This is fine for an initial setup but can get messy when it comes to updating the settings of the profile.

I see two approaches we can follow right now:

  • Define a profile, make it available to the other developers and hope that everyone updates their profile. Of course, this will not be successful every time.
  • Define a shared folder (e.g. in OneDrive) that contains the profile of the team. Any changes to the profile are automatically synced between the developers. The disadvantage is that all personal profiles are also shared with everyone.

Are there any better approaches?

If not, then I'd like to see some kind of mechanism to distribute profiles. One possibility could be to have one folder for shared profiles and one folder for personal profiles.

Feature request: Keyboard shortcut to clean up entire object and combine with ABAP Formatter

Hi Jörg-Michael, my regular shortcut usage looks like this currently:

  • SHIFT+F1 to use the ABAP Formatter on the entire class
  • CTRL+A, then CTRL+SHIFT+4 to use the ABAP Cleaner on the entire class
  • CTRL+SHIFT+F3 to save and activate everything

That's quite some finger acrobatics. 😄 My request is for a keyboard shortcut to use the ABAP Cleaner on the entire class without having to select the entire class beforehand. (So essentially: Have a shortcut that uses the same selection mechanism as the ABAP Formatter.)

My second request is for a possibility to include the ABAP Formatter in the shortcut. The ABAP Cleaner doesn't fully replace the ABAP Formatter yet, so I still see the need to use it. (I can open a separate issue for this if you want to.)

In my ideal scenario I could then put this new shortcut on SHIFT+F1 and work like I used to.

Standardize escaping of ! parameters: "Never" option?

I noticed there is no Never option available for this rule.
image

Is it truly required to escape parameters that match ABAP keywords? I have been removing these for some time without issue. Perhaps we could add a Never option?

Align keywords with second word of first line: RAISE EXCEPTION with EXPORTING

My RAISE EXCEPTION TYPE statements with MESSAGE are converted from this

        RAISE EXCEPTION TYPE zabc_path_exception
          MESSAGE ID sy-msgid
          NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
          EXPORTING
            previous = exception.

to this according to the rule.

        RAISE EXCEPTION TYPE zabc_path_exception
              MESSAGE ID sy-msgid
              NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
              EXPORTING
                previous = exception.

However without the MESSAGE addition the EXPORTING is not aligned with the second word.

        RAISE EXCEPTION TYPE zabc_path_exception
          EXPORTING
            previous = exception.
        RAISE EXCEPTION TYPE zabc_path_exception
          EXPORTING previous = exception.

It seems like another rule applies here "Align parameters and components" and overules the positioning. Is this intended? If I turn that off I get the expected result:

        RAISE EXCEPTION TYPE zabc_path_exception
              EXPORTING
                previous = exception.

Also: Shouldn't the previous = exception line in the first example also get moved directly after the EXPORTING? Like this:

        RAISE EXCEPTION TYPE zabc_path_exception
              MESSAGE ID sy-msgid
              NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
              EXPORTING previous = exception.

Feature request: Make ABAP Doc synchronized if short enough

I'd like to request a new rule on automatically making existing ABAP Doc synchronized if the text is short enough.

Example:

"! This is my documentation
CLASS lcl_example DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

Expected result:

"! <p class="shorttext synchronized">This is my documentation</p>
CLASS lcl_example DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

I think this will make writing documentation faster.

The ADT quick fixes sometimes don't generate the ABAP Doc using shorttext synchronized, so that would solve this issue as well.

Unchain into multiple statements does not apply to interfaces

The rule "Unchain into multiple statements" breaks up my method definition chained statement in classes in multiple statements. It does however not apply to method definitions in interfaces and I do not see a way to turn it on either. This seems inconsistent.

Feature request: Add missing parameters to ABAP Doc

I'd like to see a rule that adds missing parameters to the ABAP Doc. Would this be possible?

Example:

    "! <p class="shorttext synchronized"></p>
    "!
    "! @parameter param_1 | <p class="shorttext synchronized">test</p>
    METHODS meth_1
      IMPORTING
        param_1 TYPE i
        param_2 TYPE i.

Expected result:

    "! <p class="shorttext synchronized"></p>
    "!
    "! @parameter param_1 | <p class="shorttext synchronized">test</p>
    "! @parameter param_2 | <p class="shorttext synchronized"></p>
    METHODS meth_1
      IMPORTING
        param_1 TYPE i
        param_2 TYPE i.

Format code on save in ADT / Eclipse

Hi,

When saving an ABAP file in ADT/Eclipse, I would want the ABAP Cleaner to run automatically, formatting the file first and then saving it.

Similar tools for JavaScript or Java already have such functionality and I consider it very practical.

Is it possible to add a feature to format the code on save?

BR
Robin

Align declarations inserts an unexpected number of spaces

Before

    TYPES: BEGIN OF al11_file,
             dirname  TYPE dirname_al11,
             name     TYPE filename_al11,
             type     TYPE c  LENGTH 10,
             len      TYPE p  LENGTH 8 DECIMALS 0,
             owner    TYPE fileowner_al11,
             mtime    TYPE p LENGTH 6 DECIMALS 0,
             mode     TYPE c LENGTH 9,
             useable  TYPE c LENGTH 1,
             subrc    TYPE c LENGTH 4,
             errno    TYPE c LENGTH 3,
             errmsg   TYPE c LENGTH 40,
             mod_date TYPE d,
             mod_time TYPE c LENGTH 8,
             seen     TYPE c LENGTH 1,
             changed  TYPE c LENGTH 1,
             status   TYPE c LENGTH 1,
           END OF al11_file,
           al11_file_tab TYPE STANDARD TABLE OF al11_file.
    FIELD-SYMBOLS <file_list> TYPE al11_file_tab.

After

    TYPES: BEGIN OF al11_file,
             dirname     TYPE dirname_al11,
             name        TYPE filename_al11,
             type        TYPE c                           LENGTH 10,
             len         TYPE p                           LENGTH 8 DECIMALS 0,
             owner       TYPE fileowner_al11,
             mtime       TYPE p                           LENGTH 6 DECIMALS 0,
             mode        TYPE c                           LENGTH 9,
             useable     TYPE c                           LENGTH 1,
             subrc       TYPE c                           LENGTH 4,
             errno       TYPE c                           LENGTH 3,
             errmsg      TYPE c                           LENGTH 40,
             mod_date    TYPE d,
             mod_time    TYPE c                           LENGTH 8,
             seen        TYPE c                           LENGTH 1,
             changed     TYPE c                           LENGTH 1,
             status      TYPE c                           LENGTH 1,
           END OF al11_file,
           al11_file_tab TYPE STANDARD TABLE OF al11_file.
    FIELD-SYMBOLS <file_list> TYPE al11_file_tab.

Remove the self-reference me->: Does not work in interface methods

Hi Jörg-Michael, the self-reference me-> is not removed in interface methods.

Here's an example I re-created using local objects:

INTERFACE lif_test.
  METHODS from_interface.
ENDINTERFACE.


CLASS lcl_test DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES lif_test.

  PROTECTED SECTION.

  PRIVATE SECTION.
    DATA mv_value TYPE i.

    METHODS in_class.
ENDCLASS.


CLASS lcl_test IMPLEMENTATION.
  METHOD lif_test~from_interface.
    me->mv_value = 1.
  ENDMETHOD.

  METHOD in_class.
    me->mv_value = 1.
  ENDMETHOD.

ENDCLASS.

Here's the result:
image

Remove unnecessary parameters name from 'Exporting' keyword and indentation

Hi all! thank you for this great tool!

It would be nice, if you could enhance the 'Omit optional Exporting' option, so when a method has only one exporting parameter the input parameter name doesn't show up. Like this:

lv_value = get_value( value1 ).

Instead of:

lv_value = get_value( iv_value1 = value1 ).

Also, on indentation point of view it would be nice to have an option to align the parameters next to parenthesis like this:

lv_value = get_value( iv_value1 = value1
....................................... iv_value2 = value2 ).

(the dots it's just to keep the indentation as I want to show you)

instead of this:

lv_value = get_value(
iv_value1 = value1
iv_value2 = value2 ).

(Image as it is attached).

Thank you!!

indentation example

Installation error on older Eclipse release

I also tried installing the ADT Addon and came across the problem with trust/certificates (#15) which I could resolve by changing eclipse.ini.

But the installation fails anyway because of errors due to osgi repositories that can't be found.

image

This seems to go back to an incompatible Eclipse release. I'm on 2022-03 currently. It seems to work with 2022-12 and 2023-03.

It would be helpful to mention the compatibility to eclipse releases somewhere on the git site or even inlude ABAP Cleaner at https://tools.hana.ondemand.com.

"Remove needless spaces": Support for PARAMETERs

Hi Jörg-Michael, during the testing of #35 I found an example which doesn't fully work. I'm opening a new issue because the change being done isn't attributed to "Align declarations", but to "Remove needless spaces".

PARAMETERS p_test1       RADIOBUTTON GROUP 1.
PARAMETERS p_test2    RADIOBUTTON GROUP 1.
PARAMETERS p_test3 AS CHECKBOX.

After:

PARAMETERS p_test1 RADIOBUTTON GROUP 1.
PARAMETERS p_test2    RADIOBUTTON GROUP 1.
PARAMETERS p_test3 AS CHECKBOX.

Parameter p_test2 is not un-aligned correctly. If I also change the alignment of p_test3, then it works correctly.

Before:

PARAMETERS p_test1       RADIOBUTTON GROUP 1.
PARAMETERS p_test2    RADIOBUTTON GROUP 1.
PARAMETERS p_test3  AS CHECKBOX.

After and expected:

PARAMETERS p_test1 RADIOBUTTON GROUP 1.
PARAMETERS p_test2 RADIOBUTTON GROUP 1.
PARAMETERS p_test3 AS CHECKBOX.

Here are my settings:

image

image

Doesn't show in menu on Mac

I installed the plugin but doesn't show items in menu, I try install agin but doesn't work.
I use eclipse on Mac, does work on eclipse on Mac?

Set ABAP release in Stand alone app

Hi,

I had a little problem today with the stand alone app that had changed my counter count up by 1 to new notation += 1. However, the system did not support this yet. Is it possible to change the release in the settings or will it be possible?

Behavior for standardizing empty lines in class definitions

I'd like to request a change to the behavior of the rule "Standardize empty lines in class definitions".

Here's how I like class definitions to be formatted:

CLASS lcl_example DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS method_1.
    METHODS method_2.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

I don't think there's a way for the ABAP Cleaner to get to this result currently. I can achieve the empty line below the last METHODS by using the option "Add empty line above PUBLIC / PROTECTED / PRIVATE SECTION", but that also adds empty lines between the empty sections.

I have not activated the rule "Remove empty class definition SECTIONs" because I think it is more clear and consistent if all sections are there every time.

What I want could be summarized as "Add empty line below last definition in a SECTION". What do you think about this?

Formatting value statement with different line

I tested a bit with the "default" profile and provided some unclean code:

rt_result =
  VALUE #(
      ( some_id = 'A' some_text = 'ABC' a_number = 2 )
    ( some_id = 'B' some_text = 'ABC' a_number = 10 )
    ( some_id = 'C' some_text = 'DEF' a_number = 8 )
      ( some_id = 'A' some_text = 'GIH' a_number = 7 )
  ).

ABAP Cleaner has done:

rt_result =
  VALUE #( ( some_id = 'A' some_text = 'ABC' a_number = 2 )
           ( some_id = 'B' some_text = 'ABC' a_number = 10 )
           ( some_id = 'C' some_text = 'DEF' a_number = 8 )
           ( some_id = 'A' some_text = 'GIH' a_number = 7 ) ).

I expected:

rt_result = VALUE #( ( some_id = 'A' some_text = 'ABC' a_number = 2 )
                     ( some_id = 'B' some_text = 'ABC' a_number = 10 )
                     ( some_id = 'C' some_text = 'DEF' a_number = 8 )
                     ( some_id = 'A' some_text = 'GIH' a_number = 7 ) ).

Is this behavior correct?

Align keywords with second word of first line: `CALL TRANSFORMATION`

The rule "Align keywords with second word of first line" doesn't do anything for the command CALL TRANSFORMATION:

CALL TRANSFORMATION ztest
  SOURCE XML iv_xml
  RESULT urlrequest = rv_request.

Expected result:

CALL TRANSFORMATION ztest
     SOURCE XML iv_xml
     RESULT urlrequest = rv_request.

Align logical expressions: WHERE condition of FOR not aligned?

    DATA lt_vbak TYPE TABLE OF vbak.
    DATA lt_result LIKE lt_vbak.

    lt_result = VALUE #( FOR ls_vbak IN lt_vbak WHERE
                         ( vbeln = '1'
AND auart = 'A' )
                         ( ls_vbak ) ).

Above is an example in which the line AND auart = 'A' ) is not automatically aligned with the rest. It is only aligned if the previous line ( vbeln = '1' would also be aligned simultaneously. Is this a bug or is the behavior intended?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.