All streams
Search
Write a publication
Pull to refresh
633
0
Тагир Валеев @tagir_valeev

Программист

Send message
но тратить время на изучение совершенно не нужного мне недоязыка смысла не вижу.

Иногда полезно выходить из зоны комфорта.


А вообще всё в ваших руках. Изучите тюториалы на питоне, а потом переделайте их на джаву. Сами лучше разберётесь, и другие вам будут благодарны. А если книгу выпустить, на этом ещё и заработать можно.

Так это проблема системы code-review, требуйте фича-реквест! Хорошая система могла бы резолвить вызов конструктора и оставлять подсказки.
Как раз для HashMap (если религия не позволяет Java 9 или Guava) совершенно несложно написать в своём проекте свой нормальный билдер и использовать его.

Например, чтобы хранить объекты в списках и искать/удалять там? Иногда линейный поиск вполне достаточен. Ну и в целом, чтобы иметь возможность сравнивать объекты. Иногда это нужно без хэш-таблиц. Если объект при этом ещё IComparable, его можно хранить в упорядоченных множествах без хэшкода.

Ну и варнинги про нереализованный хэшкод люди не сильно любят. По хорошему стоит выдавать его только если где-то в проекте этот объект действительно используется как ключ для хэша. А если нет, зачем парить мозги разработчикам, отвлекая от реальных проблем?

State19 — очевидно автогенерённый код лексера по грамматике, это мусорный варнинг. Автогенерённый код надо исключать из анализа.

> Я не согласен, что первый шаг – это статический анализ, а только второй компиляция. Я считаю, что проверка компиляции в среднем быстрее и логичнее, чем сразу гонять «более тяжелый» статический анализ.

В моей практике эти два шага идут одновременно и неразрывно с редактированием кода. После каждой правки кода автоматически в фоне IDE находит и ошибки компиляции (не компилируя на самом деле, но это и не важно) и предупреждения статического анализа. Там есть расстановка приоритетов, хайлайтинг ошибок обычно вперёд успевает завершиться, поэтому формально «сперва компиляция». Но обычно разница во времени меньше секунды, для человека это непринципиально.
С чеккастами дофига проблем из-за этого, кстати. В данном случае он больше враг, чем друг. Инспекции вида «cast may fail» практически всегда получаются очень мусорными на байткоде, репортя места, где каста не было вообще в сорцах.
Как насчёт чтобы в условном build.gradle версия была указана конкретная, но при появлении новой версии робот на CI сам обновляет этот файл и коммитит обновлённый build-скрипт, возможно, разрешая на следующей сборке храповику прокрутиться назад? Тогда будет и обновление, и воспроизводимость.

Ваши примеры по большей части неактуальны. Джава-компилятор довольно глупенький и не делает таких умностей при компиляции в байткод, оставляя это джиту. Но как человек, посвятивший немало времени и сил анализу именно байткода, могу подтвердить, что идея от konsoletyper не пролезет. Даже для чистой джавы часть информации никаким образом оттуда не вытащишь, а часть наоборот добавляется зазря. С другими языками вроде Котлина всё ещё хуже. Компилятор может спокойно добавлять заведомо недостижимые ветки, которых в исходном коде не было и я могу это выяснить статически. В результате выдаётся предупреждение о проблеме, которой нет в исходниках. Вдобавок усложняется репортинг ошибок: у меня из отладочной информации есть только номер строки. А если строка длинная, и в ней три ошибки, попробуй-ка спозиционируйся.


Реальные примеры проблем такие. Ошибки с возможной инверсией приоритетов операций дают ложные сработки, если в исходнике были явные скобки, которые говорили "да, я хочу именно этого". Безусловный выход из цикла не поймаешь, потому что в байткоде такой цикл не отличишь от if. Саппрессить варнинги очень сложно. Стандартная аннотация @SuppressWarnings не попадает в байткод вообще. Дженерик-параметры локальных переменных исчезают напрочь, их приходится восстанавливать эвристически. В исходниках могло быть написано что-то другое, и это иногда влияет на предупреждения. Про типы-пересечения вообще молчу. JVM про них ничего не знает.


Кроме того, трудно найти вменяемый движок для работы с байт-кодом на достаточно высоком уровне, который бы поддерживался актуальным. Самому писать ещё труднее. Знаете, сколько всего надо поменять в движке вроде Spoon, чтобы поддержать конкатенацию строк из Java9+? Ничего не надо менять, в исходниках она не изменилась. А в байткоде там ад и погибель. Тот же дешугаринг лямбд наверняка ещё будет меняться. И при обсуждении реализации новых фич в джаве постоянно ребята из Оракла говорят "давайте через indy зафигачим". Если каждый инди-бутстрэп не распознавать, ваш байткод-анализатор будет очень уныло работать. А indy-бутстрэпы языко-специфичны. Наверняка если вы напишете анализатор байткода, тестируя его только на джава-коде, а потом возьмётесь за условный JRuby, вы поймёте, что ваш анализатор бесполезен. Там будет куча маленьких синтетических методов и через слово indy. Наконец, такой анализатор тупо надо тестировать на всех языках. Вам может казаться, что вы всё хорошо поддержали, но по факту вы поддержали только байткод, который генерирует javac. Встретите байткод от scalac, а там последовательность инструкций, которая сносит крышу движку — и всё пошло-поехало.

Ну а чего вы хотели? На то он и статический анализ. Было бы "всегда", я бы легко заставил Идейку решить проблему останова или доказать какую-нибудь недоказанную гипотезу теории чисел через такой варнинг :-)

Всё правильно, но к нашей ситуации не относится. Ещё раз: asm0dey оспорил не предупреждение анализатора, а ухудшение производительности. Предупреждение анализатора он не оспаривал, поэтому утверждать, что анализатор внимательнее человека, в данном случае неверно. Я ровно это хотел сказать.
Справедливости ради замечу, что анализатор не сказал «код работает чуть медленнее, чем мог бы», это уже человек, анализируя сообщение, пришёл к такому выводу. И asm0dey оспорил вывод человека, а не программы.

В целом лишнюю проверку вида condition is always true компилятор нередко удалит так же легко, как анализатор заметит, поэтому не всегда имеется ухудшение производительности. В данном случае это, конечно, вряд ли сработает, но классифицировать такие случаи на вредные или нейтральные для производительности ваш анализатор вроде бы пока не научился :-)

Бывает до смешного доходит. Пользователь присылает отчёт об ошибке, что в Идейке произошёл NullPointerException, мы смотрим стектрейс, а в этом месте сама Идейка подсвечивает код, что NullPointerException здесь возможен. Мол, «я же вас предупреждала, а вы!»


Зато недавно мы сделали другую инспекцию, которая здесь срабатывает

Перепутал ссылку на тикет, вот правильная.

А-а-а! Некрофилы в комментариях!

Слушайте, ну если вы ожидаете от другого человека помощи, почему бы не сделать максимум работы самому? Если вы репортили баг, дайте хотя бы ссылку на него. У нас десятки тысяч открытых багов, мне сейчас идти и искать по вашему расплывчатому описанию?


Кстати, если уж хочется привлечь внимание к тикету, есть способы лучше, чем писать разработчику совсем другой подсистемы. Например, твиттер. Особо хитрые жалуются на реддит. Ещё можно подговорить всех коллег проголосовать за баг. Только не сразу, а где-нибудь раз в неделю. Или можно время от времени писать дополнительные комментарии типа "проблема всё ещё актуальна в свежей версии, пожалуйста почините". Бывает, что работает. Только я вам этого не говорил :-)

В коммюнити-проекте есть. Но ориентироваться на него неправильно. Во-первых, что-то в этом профиле может быть по историческим причинам. Или каких-то предупреждений слишком много на нашей кодовой базе, и они шумят, но если делаешь проект с нуля, они полезны. Поэтому у нас выключены, а по умолчанию включены.

Ай-яй-яй, прям по больному месту прошёлся! Ту ошибку мы уже тоже находим :-)

Позвольте! Идеевский анализатор вполне себе вдумчивый!

Information

Rating
Does not participate
Location
Новосибирск, Новосибирская обл., Россия
Registered
Activity