如何用变体记录代码? (JavaDoc for ifs)
tl; dr是否有JavaDoc for if
s?
介绍
我正在为多个客户撰写企业应用程序。 99%的代码库是共享的,但是每隔一段时间就会有一个像这样的变体:
if (user.hasModule(REPORTS)) {
...conditional code...
}
我现在想为用户记录所有这些变体。 从文档中应该清楚,如果我打开例如。 模块REPORTS
。 我相信这个文档应该用JavaDoc方式编写 - 这意味着它应该尽可能接近条件代码。 它可能看起来像这样:
/** Enables the cool report. */
if (user.hasModule(REPORTS)) {
...conditional code...
}
或这个:
@Doc(text="Enables the cool report.")
if (user.hasModule(REPORTS)) {
...conditional code...
}
或者也许这样:
if (user.hasModule(REPORTS, "Enables the cool report.")) {
...conditional code...
}
结果基本上是每个模块的注释列表。
Module | Comments
----------+--------------------
REPORTS | Enables the cool report.
REPORTS | Allows exporting the reports.
IMPORT | Allows importing the data.
题
如何从代码中收集所有文档注释? 我正在考虑几种方法:
源代码提取
这需要解析器遍历源代码,找到所有这些条件并获取对(模块,注释)。 但是,它必须被挂钩到编译器中,以避免奇怪的格式问题(在长行的中间换行等)。
动态提取
每当在运行时调用user.hasModule()
时,它会记录其实际参数,然后使用此日志构建文档。 因此,例如在beta测试期间,收集文档,然后将其构建到最终版本中。 缺点是很明显的:如果系统的某个部分没有被访问,它就不会被记录下来。
字节码提取
为了避免乱七八糟的源代码,可以直接编译字节码,使用类似ASM的东西来分析它,并找到所有调用user.hasModule()
的地方。 这是我最喜欢的版本,但是在调用invoke_static
,如何确定VM堆栈顶部的实际值是怎么invoke_static
。 必须有一个更简单的方法:)
概要
有这样的工具吗? 我错过了一个简单的方法来做到这一点? 我试图记录这些情况时,我完全被误导了吗? 谢谢!
我认为你在代码中缺少一个概念。
您的模块看起来很像安全组 ,每种用法看起来都很像一个许可 。
如果你要用这种方式来模拟事物,你可以将关于每个模块的用法/许可的知识集中到一个位置。 那么就不需要通过静态分析来扫描代码。
下面的方案使用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
}
这很可能是矫枉过正 - 一个简单的枚举没有所有的自我打字废话可能就足够了。
if user.hasPermission(Permissions.Export)
我会把user.hasModule(REPORTS)==true
时执行的代码放入一个方面。 然后用JavaDoc记录方面。