如何使用变体记录代码?(ifs的JavaDoc)

vek*_*tor 7 java javadoc

tl; dr是否有JavaDoc for ifs?

介绍

我正在为多个客户编写企业应用程序.99%的代码库是共享的,但不时有这样的变体:

if (user.hasModule(REPORTS)) { 
  ...conditional code... 
}
Run Code Online (Sandbox Code Playgroud)

我现在想为用户记录所有这些变体.从文档中可以清楚地看到,如果我打开,会发生什么.模块REPORTS.我相信这个文档应该用JavaDoc方式编写 - 这意味着它应该尽可能接近条件代码.它可能看起来像这样:

/** Enables the cool report. */
if (user.hasModule(REPORTS)) { 
  ...conditional code... 
}
Run Code Online (Sandbox Code Playgroud)

或这个:

@Doc(text="Enables the cool report.")
if (user.hasModule(REPORTS)) { 
  ...conditional code... 
}
Run Code Online (Sandbox Code Playgroud)

或许这个:

if (user.hasModule(REPORTS, "Enables the cool report.")) { 
  ...conditional code... 
}
Run Code Online (Sandbox Code Playgroud)

结果基本上是每个模块的注释列表.

Module    | Comments
----------+--------------------
REPORTS   | Enables the cool report.
REPORTS   | Allows exporting the reports.
IMPORT    | Allows importing the data.
Run Code Online (Sandbox Code Playgroud)

如何从代码中收集所有文档注释?我正在考虑几种方法:

源代码提取

这将需要解析器遍历源代码,找到所有这些条件和获取对(模块,注释).但是,它必须连接到编译器以避免奇怪的格式化问题(长行中间的换行符等).

动态提取

无论何时user.hasModule()在运行时调用它记录其实际参数,该日志随后用于构建文档.因此,例如在beta测试期间,文档被收集,然后内置到最终版本中.缺点很明显:如果系统的某个部分未被访问,则不会记录.

字节码提取

为了避免凌乱的源代码,人们可以直接找到编译的字节码,用ASM之类的东西进行分析,找到所有user.hasModule()被调用的地方.这是我最喜欢的版本,但是在调用时如何弄清楚VM堆栈顶部的实际值是多么困难invoke_static.必须有一个更简单的方法:)

摘要

有这个工具吗?我错过了一个简单的方法吗?在我试图记录这些情况时,我是否完全被误导了?谢谢!

hen*_*nry 2

我认为您的代码中缺少一个概念。

您的模块看起来很像安全,每种用法看起来很像权限

如果您要以这种方式建模,您可以将每个模块的用法/权限的知识集中到一个位置。这样就不需要通过静态分析来扫描代码。

下面的方案使用 Java 类型系统来确保您无法在不先为该模块创建新权限的情况下为该模块添加 if 语句。

通过使用一些 java 循环遍历枚举值,可以轻松地从此代码生成权限和描述的完整列表。

public interface User {
 public <T extends Module<T>> boolean hasPermission(Module<T> module, Permission<T> usage);
 }

public interface Permission<T extends Module<T>> {
  String describe();
}

enum Reports implements Module<Reports> {
  REPORTS
}

enum ReportsPermissions implements Permission<Reports> {
   ENABLE_COOL_REPORT("Enables the cools reports"),
   ALLOWS_EXPORTING_THE_REPORTS("Allow exports the cools reports");

   private final String description;

    ReportsPermissions(String description) {
      this.description = description;
    }

    @Override
    public String describe() {
      return description;
     } 
  }

  enum ImportPermissions implements Permission<Import> {
    ALLOWS_IMPORTING("Allows importing the data.");
    etc
  }
Run Code Online (Sandbox Code Playgroud)

这很可能是矫枉过正——一个简单的枚举,没有所有自输入的废话可能就足够了。

if user.hasPermission(Permissions.Export)