Как написать пользовательскую проверку Checkstyle с косвенным наследованием? - PullRequest
3 голосов
/ 15 октября 2011

Нам нужно написать пользовательскую проверку checkstyle, которая проверяет определенное условие для классов, которые наследуют - прямо или косвенно - от определенного класса A. Можно ли идентифицировать косвенное наследование с помощью API checkstyle? Например, предположим, что у нас есть:

  • Класс C --- расширяется ---> Класс B
  • Класс B --- расширяется ---> Класс A

В этом случае легко проверить, что C является подклассом B, ища токен «extends» (TokenTypes.EXTENDS_CLAUSE) и ища B в предложении extends AST. Но как мы можем знать, что C также является подклассом A?

Является ли Java-отражение плюс экземпляр единственным выходом? ( Не желательно в нашем случае, так как мы должны выполнить проверку более тысячи файлов.)

Позволит ли PMD или другой инструмент статического анализа написать пользовательскую проверку с этим условием (косвенное наследование)?

Ответы [ 2 ]

2 голосов
/ 24 ноября 2011

Это можно сделать, но не легко, потому что в checkstyle нет компилятора Java.Таким образом, он может только смотреть на исходный текст и анализировать его синтаксическое дерево, но не может его «понять».

Итак, вы должны загрузить класс из проверки вашего контрольного стиля.

Для этого вам, скорее всего, потребуется определить собственный загрузчик классов, чтобы вы могли загрузить класс, скажем, из вашего рабочего пространства eclipse (или из любого другого источника).

Теперь вы можете просто позвонить instanceof A и вуаля!

Я бы не стал беспокоиться о производительности.Вы можете добавить LRU-кэш файлов классов в свой пользовательский загрузчик классов, что бы разрешить это.Кроме того, если проверка выполняется в вашей среде IDE, ей нужно только загрузить очень мало классов (тех, которые находятся в дереве прямого наследования), а если она выполняется на всем источнике, она будет работать ночью, нет?

Поскольку этот вопрос уже довольно старый, дайте мне знать, если вам нужен пример кода.

0 голосов
/ 24 апреля 2013

Мы решили проблему с отражением Java:

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

Это ограничивает применимость пользовательской проверки, поскольку она работает только в том случае, если ClassA и ClassC находятся в пути к классам.

...