Немного истории

Когда я присоединился к проекту Eclipse CDT еще в 2002 году (да, это было давно), я работал над инструментами моделирования для реального времени или, точнее, встроенными реактивными системами. Связь с конечными автоматами. Я написал генераторы кода, которые генерировали C и C ++ из ROOM-моделей, а затем, в конечном итоге, UML-RT. ROOM, кстати, был намного лучше, и его было легче создать, потому что он был более семантически полным и хорошо определенным. Эта цель является ключевой позже в этой истории.

У нас было видение более тесной интеграции наших инструментов моделирования с интегрированными средами разработки. Мы начали смотреть на Visual Studio, но Eclipse был молодым человеком. Это и IBM купила нас, Rational к тому моменту, и уже купила OTI, которая построила Eclipse, так что это было естественное совпадение. И все мы были в Оттаве. И случайно компания QNX из Оттавы уже написала IDE C / C ++ на основе Eclipse и открыла исходный код для нее, и она также идеально подходила для наших клиентов. Удивительно, как все это произошло и привело к моей жизни как CDT Doug.

Нашим первым делом было помочь CDT стать IDE промышленного класса C / C ++ и стать основой для интеграции наших инструментов моделирования. Поскольку мы хотели иметь возможность генерировать элементы модели из кода, нам потребовались точные синтаксические анализаторы и индексаторы C и C ++. Никто не предполагал, что мы сможем это сделать, но мы смогли собрать довольно приличную систему, написанную на Java, в подключаемом модуле org.eclipse.cdt.core.

Масштабирование сложно

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

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

Было сложно убедить мою команду в IBM Rational пойти по этому пути. Точность была королем наших инструментов для моделирования. Но когда я перешел в QNX, я решил отказаться от этого требования и попробовать эту стратегию «быстрого индексирования». И остальное уже история. Выполнение крупных проектов было на порядок быстрее. Инкрементное индексирование файлов по мере их сохранения даже не заметно. Это был огромный успех, и я горжусь своим вкладом в CDT. И мне было даже лучше, когда другие члены сообщества передали нам свой опыт, чтобы сделать точность все лучше и лучше, так что вы этого вообще почти не замечаете.

C ++ восстает из мертвых

Десять лет спустя переместите часы, и мы столкнулись с проблемой. Сообщество стандартов C ++ обрело новую жизнь и каждые три года добавляет массу новых функций. Сообщество CDT давно потеряло большинство экспертов, которые строили оригинальные парсеры. К счастью для нас, появилось новое поколение участников, которые работают как герои, чтобы не отставать. Но становится все труднее и труднее. Одна вещь, от которой мы выигрываем, - это то, насколько медленно разработчики встраиваемых систем, большинство пользователей CDT, принимают новые стандарты. Это дает нам время, но не навсегда. Нам нужно найти лучший способ.

Затем появился протокол языкового сервера и небольшая горстка языковых серверов, работающих на C / C ++. Я исследовал четыре из них. Три из них основаны на llvm и clang. Один из них находится в дереве с llvm и clang в clang-tools-extra, то есть clangd. Два других - это проекты, которые используют libclang с частями дерева, то есть cquery и ccls. Эти два проекта я называю «проектами одного человека», и, по крайней мере, с помощью cquery, этот человек нашел, чем заняться в ноябре прошлого года. Остерегайтесь проекта одного человека.

лязг

Я провел много времени с clangd, экспериментируя с Visual Studio Code. Clangd очень точен и быстр. Он использует файлы compile_commands.json, чтобы узнать, какие исходные файлы созданы и какие компиляторы и командные строки они используют. Мне пришлось разветвлять дерево, чтобы добавить поддержку обнаружения компиляторов, о которых он не знает, но это было довольно легко собрать. Он обеспечивает отличную поддержку контента, а при вводе вы получаете преимущества потрясающей диагностики ошибок компиляции clang. Это многообещающе.

Однако в clangd долгое время отсутствовал индексатор. Когда вы ищете ссылки, она находит их только в файлах, которые вы открывали ранее. Мысль, насколько я понимаю, заключается в том, что вы используете другой процесс для построения индекса, и это обычно делается во время сборки. Однако не у всех пользователей настроена такая среда, поэтому наличие индекса, созданного IDE, является обязательной функцией. Итак, clangd в конечном итоге получил индексатор, но он делает то же, что и старый индексатор CDT, и полностью анализирует исходный три. Как и следовало ожидать, в больших проектах на это уходит вечность, и я не думаю, что у пользователей есть желание сделать огромный шаг назад в таком виде.

IntelliSense

В ожидании подходящего решения для clangd я подумал, что могу попробовать инструменты Microsoft C / C ++ для VS Code. Мой первоначальный опыт был довольно неожиданным. Он действительно хорошо работал с проектом кросс-компилятора инструментов GNU, который я использовал для тестирования. Вы должны научить его, как анализировать ваш код, используя волшебный файл JSON, который идеально сочетается с остальной частью VS Code. Он может выбрать путь включения по умолчанию, когда вы укажете его на свой компилятор. У него есть поддержка MI для отладки, хотя нет встроенной поддержки удаленной отладки, но ее можно было взломать. Это казалось разумной альтернативой, по крайней мере, для VS Code.

Однако, когда я попробовал это с одним из наших производственных проектов, он быстро развалился. Он отлично справляется с попыткой вычислить пути включения, аналогично эвристике, которую мы используем в CDT. Это включает в себя такие вещи, как обработка всех папок в вашей рабочей области как потенциальной записи пути включения. Но он имел тенденцию ошибаться. Он даже поддерживает файлы compile_commands.json, поэтому я могу указать ему используемые командные строки. Он работал лучше, но все же пытался сделать слишком много и давал неверные результаты.

И у него еще нет индекса. Один из них скоро появится, но если он не сможет понять, как правильно анализировать мои файлы, это будет не лучший опыт. Там еще много работы.

Куда мы отправимся отсюда?

На сегодняшний день, по крайней мере, с точки зрения CDT, на самом деле не существует решения языкового сервера, которое приближалось бы к тому, что есть у нас в CDT. Да, кое-что лучше. Оба этих языковых сервера используют настоящие парсеры для анализа кода. (или, по крайней мере, clangd. Microsoft, конечно, имеет закрытый исходный код, так что я могу только предполагать). Они предоставляют действительно хорошую помощь по содержанию, диагностику ошибок и работу с открытым объявлением. Но без удобного индексатора вы не получите точных ссылок на символы. И я даже не упомянул рефакторинг, который есть в CDT и который даже не предлагается в протоколе языкового сервера.

Так что, если все, что вы делаете, это набираете код, новые языковые серверы великолепны. Но если вам нужно провести анализ кода, чтобы понять код, прежде чем изменять его, вам не повезло. Хорошая новость заключается в том, что мы продолжаем видеть инвестиции в них, так что кто знает. Но тогда, возможно, синтаксические анализаторы CDT догонят языковые стандарты до того, как на этих других языковых серверах появятся отличные индексаторы, что сделает все это спорным. Я бы не стал ставить против этого прямо сейчас.