重复项查找器(Java)
Duplicates Finder (Java) 构建运行程序旨在捕获相似的代码片段,并提供关于发现的 Java 代码的重复块的报告。 这个运行器基于 IntelliJ IDEA 的功能,因此,需要 IntelliJ IDEA 项目文件( .ipr
)或目录( .idea
)来配置运行器。
除了捆绑版本外,还可以安装另一个版本的 JetBrains IntelliJ Inspections 和 Duplicates Engine,并/或使用 Administration | Tools 页面更改默认设置。
重复项查找器(Java)运行程序还可以在由Maven2或更高版本构建的项目中查找Java重复项。
此页面包含以下 Duplicates Finder (Java)构建运行程序字段的参考信息。
IntelliJ IDEA 项目设置
选项 | 描述 |
---|---|
项目文件类型 | 为了能够在您的代码上运行 IntelliJ IDEA 检查,TeamCity 需要在此处指定一个 IntelliJ IDEA 项目文件 / 目录,Maven |
项目的路径 | 依据在 项目文件类型 中选择的项目类型,这里请指定:
这些信息是构建运行程序需要的,以理解项目的结构。 |
在 | 如果您使用的是 IntelliJ IDEA 项目,此选项将可用。在 IntelliJ IDEA 中,模块设置存储在 |
检查 / 重新解析项目 | 如果您使用 IntelliJ IDEA 项目,此选项就可用。点击此按钮以重新解析您的 IntelliJ IDEA 项目并直接从项目中导入构建设置,例如 JDK 的列表。 |
工作目录 | 如果与 Build Checkout Directory 不同,请输入到 Build Working Directory 的路径。 如有不同,可选地指定与检出目录不同的目录。 |
未解决的项目模块和路径变量
当一个 IntelliJ IDEA 模块文件( .iml
)被一个 IPR 文件引用时,这个部分会显示:
找不到;
允许您输入在 IPR-file 中使用的路径变量的值。
要刷新此部分中的值,点击 检查/重新解析项目。
选项 | 描述 |
---|---|
<path_variable_name> | 如果项目文件包含路径宏,则此字段会出现,路径宏在 IntelliJ IDEA 设置的 路径变量 对话框中定义。 在 设置字段值 中,指定一个路径到要在不同构建代理上使用的项目资源。 |
项目 JDKs
这一部分提供了项目中检测到的 JDKs 列表。
选项 | 描述 |
---|---|
JDK 主页 | 使用此字段来指定项目的 JDK 主目录。 |
JDK Jar 文件模式 | 点击此链接可打开一个文本区域,您可以在此处为项目 JDK 的 jar 文件定义模板。 使用 Ant 规则来定义 jar 文件模式。 默认值适用于 Linux 和 Windows 操作系统: jre/lib/*.jar
对于 macOS ,请使用以下行: lib/*.jar
../Classes/*.jar
|
IDEA 主页 | 如果您的项目使用 IDEA JDK,请指定 IDEA 主目录的位置。 |
IDEA Jar 文件模式 | 点击此链接以打开一个文本区域,您可以在此处为 IDEA JDK 的 jar 文件定义模板。 |
选项 | 描述 |
---|---|
JDK | 选择一个 JDK。 本节详述了可用的选项。 默认值为 |
JDK 主目录路径 | 当上方选择了 <Custom> 时,此选项便可用。使用此字段来指定用于运行构建的自定义 JDK 的路径。 如果该字段为空,则会从代理机器的 |
JVM 命令行参数 | 附加的 JVM 命令行参数允许您设置初始和最大堆大小,启用额外的日志记录,选择所需的字节码验证器模式等等。 您可以指定标准的(例如以 要指定多个命令行参数,使用空格作为分隔符。 例如: -verbose:gc -Xdiag -Xcomp -Xmx512m -Xms256m |
Java 参数
重复查找器设置
选项 | 描述 |
---|---|
测试源代码 | 如果勾选此选项,测试源代码将会被包含在重复项分析中。 |
包含 / 排除模式 | 可选,指定以限制运行重复分析的源范围。 有关详细信息,请参阅下面的章节 below。 |
详细程度 | 使用这些选项来定义在搜索重复代码片段时应区分源代码的哪些元素。 如果代码片段在结构上相似,但包含不同的变量、字段、方法、类型或字面量,那么它们可以被认为是重复的。 请参考以下示例: |
区分变量 | 如果勾选此选项,具有不同变量名称的相似内容将被识别为不同内容。 如果此选项未被选中,以下内容将被识别为重复: public static void main(String[] args) {
int i = 0;
int j = 0;
if (i == j) {
System.out.println("sum of " + i + " and " + j + " = " + i + j);
}
long k = 0;
long n = 0;
if (k == n) {
System.out.println("sum of " + k + " and " + n + " = " + k + n);
}
}
|
区分字段 | 如果勾选此选项,具有不同字段名称的相似内容将被识别为不同的内容。 如果此选项未被选中,以下内容将被识别为重复: myTable.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
}
/*.....**/
});
myTree.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
}
/*.....**/
});
|
区分方法 | 如果勾选了此选项,将会把结构类似的方法认定为不同的。 如果未选中此选项,这样的方法将被识别为重复的。 在这种情况下,它们可以被提取并重复使用。 初始版本: public void buildCanceled(Build build, SessionData data) {
/* ... **/
for (IListener listener : getListeners()) {
listener.buildCanceled(build, data);
}
}
public void buildFinished(Build build, SessionData data) {
/* ... **/
for (IListener listener : getListeners()) {
listener.buildFinished(build, data);
}
}
在不区分方法的情况下分析代码重复部分后,可以提取出重复的片段: public void buildCanceled(final Build build, final SessionData data) {
enumerateListeners(new Processor() {
public void process(final IListener listener) {
listener.buildCanceled(build, data);
}
});
}
public void buildFinished(final Build build, final SessionData data) {
enumerateListeners(new Processor() {
public void process(final IListener listener) {
listener.buildFinished(build, data);
}
});
}
private void enumerateListeners(Processor processor) {/* ... **/
for (IListener listener : getListeners()) {
processor.process(listener);
}
}
private interface Processor {
void process(IListener listener);
}
|
区分类型 | 如果勾选此选项,具有不同类型名称的相似代码片段将被识别为不同。 如果未选中此选项,此类代码片段将被识别为重复。 new MyIDE().updateStatus()
new TheirIDE().updateStatus()
|
区分字面量 | 如果勾选了此选项,具有不同字面量的相似代码行将被视为不同。 如果此选项未被勾选,这类行将被认定为重复项。 myWatchedLabel.setToolTipText("Not Logged In");
myWatchedLabel.setToolTipText("Logging In...");
|
忽略复杂度低于此值的重复项 | 源代码的复杂性由语句、表达式、声明和方法调用的数量定义。 每个复杂性都是由其成本来定义的。 总结所有这些源代码片段元素的成本,得出总体复杂性。 使用此字段来指定在检测重复项时需考虑的源代码的最低复杂度级别。 为了获得有意义的结果,从值 10 开始。 |
忽略复杂度低于的重复子表达式 | 使用此字段来指定在检测重复项时考虑的子表达式的最低复杂性级别。 |
检查子表达式是否可以被提取 | 如果勾选此选项,可以提取重复的子表达式。 |
包含 / 排除模式是一种按新行分隔的规则集,其格式为:
模式必须满足以下规则:
必须以
**
或*
结尾(这实际上将模式限制在了目录级别,它们不支持文件级别的模式)对模块的引用可以作为
[module_name] / <模块内路径>
关于模式处理的一些说明:排除具有优先于包含的优先级
如果指定了包含模式,只有匹配这些模式的目录将被包含,所有其他目录将被排除
"include" 模式具有特殊行为(由于底层限制):它包括指定的目录及其上层目录中直接驻留的所有文件。
示例: