ABAP Open Checks:开源检查 SAP 代码检查器/ATC

ABAP Open Checks 是一个开源项目,旨在增强 SAP Code Inspector 和 ABAP Test Cockpit (ATC) 的功能。它为 ABAP 代码提供了广泛的附加检查,超出了 SAP 环境中可用的标准检查范围。这些检查涵盖 ABAP 编程最佳实践、代码清洁、性能优化等各个方面,旨在提高 ABAP 代码库的质量和可维护性。

安装

该项目允许您通过 abapGit 进行安装和配置,其设计旨在无需在客户系统中创建新对象即可进行单元测试。或将源代码手动复制到系统中。通过 abapGit 安装需要创建一个空软件包,例如 $AOC

SCI 设置

  • 在事务 SCI 中激活检查(取决于版本)
    • 转到 -> 管理 -> 测试
    • 代码检查器 -> 管理 -> 测试
    • 代码检查器 -> 管理 -> 检查

将这些检查全部勾选上,你也可以选择你需要的。

  • 配置检查变量

更新

使用 upDOWNci 备份变量。

运行 abapGit,点击 "pull"。请注意,该选项只有在新代码已添加到版本库时才会显示。

如果使用 abapGit 的离线项目功能,也可点击 "导入 zip"。

卸载

运行 abapGit,点击 "卸载"。

它仅支持英语,适用于 SAP 系统 7.40 SP02 或更高版本。检查范围从验证 IF 条件、循环、TRY-CATCH 块的使用,到执行命名约定、检查过时语句等等。

您可以在其文档网站上找到 ABAP Open Checks 所提供的具体检查的完整列表,包括行长检查、ASCII 合规性检查、漂亮的打印机使用、CALL METHOD 的功能性书写风格以及其他许多旨在执行编码标准和提高代码质量的检查。

Check if 存在多层嵌套

通过这个工具,可以将两层嵌套:

erlang 复制代码
IF condition1.
  IF condition2.
    ...
  ENDIF.
ENDIF.

可缩减为:

erlang 复制代码
IF ( condition1 ) AND ( condition2 ).
  ...
ENDIF.

或者将:

erlang 复制代码
ELSE.
  IF condition.
    ...
  ENDIF.
ENDIF.

可缩减为:

erlang 复制代码
ELSEIF condition.
  ...
ENDIF.

源码:

ABAP 复制代码
CLASS zcl_aoc_check_01 DEFINITION
  PUBLIC
  INHERITING FROM zcl_aoc_super
  CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS constructor.

    METHODS check
        REDEFINITION.

  PROTECTED SECTION.
    METHODS contains_else
      IMPORTING
        !io_structure  TYPE REF TO zcl_aoc_structure
      RETURNING
        VALUE(rv_bool) TYPE abap_bool.
    METHODS run_check
      IMPORTING
        !io_structure TYPE REF TO zcl_aoc_structure
        !io_scan      TYPE REF TO zcl_aoc_scan.

  PRIVATE SECTION.
ENDCLASS.



CLASS zcl_aoc_check_01 IMPLEMENTATION.


  METHOD check.

* abapOpenChecks
* https://github.com/larshp/abapOpenChecks
* MIT License

    DATA: lo_structure TYPE REF TO zcl_aoc_structure.


    lo_structure = zcl_aoc_structure=>build(
      it_tokens     = io_scan->tokens
      it_statements = io_scan->statements
      it_structures = io_scan->structures ).

    run_check(
      io_structure = lo_structure
      io_scan      = io_scan ).

  ENDMETHOD.


  METHOD constructor.

    super->constructor( ).

    version        = '001'.
    position       = '001'.

    has_attributes = abap_true.
    attributes_ok  = abap_true.

    enable_rfc( ).
    enable_checksum( ).

    insert_scimessage(
      iv_code = '001'
      iv_text = 'IF in IF, can easily be reduced'(m01) ).

  ENDMETHOD.


  METHOD contains_else.

    DATA: lo_structure TYPE REF TO zcl_aoc_structure.

    LOOP AT io_structure->get_structure( ) INTO lo_structure.
      IF lo_structure->get_type( ) = zcl_aoc_scan=>gc_structure_statement-else
          OR lo_structure->get_type( ) = zcl_aoc_scan=>gc_structure_statement-elseif.
        rv_bool = abap_true.
        RETURN.
      ENDIF.
    ENDLOOP.

  ENDMETHOD.


  METHOD run_check.

    DATA: lo_structure TYPE REF TO zcl_aoc_structure,
          lo_then      TYPE REF TO zcl_aoc_structure,
          lv_include   TYPE program,
          lv_if        TYPE i,
          lv_other     TYPE i,
          lv_row       TYPE token_row,
          lv_position  LIKE sy-tabix.


    IF io_structure->get_type( ) = zcl_aoc_scan=>gc_structure_statement-if
        OR io_structure->get_type( ) = zcl_aoc_scan=>gc_structure_statement-else.

      IF io_structure->get_type( ) = zcl_aoc_scan=>gc_structure_statement-if.
        READ TABLE io_structure->get_structure( ) INDEX 1 INTO lo_then.
        ASSERT sy-subrc = 0.

        LOOP AT io_structure->get_structure( ) INTO lo_structure.
          CASE lo_structure->get_type( ).
            WHEN zcl_aoc_scan=>gc_structure_statement-elseif
                OR zcl_aoc_scan=>gc_structure_statement-else.
              lv_if = lv_if + 2.
          ENDCASE.
        ENDLOOP.
      ELSE.
        lo_then = io_structure.
      ENDIF.

      LOOP AT lo_then->get_structure( ) INTO lo_structure.
        CASE lo_structure->get_type( ).
          WHEN zcl_aoc_scan=>gc_structure_statement-if.
            IF contains_else( lo_structure ) = abap_true
                AND io_structure->get_type( ) = zcl_aoc_scan=>gc_structure_statement-if.
              lv_if = lv_if + 1.
            ENDIF.
            lv_if = lv_if + 1.
          WHEN OTHERS.
            lv_other = lv_other + 1.
        ENDCASE.
      ENDLOOP.
    ENDIF.

    IF lv_if = 1 AND lv_other = 0.
      lv_include = io_scan->get_include( io_structure->get_statement( )-level ).

      lv_row = io_structure->get_statement( )-row.
      READ TABLE io_scan->statements WITH KEY trow = lv_row TRANSPORTING NO FIELDS.
      lv_position = sy-tabix.

      inform( p_sub_obj_name = lv_include
              p_position     = lv_position
              p_line         = lv_row
              p_kind         = mv_errty
              p_test         = myname
              p_code         = '001' ).
    ELSE.
      LOOP AT io_structure->get_structure( ) INTO lo_structure.
        run_check( io_structure = lo_structure
                   io_scan      = io_scan ).
      ENDLOOP.
    ENDIF.

  ENDMETHOD.
ENDCLASS.

测试代码

dart 复制代码
*&---------------------------------------------------------------------*  
*& Report ZCHECK01  
*&---------------------------------------------------------------------*  
*&  
*&---------------------------------------------------------------------*  
REPORT zcheck01.  
  
DATA: num TYPE i.  
num = 1.  
IF num <= 2.  
  IF num MOD 2 <> 0.  
    WRITE: num.  
  ENDIF.  
ENDIF.

Open Checks 检查结果:

  1. 嵌套循环
  1. 不应该声明字段 num 为全局变量
  1. 不好的命名方式,全局变量应该 gv_ 开头,但是我们只命名了 num

其他检查结果,大家可以结合实际进行探索。

开源地址:larshp/abapOpenChecks: Open source checks for SAP Code Inspector / ABAP Test Cockpit (github.com)

文档地址:abapOpenChecks - Checks

相关推荐
鬼火儿4 小时前
SpringBoot】Spring Boot 项目的打包配置
java·后端
cr7xin4 小时前
缓存三大问题及解决方案
redis·后端·缓存
间彧5 小时前
Kubernetes的Pod与Docker Compose中的服务在概念上有何异同?
后端
间彧6 小时前
从开发到生产,如何将Docker Compose项目平滑迁移到Kubernetes?
后端
间彧6 小时前
如何结合CI/CD流水线自动选择正确的Docker Compose配置?
后端
间彧6 小时前
在多环境(开发、测试、生产)下,如何管理不同的Docker Compose配置?
后端
间彧6 小时前
如何为Docker Compose中的服务配置健康检查,确保服务真正可用?
后端
间彧6 小时前
Docker Compose和Kubernetes在编排服务时有哪些核心区别?
后端
间彧6 小时前
如何在实际项目中集成Arthas Tunnel Server实现Kubernetes集群的远程诊断?
后端
brzhang6 小时前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构