我正在进行的项目在类路径中的类冲突和开发人员重用类名时遇到了可怕的问题。例如,我们有16个,是16个接口,在这个血腥的东西中称为常量,它引起各种各样的问题。
我想实现一个checkstyle检查,它将搜索各种形式的类复制。这是班级
import java.io.File;
import java.util.List;
import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
import com.wps.codetools.common.classpath.ClassScanner;
import com.wps.codetools.common.classpath.criteria.ClassNameCriteria;
import com.wps.codetools.common.classpath.locator.ClasspathClassLocator;
/**
* This codestyle check is designed to scan the project for duplicate class names
* This is being done because it is common that if a class name matches a class
* name that is in a library, the two can be confused. Its in my best practice that
* the class names should be unique to the project.
*
*
*/
public class DuplicateClassNames extends AbstractFileSetCheck {
private int fileCount;
@Override
public void beginProcessing(String aCharset) {
super.beginProcessing(aCharset);
// reset the file count
this.fileCount = 0;
}
@Override
public void processFiltered(File file, List<String> aLines) {
this.fileCount++;
System.out.println(file.getPath());
ClassScanner scanner = new ClassScanner();
scanner.addClassCriteria(new ClassNameCriteria(file.getPath()));
scanner.addClassLocater(new ClasspathClassLocator());
List<Class<?>> classes = scanner.findClasses();
if (classes.size() > 0) {
// log the message
log(0, "wps.duplicate.class.name", classes.size(), classes);
// you can call log() multiple times to flag multiple
// errors in the same file
}
}
}
好的,所以ClassScanner打开了当前JVM的类路径,并使用各种标准进行搜索。这个特殊的是一个类名。它可以进入源文件夹,最重要的是它可以进入类路径中包含的库,并使用ASM搜索jar中的* .class文件。如果它根据显示的条件对象找到副本,则返回文件数组。这仍然需要在主流之前进行一些按摩,但我在这里的时间预算如此快速和肮脏。
我的问题是了解支票本身的输入参数。我从示例中复制了,但看起来CheckStyles为源文件本身提供了一个基本的IO文件对象,并在字符串数组中给出了源文件的内容。
在获得完全限定的类名之前,我是否必须通过另一个处理器运行此数组?
答案 0 :(得分:1)
这比人们想象的更难做,主要是因为Java支持所有类型的嵌套,比如在接口中定义的静态类,匿名内部类等等。此外,您正在扩展AbstractFileSetCheck
,这不是TreeWalker模块,因此您不会获得AST。如果您想要AST,请改为扩展Check
。
由于“快速和脏”是您的选项,您可以简单地从文件名中推断出类名:确定规范路径,从String的开头删除常用目录,用点替换斜杠,切断文件扩展名,你或多或少都在那里。 (当然,不支持内部课程等。)
更好的解决方案可能是扩展Check
并注册PACKAGE_DEF,CLASS_DEF,ANNOTATION_DEF,ENUM_DEF和INTERFACE_DEF。在您的检查中,您将维护在这些位置找到的一堆IDENT,这将为您提供.java文件中的所有完全限定的类名。 (如果你也想要匿名课程,也要注册LITERAL_NEW。我相信你不需要那些。)
后一种解决方案在像Eclipse这样的IDE中不能很好地工作,因为Check生命周期太短,你会不断丢失完全限定的类名列表。但它可以在持续集成系统或其他形式的外部运行中工作。在检查运行之间保留对要维护的类列表的静态引用非常重要。如果您需要Eclipse支持,则必须在Eclipse插件中添加一些可以保留列表的内容(以及以前完整版本中的列表,并保留在某处)。