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

相关推荐
shengjk17 分钟前
序列化和反序列化:从理论到实践的全方位指南
java·大数据·开发语言·人工智能·后端·ai编程
hie988941 小时前
使用Spring Boot集成Nacos
java·spring boot·后端
源码方舟1 小时前
基于SpringBoot+Vue的房屋租赁管理系统源码包(完整版)开发实战
vue.js·spring boot·后端
景天科技苑2 小时前
【Rust trait特质】如何在Rust中使用trait特质,全面解析与应用实战
开发语言·后端·rust·trait·rust trait·rust特质
Mikey_n3 小时前
Spring Boot 注解详细解析:解锁高效开发的密钥
java·spring boot·后端
Kookoos3 小时前
【实战】基于 ABP vNext 构建高可用 S7 协议采集平台(西门子 PLC 通信全流程)
后端·物联网·c#·.net
帮帮志3 小时前
vue3与springboot交互-前后分离【完成登陆验证及页面跳转】
spring boot·后端·交互
炒空心菜菜13 小时前
SparkSQL 连接 MySQL 并添加新数据:实战指南
大数据·开发语言·数据库·后端·mysql·spark
蜗牛沐雨15 小时前
Rust 中的 `PartialEq` 和 `Eq`:深入解析与应用
开发语言·后端·rust
Python私教15 小时前
Rust快速入门:从零到实战指南
开发语言·后端·rust