Skip to Content
Author's profile photo Enno Wulff

Find Redefinitions!

In a project I made extensive use of inheritance of a super class. This super class holds all the standard functionality of objects. If a specific object needs to change the standard behaviour the method can be redefined. This concept worked out well.

The problem I faced was, that I didn’t know anymore which sub classes use a special functionality. I had to enter the class, scroll down, find the right method and check if and how the redefinition looked like.

This procedure of course is totally inadequate for a programmer! 😉

So I wrote a little programm which investigates the redfined methods of sub classes.

For example you can enter the class CL_GUI_CONTROL and the method FREE and you will get all subclasses which redefined this method. The classes will be listed in an SALV control.

With a double click on a class the source code of the redefined method will be shown in a docker control.

With this program it’s easy for me to see which of the ~60 sub classes uses a special CALCULATION or extra CHECKs.

Code

Find the code here

REPORT ztrcktrsr_find_redefinitions.


PARAMETERS p_clas TYPE seoclsname DEFAULT 'CL_GUI_CONTROL'.
PARAMETERS p_meth TYPE seocpdname DEFAULT 'FREE'.


CLASS lcl_main DEFINITION.
  PUBLIC SECTION.
    METHODS on_double_click
                  FOR EVENT double_click OF cl_salv_events_table
      IMPORTING row column.
    METHODS docker.
    METHODS display.
    METHODS do
      IMPORTING
        i_class  TYPE clike
        i_method TYPE clike
        i_start  TYPE boolean_flg.
  PROTECTED SECTION.
    DATA mt_redef     TYPE STANDARD TABLE OF seoredef.
    DATA mo_docker    TYPE REF TO cl_gui_docking_container.
    DATA mo_editor    TYPE REF TO cl_gui_abapedit.
    METHODS display_source IMPORTING is_source TYPE seoredef.

ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD on_double_click.
    docker( ).
    DATA(redef) = mt_redef[ row ].

    display_source( redef ).

  ENDMETHOD.

  METHOD display_source.
    DATA lt_source TYPE STANDARD TABLE OF string.

    DATA(include) = cl_oo_classname_service=>get_method_include(
                      EXPORTING mtdkey = VALUE #( clsname = is_source-clsname
                                                  cpdname = is_source-mtdname ) ).
    READ REPORT include INTO lt_source.
    mo_editor->set_text( lt_source ).

  ENDMETHOD.

  METHOD docker.

    CHECK mo_docker IS INITIAL.
    mo_docker = NEW #( side = cl_gui_docking_container=>dock_at_right ratio = 50 ).
    mo_editor = NEW #( parent = mo_docker ).
    mo_editor->set_readonly_mode( 1 ).

  ENDMETHOD.

  METHOD display.

    TRY.
        " create SALV
        CALL METHOD cl_salv_table=>factory
          IMPORTING
            r_salv_table = DATA(lr_table)
          CHANGING
            t_table      = mt_redef.

        lr_table->get_functions( )->set_all( ).

        " register event DOUBLE_CLICK
        SET HANDLER on_double_click FOR lr_table->get_event( ).

        " hide columns which are not relevant
        DATA(lr_columns) = lr_table->get_columns( ).
        lr_columns->get_column( 'VERSION' )->set_technical( ).
        lr_columns->get_column( 'MTDABSTRCT' )->set_technical( ).
        lr_columns->get_column( 'MTDFINAL' )->set_technical( ).
        lr_columns->get_column( 'ATTVALUE' )->set_technical( ).
        lr_columns->get_column( 'EXPOSURE' )->set_technical( ).
        lr_table->display( ).
      CATCH cx_salv_error.
    ENDTRY.


  ENDMETHOD.


  METHOD do.

    DATA lr_class TYPE REF TO cl_oo_class.
    DATA lt_subclasses TYPE seo_relkeys.
    DATA ls_subclass   LIKE LINE OF lt_subclasses.

    TRY .
        lr_class ?= cl_oo_class=>get_instance( i_class ).

        LOOP AT lr_class->redefinitions INTO DATA(ls_redef) WHERE mtdname = i_method.
          APPEND ls_redef TO mt_redef.
        ENDLOOP.
        lt_subclasses = lr_class->get_subclasses( ).

        IF i_start = abap_true.
          " search
          LOOP AT lt_subclasses INTO ls_subclass.
            do( i_class  = ls_subclass-clsname
                i_method = i_method
                i_start  = space ).
          ENDLOOP.
        ENDIF.
      CATCH cx_class_not_existent.
    ENDTRY.

  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

  DATA(main) = NEW lcl_main( ).
  main->do( i_class  = p_clas
            i_method = p_meth
            i_start  = abap_true ).
  main->display( ).

and on github: https://github.com/tricktresor/find_redefinitions

 

Assigned Tags

      6 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Scott Lawton
      Scott Lawton

      There's actually a very easy way to do this in ADT. In either the class definition or implementation sections, put your cursor on the name of the method you want to check and hit Ctrl+T. This will display a popup window that shows the inheritance tree. If you do this in the highest level superclass, you can quickly see every subclass that implements the method. Classes that redefine the method are shown with a colored icon and black text; classes that do not redefine the method are grayed out. You can select any class to jump immediately to the method implementation in that class.

      You can also use Ctrl+T in an interface to see every class that implements the interface method and any subclasses of those classes. Again, any classes where the method is implemented or redefined are shown in color and those that do not are grayed out.

      If you're not using ADT yet, I highly recommend it! It takes a little bit of time to get used to it, but once you adjust, there are lots of really great features and improvements over SE80 (especially if you're doing OO development). There are still some limited, specific situations where I need to SE80 (exception classes, primarily), but otherwise, I only use ADT for development now.

       

      Author's profile photo Enno Wulff
      Enno Wulff
      Blog Post Author

      Thanks Scott!

      Great tip! I will try next time.

      Regards
      Enno

      Author's profile photo Matthew Billingham
      Matthew Billingham

      In SAPGUI, open the object tree. Redefined methods are under their own node.

      Author's profile photo Scott Lawton
      Scott Lawton

      Great point! I would say that Crtl+T in ADT is better if you're looking for all of the places a specific method is redefined and the the object tree in SE80 is better if you're looking for every method in a particular class that is redefined somewhere. Using Crtl+T on a class name in ADT shows you every subclass, but not the methods that those subclasses redefine.

      Author's profile photo Enno Wulff
      Enno Wulff
      Blog Post Author

      That's exactly the annoying point:

      Redefined methods are under their own node.

      That means if I have 60 classes I would need to open every single class (+ open redefined methods) to see if there are any. This report shows all of the redefined methods in a list.

      Author's profile photo Kirill Gorin
      Kirill Gorin

      Very nice. We need to compile helpful stuff like this into some mega utility some day and release a single abapgit.