Насчёт совместимости и raw-типов. Задача: есть старая версия Java-класса, где некий метод возвращает raw List, и новая версия, где List<String>. Могу ли я сделать Котлин-класс, который вызывает этот метод и способен линковаться с любой из этих двух версий? Скажем, я пишу плагин к системе и хочу уметь работать со старой и новой версией системы. На чистой джаве никаких проблем нет, такое изменение не считается ломающим совместимость на уровне исходного кода.
Любая свобода в стандарте — это простор для оптимизации компилятора, чем компиляторы и пользуются. Полагаю, что тут вне зависимости от целевой архитектуры (где-нибудь на уровне middle level intermediate language) компилятор заметил, что указатели основаны на разных объектах, а значит, легально заменить выражение сравнения на константу 0. Кодогенератор целевой платформы в бэкенде компилятора уже не видит сравнения, а видит просто 0. Возможна и более агрессивная оптимизация, когда этот ноль прямо подставится в строку формата "%p %p 0" на этапе компиляции.
Интересно, а array overrun — это у вас потоковый анализ ловит или по шаблонам находите? А если потоковый, то как вы доказываете, что состояние index == size действительно достижимо, а не эфемерно? В общем случае этого нельзя доказать статически, всегда можно придумать код, на котором будет ложная сработка. Как такие сработки свести к минимуму?
Некоторые ошибки из статьи некритичны. Например, size_t pos = i * 2 + (v1 == 0xff) ? 1 : 2; ведёт только к неправильном у логированию в случае какой-то другой ошибки. Вообще ветки обработки ошибок как правило самые недотестированные.
И разница, кстати, большая. Вы огребёте большое количество ложных сработок на котлиновском байткоде, если возьмётесь его анализировать джавовским анализатором байткода. Я пробовал.
Нет, я про другой пример. Нумеруйте их что ли, чтобы ссылаться можно было =)
public static boolean equal(byte[] arg1, final int start1,
final int len1, byte[] arg2,
final int start2, final int len2) {
if (len1 != len2) { // <=
return false;
}
if (len1 == 0) {
return true;
}
....
if (len1 == len2) { // <=
....
}
}
Почему невозможно? Возможно. Во-первых, у нас кода нереально больше, чем у вас. У нас не статический анализатор, а IDE, которая поддерживает уйму языков и миллион фич вроде интеграции с Git, Docker и чёрт знает что ещё. Во-вторых, я, например, никогда не коммичу жёлтый код. В новом коде от меня варнингов нет. Если я редактирую существующий код, я по возможности заодно исправляю варнинги в нём. Многие поступают так же.
Ну и вы же сами зачем-то поддерживаете режим «показать только свежие предупреждения». По вашей логике, если эта фича востребована, значит, вашим анализатором тоже невозможно пользоваться ;-)
Ну и code smells — понятие растяжимое. Пример метода equal из Hive в этой статье — вполне себе code smell. Условие избыточно и всегда истинно, но не приводит ни к каким проблемам. Если его убрать, поведение метода не меняется ни при каких входных данных. Так что это не баг.
Это тут ни при чём. Там и реальных проблем полно, десятки тысяч, и можно сделать профиль инспекций, который только реальные проблемы будет показывать. Особенно с nullability много. Это механически не исправишь, там в каждом месте смотреть надо.
Это ни о чём не говорит. Идейка в сорцах Идейки находит двести тысяч предупреждений. В том числе и те, которые в посте есть. Просто не всегда доходят руки их исправить.
У нас в Идейке parse tree с full fidelity, конечно, но это не сильно усложняет потоковый анализ. Конечно, у нас и вычисление типов, и резолв ссылок сделан. В байткоде с этим проще, но и свои минусы есть — erasure. Восстановить generic-сигнатуру бывает очень сложно (эту задачу решают декомпиляторы). С байткодом, кстати, ещё большой минус — привязать предупреждение к конкретному элементу исходника. Там только номера строк есть, если отладочную инфу генерировали. Иногда это сильно усложняет понимание, где же ошибка.
На уровне байткода анализировать джаву — довольно тупиковый путь. Я писал свой анализатор на байткоде. Некоторые проблемы в принципе не увидишь. Надо быть как можно ближе к исходникам.
Я вот даже не уверен, что автоматическое удаление скобок в Spoon — это хорошая идея. Например, a << 16 + b похоже на ошибку: приоритет сложения выше, чем сдвига, а выглядит так будто автор забыл про это. С другой стороны, a << (16 + b) уже выглядит сознательным решением, и тут предупреждать не надо. Если есть дерево без скобок, эту разницу не увидишь. Даже комментарии в коде и отступы очень важны для статического анализа.
Ничего себе! У нас только dataflow выдаёт больше 10000 предупреждений, а все включённые инспекции на всём коде Идеи — около 200000. Что с ними делать — абсолютно непонятно :-D
Это ea, релиза же нету ещё. Релизной oracle jdk не будет бесплатно.
Насчёт совместимости и raw-типов. Задача: есть старая версия Java-класса, где некий метод возвращает raw List, и новая версия, где
List<String>
. Могу ли я сделать Котлин-класс, который вызывает этот метод и способен линковаться с любой из этих двух версий? Скажем, я пишу плагин к системе и хочу уметь работать со старой и новой версией системы. На чистой джаве никаких проблем нет, такое изменение не считается ломающим совместимость на уровне исходного кода.Первая ошибка крутая, молодцы!
Вы в test.fish в командную строку компилятора не добавили опцию -O, только вывели её на экран.
Любая свобода в стандарте — это простор для оптимизации компилятора, чем компиляторы и пользуются. Полагаю, что тут вне зависимости от целевой архитектуры (где-нибудь на уровне middle level intermediate language) компилятор заметил, что указатели основаны на разных объектах, а значит, легально заменить выражение сравнения на константу 0. Кодогенератор целевой платформы в бэкенде компилятора уже не видит сравнения, а видит просто 0. Возможна и более агрессивная оптимизация, когда этот ноль прямо подставится в строку формата
"%p %p 0"
на этапе компиляции.Необязательно такой код придумывать из головы, можно и в дикой природе найти.
Ну я же конкретно про этот случай спросил, а не про большую тему.
Интересно, а array overrun — это у вас потоковый анализ ловит или по шаблонам находите? А если потоковый, то как вы доказываете, что состояние
index == size
действительно достижимо, а не эфемерно? В общем случае этого нельзя доказать статически, всегда можно придумать код, на котором будет ложная сработка. Как такие сработки свести к минимуму?Некоторые ошибки из статьи некритичны. Например,
size_t pos = i * 2 + (v1 == 0xff) ? 1 : 2;
ведёт только к неправильном у логированию в случае какой-то другой ошибки. Вообще ветки обработки ошибок как правило самые недотестированные.strictfp на современных процессорах ни на что не влияет. Его даже убрать хотят из джавы вообще.
В статье же всё сказано. Нет, не байткод.
И разница, кстати, большая. Вы огребёте большое количество ложных сработок на котлиновском байткоде, если возьмётесь его анализировать джавовским анализатором байткода. Я пробовал.
Нет, я про другой пример. Нумеруйте их что ли, чтобы ссылаться можно было =)
Ну и вы же сами зачем-то поддерживаете режим «показать только свежие предупреждения». По вашей логике, если эта фича востребована, значит, вашим анализатором тоже невозможно пользоваться ;-)
Это тут ни при чём. Там и реальных проблем полно, десятки тысяч, и можно сделать профиль инспекций, который только реальные проблемы будет показывать. Особенно с nullability много. Это механически не исправишь, там в каждом месте смотреть надо.
Это ни о чём не говорит. Идейка в сорцах Идейки находит двести тысяч предупреждений. В том числе и те, которые в посте есть. Просто не всегда доходят руки их исправить.
У нас в Идейке parse tree с full fidelity, конечно, но это не сильно усложняет потоковый анализ. Конечно, у нас и вычисление типов, и резолв ссылок сделан. В байткоде с этим проще, но и свои минусы есть — erasure. Восстановить generic-сигнатуру бывает очень сложно (эту задачу решают декомпиляторы). С байткодом, кстати, ещё большой минус — привязать предупреждение к конкретному элементу исходника. Там только номера строк есть, если отладочную инфу генерировали. Иногда это сильно усложняет понимание, где же ошибка.
На уровне байткода анализировать джаву — довольно тупиковый путь. Я писал свой анализатор на байткоде. Некоторые проблемы в принципе не увидишь. Надо быть как можно ближе к исходникам.
Я вот даже не уверен, что автоматическое удаление скобок в Spoon — это хорошая идея. Например,
a << 16 + b
похоже на ошибку: приоритет сложения выше, чем сдвига, а выглядит так будто автор забыл про это. С другой стороны,a << (16 + b)
уже выглядит сознательным решением, и тут предупреждать не надо. Если есть дерево без скобок, эту разницу не увидишь. Даже комментарии в коде и отступы очень важны для статического анализа.Ничего себе! У нас только dataflow выдаёт больше 10000 предупреждений, а все включённые инспекции на всём коде Идеи — около 200000. Что с ними делать — абсолютно непонятно :-D