Назначение инструмента
Программа предназначена для статического анализа модулей встроенного языка 1С (файлов *.bsl).
Зачем это нужно? Применение статического анализа при разработке позволяет сократить количество ошибок, выявляемых на этапе работы и сократить время, затрачиваемое на отладку за счёт выявления этих ошибок на этапе разработки.
В ходе работы проверяется в первую очередь корректность программы на встроенном языке (несколько строже, чем сам 1С), а так же ищутся ошибки в конструкциях программы, которые являются синтаксически правильными, но при этом содержат смысловые ошибки (см. список проверяемых ошибок ниже).
Возможности
Позволяет выполнить проверку файлов на наличие ошибок в интерактивном или пакетном режиме работы.
В интерактивном режиме предоставляется возможности:
- загрузки и проверки файла на наличие ошибок с учётом задаваемых констант компиляции
- отображения списка ошибок и переход из него к месту ошибки в редактируемом файле
- загрузки файла для редактирования
- сохранения файла
- при запуске программы открывается последний редактируемый файл
В пакетном режиме предоставляется возможность проверки одного или нескольких файлов с учётом определённых констант препроцессора и вывод сообщений об ошибках в файл протокола
Запуск в пакетном режиме
bslsa.exe pathToLogFile [ —define=DEFINE […]] pathToFileToCheck1 [… pathToFileToCheckN]
где:
pathToLogFile — путь к файлу протокола
—define=DEFINE — определение требуемого символа препроцессора, например Клиент или Сервер
pathToFileToCheck1 — путь к файлу или файлам, которые требуется проверить
Пример строки запуска в пакетном режиме
bslsa.exe c:check.log —define=Клиент —define=Сервер d:cfgunload*.bsl
Планы по развитию
В перспективе планируется:
- реализовать возможность проверять файлы не как отдельные единицы, но как часть конфигурации
- реализовать выбор набора правил для анализа
- расширить набор правил анализа
- улучшить работу с протоколом ошибок (сортировка, отбор и т.д.)
- улучшить редактор (раскраска текста и поиск по файлу)
Ошибки и предложения
https://trello.com/b/mwACzUl2/estatico-analisis
Распознаваемые ошибки
- Две последовательные переменные присваиваются через одно и то же выражение, что может являться логической ошибкой или неоптимизированным кодом.
- Не все ветви выполнения в функции %1 возвращают какое-либо значение, что похоже на ошибку.
- В функции ИМЯ отсутствует завершающий оператор ВОЗВРАТ (или ВЫЗВАТЬИСКЛЮЧЕНИЕ) что похоже на ошибку.
- Результат вызова функции ‘%1’ не используется, что может являться ошибкой.
- Функция ИМЯ возвращает одно и тоже значение ЗНАЧЕНИЕ во всех точках возврата, что похоже на ошибку.
- Операторы функции ИМЯ1 полностью совпадают с операторами функции ИМЯ2.
- Возможно конструкция A[B ОПЕРАТОР C] ошибочна и нужна была A[B] ОПЕРАТОР C.
- Функция СтрДлина вызывается в цикле для константного выражения, что может сказываться на производительности.
- В выражении используется неинициализированная локальная переменная %1, что похоже на ошибку.
- Создаваемая переменная ИМЯ имеет тоже имя что и процедура, что может привести к ошибкам.
- Переменная ИМЯ присваивается дважды подряд без её использования между присваиваниями, что похоже на ошибку.
- Переменной ИМЯ присвоено значение, но оно нигде не используется, что похоже на ошибку.
- Переменная ИМЯ имеет имя одинаковое с глобальной переменной, что может привести к ошибкам.
- Переменная %1 переопределяет одноимённый параметр.
- Инструкция ПРОДОЛЖИТЬ является последней в цикле. Она либо является лишней, либо это похоже на ошибку кодирования.
- Отсутствуют какие-либо операторы внутри блока (ЦИКЛ|ЕСЛИ). Возможно это ошибка кодирования.
- Переменная ИМЯ используется для счётчика цикла и в этом и внешнем цикле, что похоже на ошибку кодирования.
- Этот и внешний циклы ДЛЯ КАЖДОГО реализуют обход по одной и той же коллекции %1, что может быть ошибкой.
- Начальное и конечное значение цикла совпадают, что похоже на ошибку кодирования.
- Безусловная операция ВОЗВРАТ внутри цикла. Это может указывать на логическую ошибку.
- Недостижимый код.
- Оператор ? вне зависимости от условия возвращает одинаковые значения.
- Присвоение переменной ИМЯ самой себе похоже на ошибку кодирования.
- Рекурсивная проверка ЕСЛИ (%1) ТОГДА ЕСЛИ (%1) … похожа на ошибку кодирования, так как условие уже проверено выше.
- Обнаружены два взаимоисключающих условия (%1) и (%2). Второе условие всегда будет ложным.
- Последний оператор ВОЗВРАТ в ветке ТОГДА|ИНАЧЕТОГДА|ИНАЧЕ идентичен оператору ВОЗВРАТ следующему после оператора ЕСЛИ. Похоже, что он не нужен или присутствует ошибка.
- В первом из двух последовательных операторов ЕСЛИ с одинаковыми условиями содержится безусловный оператор ВОЗВРАТ. Второй оператор ЕСЛИ либо не нужен, либо его условие записано с ошибкой.
- Конструкция ЕСЛИ (%1) ТОГДА … ИНАЧЕ ЕСЛИ (%1) … похожа на ошибку кодирования, так как оно никогда не будет выполнено.
- Операторы в блоке ТОГДА полностью эквивалентны операторам в блоке ИНАЧЕ.
- Выражение (%1) окружено бесполезными скобками. Может быть они не нужны или присутствует ошибка
- Одинаковые выражения ‘%2’ слева и справа от оператора ‘%1’. Возможно это ошибка кодирования.
Возможна ли пакетная работа?
А без окошка, в командной строке работает?
Правильно я понимаю, что пока исследуется только независимый/отдельный модуль, без связей с соседними модулями, например, общие модули ?
(3) artbear, судя по диагностике «переменная дублирует глобальную переменную» — нет. Или под глобальной имеется в виду переменная уровня модуля?
Некорректно обрабатывает комментарии внутри многострочной строки вида:
«Многострочная
|строка
// коммент +
|с добавленным текстом, окруженным тегами
// коммент —
|завершение строки»;
Ну и конечно же интересует запуск из командной строки. Плюс интересно взглянуть на исходники (желательно открытые) 🙂
Спасибо за инструмент!
winxp — не запустилось.
С чем связан выбор qt?
разбор по грамматике или руками? Поддержка препроцессора есть или планируется? Разделение по областям видимости — если сделана — то как? Обработка правил — как реализована (кодом или есть язык преобразований)? Сырцы — принципиально не открываешь или можно ожидать?
(1) ardn, Возможна. Посмотрить окно «О программе», там написано, как это сделать.
(2) Evil Beaver, Работает. Можно увидеть синтаксис командной строки вызвав программу с параметром /?
(3) artbear, Да, правильно. Пока только один модуль без связи с соседними. И это существенно сказывается на выводе типов.
(5) nixel, разбор многострочной строки на выходных попробую исправить.
(6) so-quest, на QT потому, что не охота было сильно заморачиваться с интерфейсом. А что пишет в WinXP — ошибка какая-то есть или совсем не запускается?
(7) so-quest, Препроцессор поддерживается. Про области видимости — не понял о чём речь.
Разбор пока руками, может когда ANTLR v4 поддержит С++ перейдём на него.
Исходники вам в данный момент зачем?
(13) нам в данный момент они (исходники) не зачем, но в перспективе мы хотим использовать открытый инструмент (если он будет открытым). Религия у нас такая тут… ))
Кроме того, в открытый инструмент мы запросто сможем вложиться кодом, делая мир лучше.
(14) Evil Beaver, простите, я религии стараюсь обходить стороной. Пока открывать не готов, потом — подумаем.
(15) думайте, конечно. Просто когда надоест пилить в одиночку, вспомните мои слова )))
(16) Evil Beaver, под oneScript eго проще заново написать, чем этот переделывать.
Да не в коде дело, а в правилах и модели на которой эти правила будете анализировать.
(17) как совет — пока не поздно — уходи с С++ на языки с более простым циклом разработки
(17) я вовсе не в привязке к oscript спрашиваю)))
(19) Evil Beaver, да я, если честно, ни в чём плохом вас и не подозревал. Извините, действительно со стороны некрасиво получилось.
(18) so-quest, более простой цикл разработки — это какой-же? 🙂 Шарп, ява? Фреймворки у них мощные, а цикл разработки такой же — кодишь, дебажишь, тестишь.
(21) лисп/кложура/схема : тест -> репл -> код и функции не будут такие большие
(21)
ОФФ/2 А если юзать ТДД, то скорость будет выше 🙂
(22) so-quest, GoLang забыл
(24) lustin, кстати, да. Golang разработан, как конкурент C/C++, в нем авторы серьезно подумали над устранением атавизмов C++ и заявляют практически о будущем мировом господстве.
На Инфостарте уже был опубликован проект тестирования конфигураций. Реализован на wsh скриптах (vbs, js). Исходные коды открыты. Тесты легко подключаются буквально на лету, каждый тест снабжен документацией, в проекте принимало участие несколько разработчиков. Кому интересно, можно посмотреть поссылке .
(26) premier,
Больше инструментов, хороших и разных.
Сайт программы недоступен.
(26) premier, это разные вещи
Без раскраски кода не годится!
Для такого инструмента, как статический анализатор кода, она обязательна должна быть!
(29) — а подробнее? чем эта раскраска поможет?
(29) pro1c@inbox.ru, вот тоже хотелось бы узнать — чем поможет раскраска, если основной режим работы для не встроенного в Конфигуратор инструмента, вообще говоря, из командной строки.
(30) so-quest,
Если я делаю, статический анализ кода, мне мало сообщений о потенциальных или существующих ошибках, а хотелось бы без труда охватить взглядом код!
Ведь где то я могу согласится с анализатором, а где то нет, раскраска просто помогает мне визуально пробегать по коду взглядом, без лишнего труда выделять ключевые слова и т.д.
Плюс, я могу просто начать писать какую-нибудь процедуру для своих тестов на анализ сразу в окне, хотелось бы иметь удобный редактор!
(32) Подобные инструменты просто делают вывод (файл или консоль) а уж раскраской занимаются совсем другие программы. Основная задача анализатора — сообщить о проблеме (сообщение может быть и ложным, но если анализатор его нашел, значит текст попадает под правило анализа) Что делать с этой информаций дальше — анализатору пофиг. ведь вывод прогаммы можно и в dev/null отправить
(27) Сайт программы действительно недоступен, т.к. автор этот проект забросил, но я принимал активное участие в этом проекте (писал часть движка и некоторые тесты) и, думаю, смог бы убедить автора проекта «подарить» его сообществу. К тому же большинство исходных кодов сохранились, их можно на этом сайте скачать или у меня попросить (не уверен, правда, что самой последней версии) .
(28) Уважаемый, Вы ошибаетесь. Эти проекты из одной и той же области — а именно: тестирование кода модулей на соответствие некоторым стандартам (кто уж какой придумает). Отличие от предлагаемого ПО в данной публикации (+ кстати забыл поставить, исправлюсь) — это открытость кодов и масштабируемость, т.е. возможность написать тест под какие-то свои стандарты оформления кода. Ну и возможность работы над проектом в команде.
Вот архив, который у меня сохранился, посмотрите, протестируйте…
Как минимум неплохо бы документацию.
Как максимум — подробную документацию.
(36) so-quest, как-то пока руки не дошли
(0) Автор, утверждение Конструкция ЕСЛИ (%1) ТОГДА … ИНАЧЕ ЕСЛИ (%1) … похожа на ошибку кодирования, так как оно никогда не будет выполнено. не совсем верно, так как ЕСЛИ (%1) = Истина то код, следующий за оператором ТОГДА будет выполняться всегда, а вот код, следующий за конструкцией ИНАЧЕ ЕСЛИ (%1) ТОГДА действительно никогда выполняться не будет.
(38) premier, спасибо. Переформулирую в следующей версии
Коллеги, вопрос: кроме понятного желания «больше правил» и хотелки «подкрашивающий редактор» есть ещё какие-то пожелания по функционалу, которые вы считаете важными, но они отсутствуют? Настройка списка правил для проверки и т.д.?
1. Отдельно правила для лексера, парсера, преобразователя.
2. Свое описание правил и соответственно интерпретатор этих правил.
3. Возможность выключать проверку правила в коде
4. Связь метаданных и кода
5. Расчет метрик для кода
6. Вывод лексем и ast в отдельный файл (даст возможность самому писать правила)
7. Документировать все это
8. Уйти от ручного разбора на генератор парсеров
Отличная доработка! Если возможно добавьте в следующих версиях поиск по анализируемому тексту! Нужно для анализа таких ошибок например как:»..похожа на ошибку кодирования, так как условие уже проверено выше.». И конечно же мечта это анализ cf -ников или для начала *.epf и *.erf))).
А так суперская Приблуда! Спасибо!
(45) Zlohobbit, я подумывал сделать сортировку списка ошибок и его фильтрацию по типам и процедурам. Поиск, по-моему, тут не очень пригодится.
Для анализа cf, epf, erf — их нужно распаковывать, а это уже другой компот: уже существуют такие инструменты, зачем писать ещё один.
(44) so-quest, про разбор я уже писал — antlr4 пока не поддерживает С++
Писать самостоятельно пользовательские правила и их интерпретацию — я пока не вижу перспективы и ресурсов для этого, что самое главное. так же как и вывод дерева в файл, Это-то вообще зачем? Чтобы использовать в сторонних инструментах? И в каком формате?
Пока хочется документировать нормально, сделать настройку списка проверяемых правил, исправить ошибки, внести новые 🙂 правила.
Можно и расчет метрик кода.
Остальное, как мне кажется, сейчас не так важно.
(47) Я бы тебе рекомендовал определиться — ты будешь за деньги это продавать или бесплатно раздавать. Если за деньги — тогда твои аргументы понятны и смысла что либо дальше говорить — мало. Если же оплата не планируется — тогда я не понимаю в чем проблема вывести дерево в файл (формат — любой какой нравится — от xml до чистого текста, главное его хоть как-то описать)
Про генератор — кроме антлр есть море генераторов. Выгода от них — в более быстрой разработке — не надо думать про состояния и переходы. За тебя все сделают. Да и когда захочешь с С++ уйти — не придется много переписывать.
Про правила — ты уверен что будешь успевать реагировать на все просьбы — добавь то или это? проще дать язык описания правил и на нем уже пусть пишут все что хотят. Внутри все равно примитивная перезапись термов и паттернматчинг .
(48) so-quest, Сделать вывод дерева — проблем нет. Как я уже выше спросил — какой в этом смысл? Кому это нужно и для чего? От этого зависит что и как выводить.
Нужно ли, в конце концов, вообще тратить на это время?
Про генераторы я в курсе. Flex, bison, flex++, bison++, spirit… и иже с ними. А так же про проблемы левой рекурсии и адские сообщения компилятора у некоторых.
Что же про разработку основанную на правилах — считаю, что это ни разу не тривиальная задача по масштабам сравнивая и даже наверное больше с самим анализатором. Время затраченное на её разработку можно потратить довольно много и без особого успеха. Ведь это по сути — интерпретатор ещё одного языка, который будет описывать эти правила.
Можете привести пример хотя бы одного анализатора, который использует такой подход? Я поглядел в википедии, но что-то ничего там такого не нашёл, хотя, нужно признаться, искал тоже не очень сильно.
> Сделать вывод дерева — проблем нет. Как я уже выше спросил — какой в этом смысл? Кому это нужно и для чего?
Сделай. Мне нужен этот вывод. Для собственных правил. Это же очевидно.
> А так же про проблемы левой рекурсии …
Ты грамматику С/С++ разбираешь? Это примитивный 1С. Тупо бейсик, без всяких извращений. Тебе грамматика наоборот поможет и спасет от проблем связанных с неоднозначностью разбора выражений
> Что же про разработку основанную на правилах — считаю, что это ни разу не тривиальная задача
Кто сказал что будет просто? Хотя там сложного ничего и нет . Вот пример простого правила для подобной твоей системы-
Где сложность в реализации? Аналогично и для обхода AST строиться набор правил.
Про построение статанализаторов кода —https://lvee.org/en/reports/LVEE_2012_01 и дальше по ссылкам.
И просьба — сделай что бы под WinXP работала твоя разработка.
Начинал как то делать что-то подобное на регулярках в шарпе, просто была идея немного упростить труд КодРевьюверов ) и заодно «прошерстить» код от франчайзи. никакого статанализа не делал, только регулярка )
за код стыдно если честно. Последняя версия в ветви VS08.
работает так: распаковываете все модули конфигурации в каталог,
и в этом каталоге запускаете прогу .. а она в консоль выдает все найденные ошибки (имя объекта.имя модуля. имя метода. номер строки. кусок кода)
(50) so-quest,
про вывод дерева понял. запишу себе в план.
про то, где сложность реализации. Вот есть правило:
(defrule :where ‘lexer
:name ‘check-id-length
:token ‘:identifier
:description «Длинна переменной меньше 2 символов»
:check #'(lambda (text type start end file index data)
(> 2 (length text ))))
сложность хотя бы в том, что в С++ нет возможности взять лямбду в виде куска кода из файлы и выполнить. Т.е. Нужно будет написать ещё один интерпретатор. или встроить какой-то, типа lua.
про построение анализаторов — интересно, но примеров анализатора, основанного на правилах (о чём я собственно и задавал вопрос), которые мог бы задавать непосредственно пользователь я там что-то не обнаружил. Плохо искал?
-> про вывод дерева понял. запишу себе в план.
Ну хоть что-то 🙂 Когда ждать? Где будут обновления?
-> сложность хотя бы в том, что в С++ нет возможности взять лямбду в виде куска кода из файлы и выполнить.
<
(45) Zlohobbit, при клике на сообщении курсор переходит на строку, где диагностировали ошибку. Этого не достаточно?
(53) so-quest, ecl — это Embedable Common Lisp? Если да, ну и зачем оно мне — в QT уже есть встроенная поддержка QtScript.
(55) naf2000, Если вы серьёзно не понимаете зачем это, то дискуссия видится бессмысленной.
(55) Тролишь? Или можешь привести доказательство того что 1С недоязык?
(56) тогда непонятно что вsзвало проблему — » С++ нет возможности взять лямбду в виде куска кода из файлы и выполнить. Т.е. Нужно будет написать ещё один интерпретатор. или встроить какой-то, типа lua. » — если есть qtscript.
(58) so-quest, правила в приведённом виде — это не язык. и нужно будет делать их анализ и интерпретацию.
В общем, я запишу и подумаю.
(59) Забросил проект?
Посмотрите наш проектhttps://silverbulleters.org/sonarqube/
Тот самый крутой статический анализатор на базе AST-деревьев, кеша метаданных и т.п.
Можно свои правила добавлять.
Уже в куче разных компаний юзается, есть и облачные решения для клиентов
По ссылке намного подробнее написано
Годная штука. Находит досадные недочеты
(0) (61) да, лучший вариант эти правила добавить в сонар. Можно в свободный плагин, который развивает сообществоhttps://github.com/1c-syntax/bsl-language-server