Если еще проще, то мы взяли dataflow анализатор и еще некоторый функционал из C++ анализатора и прикрутили его к Java анализатору (почти как библиотеку).
Про C# я не знаю наверняка, но думаю что на тот момент и инфраструктура C++ анализатора тоже не позволила бы так просто перенести что-либо в C#.
Да такое мы различаем, благодаря тому, что dataflow взяли из C++. Там ведь возможна аналогичная ситуация:
int *ptr1 = ....;
int *ptr2 = ....;
if (*ptr1 == *ptr2 && ptr1 != ptr2) { .... }
Если в двух словах, то виртуальные значения для ссылок в Java, это наши виртуальные значения для указателей из C++. А виртуальное значение для указателя может, в свою очередь, содержать «boxed» значение (например целого числа, строки, и т.п.).
Ну и соответственно, в одном случае сравниваются виртуальные значения строк, а в другом указателей ссылок.
Как мы видим, changeTracker() просто возвращает указатель из приватного поля d, а displayChanges() просто возвращает bool из приватного поля d.
При этом, между вызовами эти значения не изменяются. Анализатор понимает это и выдает предупреждение.
Т.е. в данном случае анализатор производит анализ тел вызываемых методов и собирает информацию о модифицируемых переменных, а вовсе не ограничивается простым паттерн-матчингом вида x || !x.
Эта информация собирается визитором на стороне Java. А механизм Data-Flow просто не будет задействован в таком случае. Думаю, по возможности, мы как-нибудь расскажем обо всем поподробнее.
На самом деле, генерировать JNI обертки с помощью SWIG не так уж сложно.
Ну и очевидно, что Spoon мы юзаем, из-за того, что наш C++ парсер не очень подходит для разбора Java =).
А вот в механизме Data-Flow ничего специально мы не делали, чтобы поддержать такое в Java.
В ваших примерах варнинги не сохраняются, раз вы предоставляете публичный интерфейс для изменения содержимого массива.
Можно, конечно, упомянуть межмодульный анализ, однако вряд ли разработчики библиотеки станут без необходимости делать этот массив публичным.
Вот небольшая заметка на тему синтетических тестов.
На мой взгляд, Data Flow анализ в нем слабый. Явно слабее того, что мы можем предоставить уже сейчас.
Кроме того, механизм аннотаций не развит. Не находятся ошибки такого типа:
int test1(int a, int b)
{
int x = Math.max(a, a); // <=
return x + b;
}
String test2(String a)
{
return a.replace("aaa", "aaa"); // <=
}
Подобные ошибки часто допускают из-за опечаток и упускать их точно не стоит.
При этом, без предварительной настройки, SonarLint уж очень сильно «шумит».
Также, у нас есть ряд уникальных диагностик в C++ и C# анализаторах, которые будут перенесены в анализатор Java.
Короче говоря, конкурентные преимущества будут.
Для прототипа мы решили использовать дерево и семантическую модель из spoon, т.к это позволяет существенно ускорить разработку.
Поэтому и сами диагностические правила также пишутся на Java.
Так написать можно. Structured bindings, как было сказано в статье, умеют производить декомпозицию типов, содержащих только нестатические открытые члены.
Такой паттерн это же явно баг.
Про C# я не знаю наверняка, но думаю что на тот момент и инфраструктура C++ анализатора тоже не позволила бы так просто перенести что-либо в C#.
Если в двух словах, то виртуальные значения для ссылок в Java, это наши виртуальные значения для указателей из C++. А виртуальное значение для указателя может, в свою очередь, содержать «boxed» значение (например целого числа, строки, и т.п.).
Ну и соответственно, в одном случае сравниваются виртуальные значения строк, а в другом
указателейссылок.Так что стараемся учитывать подобный код.
Что-то мне подсказывает, что здесь скопипастили и забыли во втором случае поменять definition на metadata.
V6029 Possible incorrect order of arguments passed to method: 'parent', 'profile'. InheritanceActionTest.java 254:
RuleActivator.java
Пример неудачный, заменил его другим.
Как мы видим,
changeTracker()
просто возвращает указатель из приватного поляd
, аdisplayChanges()
просто возвращаетbool
из приватного поляd
.При этом, между вызовами эти значения не изменяются. Анализатор понимает это и выдает предупреждение.
Т.е. в данном случае анализатор производит анализ тел вызываемых методов и собирает информацию о модифицируемых переменных, а вовсе не ограничивается простым паттерн-матчингом вида
x || !x
.Ну и очевидно, что Spoon мы юзаем, из-за того, что наш C++ парсер не очень подходит для разбора Java =).
А вот в механизме Data-Flow ничего специально мы не делали, чтобы поддержать такое в Java.
В ваших примерах варнинги не сохраняются, раз вы предоставляете публичный интерфейс для изменения содержимого массива.
Можно, конечно, упомянуть межмодульный анализ, однако вряд ли разработчики библиотеки станут без необходимости делать этот массив публичным.
Вот небольшая заметка на тему синтетических тестов.
На мой взгляд, Data Flow анализ в нем слабый. Явно слабее того, что мы можем предоставить уже сейчас.
Кроме того, механизм аннотаций не развит. Не находятся ошибки такого типа:
Подобные ошибки часто допускают из-за опечаток и упускать их точно не стоит.
При этом, без предварительной настройки, SonarLint уж очень сильно «шумит».
Также, у нас есть ряд уникальных диагностик в C++ и C# анализаторах, которые будут перенесены в анализатор Java.
Короче говоря, конкурентные преимущества будут.
Поэтому и сами диагностические правила также пишутся на Java.
std::is_class
илиstd::is_arithmetic
.