Правило Sonarqube: определение нескольких вызовов методов в одной строке - PullRequest
0 голосов
/ 22 мая 2018

Я пытаюсь реализовать пользовательское правило SonarQube-Rule, которое идентифицирует использование API потока Java и обнаруживает нарушение, когда в одной и той же кодовой строке вызывается более одного метода после вызова .stream.

Пример:

// BAD CODE:
strings.stream().filter(s -> s.length() > 2).sorted()
.map(s -> s.substring(0, 2)).collect(Collectors.toList());

// GOOD CODE:
strings.stream()
.filter(s -> s.length() > 2)
.sorted()
.map(s -> s.substring(0, 2))
.collect(Collectors.toList());

Я уже определил различные вызовы методов через посетителя MethodInvocationTree, но как я могу идентифицировать их как вызовы метода stream (), отличая их от всех других вызовов метода?в моем коде?Особенно потому, что мои вызовы метода параметров также идентифицируются как AST MethodInvocationTree.

Возможно, есть вспомогательный класс SonarQube, который помогает мне углубиться в AST или позволяет выбрать точные части нужного мне AST,как у PMD node.getFirstChildOfType(ASTTree.class)?

Большое спасибо за вашу помощь!

1 Ответ

0 голосов
/ 22 мая 2018

Чтобы ответить на ваш последний вопрос, API SonarJava не предоставляет никакого способа фильтрации дочерних элементов непосредственно из AST по их древовидному виду.Это должно быть сделано во время посещения.

Теперь, возможно, есть несколько способов достичь того, что вы пытаетесь сделать, но вам наверняка потребуется работать как с синтаксисом, так и с семантическим API.Обратите внимание, что это правило может потребовать много работы, чтобы охватить все случаи.

Я бы посоветовал вам взглянуть на дерево methodSelect MethodInvocationTree и оттудапроверьте, если сначала это MemberSelectExpressionTree, получите идентификатор, а затем снова MethodInvocationTree от выбранного члена.Зацикливаясь на нем, пока вы не достигнете чего-то, что не является вызовом метода или напрямую идентификатором, вы должны собрать все вызовы метода.Теперь возникает вопрос, как убедиться, что это метод из java.util.stream.Stream.

После сбора для каждого вызова метода в цепочке вы можете использовать семантический API для доступа к symbol() соответствует вызванному методу.Если методы правильно разрешены семантическим механизмом (для анализа предоставлен байт-код, правильное вычисление механизма вывода, символ не помечен как unknown), вы сможете проверить тип владелец метода.Для всех этих методов владельцем должно быть java.util.stream.Stream.

...