开发者

How to write a Checkstyle custom check involving indirect inheritance?

开发者 https://www.devze.com 2023-04-13 07:30 出处:网络
We need to write a checkstyle custom check that verifies a specific condition for classes that inherit—directly or indirectly—from a certain class A. Is it possible to identify the indirect inherita

We need to write a checkstyle custom check that verifies a specific condition for classes that inherit—directly or indirectly—from a certain class A. Is it possible to identify the indirect inheritance using the checkstyle API? For example, suppose we have:

  • Class C ---extends---> class B
  • Class B ---extends---> class A

In this case, it’s easy to check that C is a subclass of B by looking for开发者_如何学JAVA the “extends” token (TokenTypes.EXTENDS_CLAUSE) and looking for B in the extends clause AST. But how can we know that C is also a subclass of A?

Is Java reflection plus instanceof the only way out? (Not desirable in our case as we have to run the check over thousands of files.)

Would PMD or another static analysis tool allow me to write a custom check with that (indirect inheritance) condition?


It can be done, but not easily, because checkstyle has no Java compiler. So it can only look at the source text and analyze its syntax tree, but it cannot "understand" it.

So, you must load the class from within your checkstyle check.

For this, you will most likely need to define your own class loader, so that you can load the class from, let's say, your eclipse workspace (or from whereever else your sources are).

Now you can simply call instanceof A and voilà!

I wouldn't worry about performance. You could add an LRU cache of class files to your custom class loader, which would resolve that. Also, if the check runs in your IDE, it only needs to load very few classes (those in the direct inheritance tree), and if it runs on the entire source, it will run at night, no?

Since this question is already quite old, let me know if you need a code example.


We have solved the problem with Java reflection:

Class<?> clazz = Class.forName(ClassA);
if (ClassC.class.isAssignableFrom(clazz)) {
    // Class C is a direct or indirect subclass of ClassA
}

It limits the applicability of the custom check though, because it only works if ClassA and ClassC are in the classpath.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号