Статический анализатор кода для встроенного языка 1С

Инструмент статического анализа модулей встроенного языка 1С

Назначение инструмента

Программа предназначена для статического анализа модулей встроенного языка 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’. Возможно это ошибка кодирования.

62 Comments

  1. ardn

    Возможна ли пакетная работа?

    Reply
  2. Evil Beaver

    А без окошка, в командной строке работает?

    Reply
  3. artbear

    Правильно я понимаю, что пока исследуется только независимый/отдельный модуль, без связей с соседними модулями, например, общие модули ?

    Reply
  4. Evil Beaver

    (3) artbear, судя по диагностике «переменная дублирует глобальную переменную» — нет. Или под глобальной имеется в виду переменная уровня модуля?

    Reply
  5. nixel

    Некорректно обрабатывает комментарии внутри многострочной строки вида:

    «Многострочная

    |строка

    // коммент +

    |с добавленным текстом, окруженным тегами

    // коммент —

    |завершение строки»;

    Ну и конечно же интересует запуск из командной строки. Плюс интересно взглянуть на исходники (желательно открытые) 🙂

    Спасибо за инструмент!

    Reply
  6. so-quest

    winxp — не запустилось.

    С чем связан выбор qt?

    Reply
  7. so-quest

    разбор по грамматике или руками? Поддержка препроцессора есть или планируется? Разделение по областям видимости — если сделана — то как? Обработка правил — как реализована (кодом или есть язык преобразований)? Сырцы — принципиально не открываешь или можно ожидать?

    Reply
  8. honomer

    (1) ardn, Возможна. Посмотрить окно «О программе», там написано, как это сделать.

    Reply
  9. honomer

    (2) Evil Beaver, Работает. Можно увидеть синтаксис командной строки вызвав программу с параметром /?

    Reply
  10. honomer

    (3) artbear, Да, правильно. Пока только один модуль без связи с соседними. И это существенно сказывается на выводе типов.

    Reply
  11. honomer

    (5) nixel, разбор многострочной строки на выходных попробую исправить.

    Reply
  12. honomer

    (6) so-quest, на QT потому, что не охота было сильно заморачиваться с интерфейсом. А что пишет в WinXP — ошибка какая-то есть или совсем не запускается?

    Reply
  13. honomer

    (7) so-quest, Препроцессор поддерживается. Про области видимости — не понял о чём речь.

    Разбор пока руками, может когда ANTLR v4 поддержит С++ перейдём на него.

    Исходники вам в данный момент зачем?

    Reply
  14. Evil Beaver

    (13) нам в данный момент они (исходники) не зачем, но в перспективе мы хотим использовать открытый инструмент (если он будет открытым). Религия у нас такая тут… ))

    Кроме того, в открытый инструмент мы запросто сможем вложиться кодом, делая мир лучше.

    Reply
  15. honomer

    (14) Evil Beaver, простите, я религии стараюсь обходить стороной. Пока открывать не готов, потом — подумаем.

    Reply
  16. Evil Beaver

    (15) думайте, конечно. Просто когда надоест пилить в одиночку, вспомните мои слова )))

    Reply
  17. honomer

    (16) Evil Beaver, под oneScript eго проще заново написать, чем этот переделывать.

    Reply
  18. so-quest

    Да не в коде дело, а в правилах и модели на которой эти правила будете анализировать.

    (17) как совет — пока не поздно — уходи с С++ на языки с более простым циклом разработки

    Reply
  19. Evil Beaver

    (17) я вовсе не в привязке к oscript спрашиваю)))

    Reply
  20. honomer

    (19) Evil Beaver, да я, если честно, ни в чём плохом вас и не подозревал. Извините, действительно со стороны некрасиво получилось.

    Reply
  21. honomer

    (18) so-quest, более простой цикл разработки — это какой-же? 🙂 Шарп, ява? Фреймворки у них мощные, а цикл разработки такой же — кодишь, дебажишь, тестишь.

    Reply
  22. so-quest

    (21) лисп/кложура/схема : тест -> репл -> код и функции не будут такие большие

    Reply
  23. artbear

    (21)

    цикл разработки такой же — кодишь, дебажишь, тестишь.

    ОФФ/2 А если юзать ТДД, то скорость будет выше 🙂

    Reply
  24. lustin

    (22) so-quest, GoLang забыл

    Reply
  25. Evil Beaver

    (24) lustin, кстати, да. Golang разработан, как конкурент C/C++, в нем авторы серьезно подумали над устранением атавизмов C++ и заявляют практически о будущем мировом господстве.

    Reply
  26. premierex

    На Инфостарте уже был опубликован проект тестирования конфигураций. Реализован на wsh скриптах (vbs, js). Исходные коды открыты. Тесты легко подключаются буквально на лету, каждый тест снабжен документацией, в проекте принимало участие несколько разработчиков. Кому интересно, можно посмотреть по ссылке.

    Reply
  27. honomer

    (26) premier,

    Больше инструментов, хороших и разных.

    Сайт программы недоступен.

    Reply
  28. brr

    (26) premier, это разные вещи

    Reply
  29. pro1c@inbox.ru

    Без раскраски кода не годится!

    Для такого инструмента, как статический анализатор кода, она обязательна должна быть!

    Reply
  30. so-quest

    (29) — а подробнее? чем эта раскраска поможет?

    Reply
  31. honomer

    (29) pro1c@inbox.ru, вот тоже хотелось бы узнать — чем поможет раскраска, если основной режим работы для не встроенного в Конфигуратор инструмента, вообще говоря, из командной строки.

    Reply
  32. pro1c@inbox.ru

    (30) so-quest,

    Если я делаю, статический анализ кода, мне мало сообщений о потенциальных или существующих ошибках, а хотелось бы без труда охватить взглядом код!

    Ведь где то я могу согласится с анализатором, а где то нет, раскраска просто помогает мне визуально пробегать по коду взглядом, без лишнего труда выделять ключевые слова и т.д.

    Плюс, я могу просто начать писать какую-нибудь процедуру для своих тестов на анализ сразу в окне, хотелось бы иметь удобный редактор!

    Reply
  33. so-quest

    (32) Подобные инструменты просто делают вывод (файл или консоль) а уж раскраской занимаются совсем другие программы. Основная задача анализатора — сообщить о проблеме (сообщение может быть и ложным, но если анализатор его нашел, значит текст попадает под правило анализа) Что делать с этой информаций дальше — анализатору пофиг. ведь вывод прогаммы можно и в dev/null отправить

    Reply
  34. premierex

    (27) Сайт программы действительно недоступен, т.к. автор этот проект забросил, но я принимал активное участие в этом проекте (писал часть движка и некоторые тесты) и, думаю, смог бы убедить автора проекта «подарить» его сообществу. К тому же большинство исходных кодов сохранились, их можно на этом сайте скачать или у меня попросить (не уверен, правда, что самой последней версии) .

    (28) Уважаемый, Вы ошибаетесь. Эти проекты из одной и той же области — а именно: тестирование кода модулей на соответствие некоторым стандартам (кто уж какой придумает). Отличие от предлагаемого ПО в данной публикации (+ кстати забыл поставить, исправлюсь) — это открытость кодов и масштабируемость, т.е. возможность написать тест под какие-то свои стандарты оформления кода. Ну и возможность работы над проектом в команде.

    Reply
  35. premierex

    Вот архив, который у меня сохранился, посмотрите, протестируйте…

    Reply
  36. so-quest

    Как минимум неплохо бы документацию.

    Как максимум — подробную документацию.

    Reply
  37. honomer

    (36) so-quest, как-то пока руки не дошли

    Reply
  38. premierex

    (0) Автор, утверждение Конструкция ЕСЛИ (%1) ТОГДА … ИНАЧЕ ЕСЛИ (%1) … похожа на ошибку кодирования, так как оно никогда не будет выполнено. не совсем верно, так как ЕСЛИ (%1) = Истина то код, следующий за оператором ТОГДА будет выполняться всегда, а вот код, следующий за конструкцией ИНАЧЕ ЕСЛИ (%1) ТОГДА действительно никогда выполняться не будет.

    Reply
  39. honomer

    (38) premier, спасибо. Переформулирую в следующей версии

    Reply
  40. honomer

    Коллеги, вопрос: кроме понятного желания «больше правил» и хотелки «подкрашивающий редактор» есть ещё какие-то пожелания по функционалу, которые вы считаете важными, но они отсутствуют? Настройка списка правил для проверки и т.д.?

    Reply
  41. so-quest

    1. Отдельно правила для лексера, парсера, преобразователя.

    2. Свое описание правил и соответственно интерпретатор этих правил.

    3. Возможность выключать проверку правила в коде

    4. Связь метаданных и кода

    5. Расчет метрик для кода

    Reply
  42. so-quest

    6. Вывод лексем и ast в отдельный файл (даст возможность самому писать правила)

    Reply
  43. so-quest

    7. Документировать все это

    Reply
  44. so-quest

    8. Уйти от ручного разбора на генератор парсеров

    Reply
  45. Zlohobbit

    Отличная доработка! Если возможно добавьте в следующих версиях поиск по анализируемому тексту! Нужно для анализа таких ошибок например как:»..похожа на ошибку кодирования, так как условие уже проверено выше.». И конечно же мечта это анализ cf -ников или для начала *.epf и *.erf))).

    А так суперская Приблуда! Спасибо!

    Reply
  46. honomer

    (45) Zlohobbit, я подумывал сделать сортировку списка ошибок и его фильтрацию по типам и процедурам. Поиск, по-моему, тут не очень пригодится.

    Для анализа cf, epf, erf — их нужно распаковывать, а это уже другой компот: уже существуют такие инструменты, зачем писать ещё один.

    Reply
  47. honomer

    (44) so-quest, про разбор я уже писал — antlr4 пока не поддерживает С++

    Писать самостоятельно пользовательские правила и их интерпретацию — я пока не вижу перспективы и ресурсов для этого, что самое главное. так же как и вывод дерева в файл, Это-то вообще зачем? Чтобы использовать в сторонних инструментах? И в каком формате?

    Пока хочется документировать нормально, сделать настройку списка проверяемых правил, исправить ошибки, внести новые 🙂 правила.

    Можно и расчет метрик кода.

    Остальное, как мне кажется, сейчас не так важно.

    Reply
  48. so-quest

    (47) Я бы тебе рекомендовал определиться — ты будешь за деньги это продавать или бесплатно раздавать. Если за деньги — тогда твои аргументы понятны и смысла что либо дальше говорить — мало. Если же оплата не планируется — тогда я не понимаю в чем проблема вывести дерево в файл (формат — любой какой нравится — от xml до чистого текста, главное его хоть как-то описать)

    Про генератор — кроме антлр есть море генераторов. Выгода от них — в более быстрой разработке — не надо думать про состояния и переходы. За тебя все сделают. Да и когда захочешь с С++ уйти — не придется много переписывать.

    Про правила — ты уверен что будешь успевать реагировать на все просьбы — добавь то или это? проще дать язык описания правил и на нем уже пусть пишут все что хотят. Внутри все равно примитивная перезапись термов и паттернматчинг .

    Reply
  49. honomer

    (48) so-quest, Сделать вывод дерева — проблем нет. Как я уже выше спросил — какой в этом смысл? Кому это нужно и для чего? От этого зависит что и как выводить.

    Нужно ли, в конце концов, вообще тратить на это время?

    Про генераторы я в курсе. Flex, bison, flex++, bison++, spirit… и иже с ними. А так же про проблемы левой рекурсии и адские сообщения компилятора у некоторых.

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

    Можете привести пример хотя бы одного анализатора, который использует такой подход? Я поглядел в википедии, но что-то ничего там такого не нашёл, хотя, нужно признаться, искал тоже не очень сильно.

    Reply
  50. so-quest

    > Сделать вывод дерева — проблем нет. Как я уже выше спросил — какой в этом смысл? Кому это нужно и для чего?

    Сделай. Мне нужен этот вывод. Для собственных правил. Это же очевидно.

    > А так же про проблемы левой рекурсии …

    Ты грамматику С/С++ разбираешь? Это примитивный 1С. Тупо бейсик, без всяких извращений. Тебе грамматика наоборот поможет и спасет от проблем связанных с неоднозначностью разбора выражений

    > Что же про разработку основанную на правилах — считаю, что это ни разу не тривиальная задача

    Кто сказал что будет просто? Хотя там сложного ничего и нет . Вот пример простого правила для подобной твоей системы-

    (defrule :where ‘lexer
    :name ‘check-id-length
    :token ‘:identifier
    :description «Длинна переменной меньше 2 символов»
    :check #'(lambda (text type start end file index data)
    (> 2 (length text ))))
    

    Где сложность в реализации? Аналогично и для обхода AST строиться набор правил.

    Про построение статанализаторов кода — https://lvee.org/en/reports/LVEE_2012_01 и дальше по ссылкам.

    И просьба — сделай что бы под WinXP работала твоя разработка.

    Reply
  51. eugeniezheludkov

    Начинал как то делать что-то подобное на регулярках в шарпе, просто была идея немного упростить труд КодРевьюверов ) и заодно «прошерстить» код от франчайзи. никакого статанализа не делал, только регулярка )

    https://github.com/znsoft/1SCodeAnalyze

    за код стыдно если честно. Последняя версия в ветви VS08.

    работает так: распаковываете все модули конфигурации в каталог,

    и в этом каталоге запускаете прогу .. а она в консоль выдает все найденные ошибки (имя объекта.имя модуля. имя метода. номер строки. кусок кода)

    Reply
  52. honomer

    (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.

    про построение анализаторов — интересно, но примеров анализатора, основанного на правилах (о чём я собственно и задавал вопрос), которые мог бы задавать непосредственно пользователь я там что-то не обнаружил. Плохо искал?

    Reply
  53. so-quest

    -> про вывод дерева понял. запишу себе в план.

    Ну хоть что-то 🙂 Когда ждать? Где будут обновления?

    -> сложность хотя бы в том, что в С++ нет возможности взять лямбду в виде куска кода из файлы и выполнить.

    <

    Reply
  54. honomer

    (45) Zlohobbit, при клике на сообщении курсор переходит на строку, где диагностировали ошибку. Этого не достаточно?

    Reply
  55. honomer

    (53) so-quest, ecl — это Embedable Common Lisp? Если да, ну и зачем оно мне — в QT уже есть встроенная поддержка QtScript.

    Reply
  56. honomer

    (55) naf2000, Если вы серьёзно не понимаете зачем это, то дискуссия видится бессмысленной.

    Reply
  57. so-quest

    (55) Тролишь? Или можешь привести доказательство того что 1С недоязык?

    (56) тогда непонятно что вsзвало проблему — » С++ нет возможности взять лямбду в виде куска кода из файлы и выполнить. Т.е. Нужно будет написать ещё один интерпретатор. или встроить какой-то, типа lua. » — если есть qtscript.

    Reply
  58. honomer

    (58) so-quest, правила в приведённом виде — это не язык. и нужно будет делать их анализ и интерпретацию.

    В общем, я запишу и подумаю.

    Reply
  59. 987ww765

    (59) Забросил проект?

    Reply
  60. artbear

    Посмотрите наш проект https://silverbulleters.org/sonarqube/

    Тот самый крутой статический анализатор на базе AST-деревьев, кеша метаданных и т.п.

    Можно свои правила добавлять.

    Уже в куче разных компаний юзается, есть и облачные решения для клиентов

    По ссылке намного подробнее написано

    Reply
  61. guy_septimiy

    Годная штука. Находит досадные недочеты

    Reply
  62. gubanoff

    (0) (61) да, лучший вариант эти правила добавить в сонар. Можно в свободный плагин, который развивает сообщество https://github.com/1c-syntax/bsl-language-server

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *