Выберите наугад ваш любимый репозиторий Java, ревизию и файл (или попробуйте этот). Посетите этот файл в Sourcegraph, и через несколько секунд вы сможете перейти к определению (Ctrl / ⌘-щелчок), найти все ссылки (щелкните правой кнопкой мыши), выполнить поиск символов (Ctrl / ⌘-p) и просмотреть примеры использования, взятые из других проекты.

Как работает магия? По большей части это новый открытый стандарт, который называется протокол языкового сервера (LSP). Мы думаем, что LSP принесет пользу почти каждому редактору кода и плагину, и мы хотели бы объяснить, почему, на примерах того, как Sourcegraph использовал его для масштабирования до миллионов репозиториев на многих разных языках.

Код Разведки

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

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

Исходный код разработан, чтобы быть быстрым и простым способом разобраться в коде. Он быстрее, чем OpenGrok, и такой же умный, как и ваша IDE, когда дело доходит до поиска всех ссылок на символ. Под капотом находится сложная система, которая анализирует и анализирует исходный код на лету, чтобы предоставить базовые возможности, которые мы называем Code Intelligence. «Code Intelligence» - это просто сокращение от языковых средств повышения производительности, таких как:

  • Перейти к определению
  • Найти ссылки
  • Поиск символа
  • Подсказки при наведении
  • Автозаполнение

Но такие функции существуют в таких инструментах, как платформа Eclipse, на протяжении десятилетий. Почему сейчас нужен новый открытый стандарт? Причина в сговорчивости.

O (M · N) проблема

IDE, такие как Eclipse IDE, представляют собой сложные системы, которые часто поддерживают Code Intelligence на определенном наборе языков. Sourcegraph направлен на поддержку всех языков. LSP делает оба эти начинания более сговорчивыми.

Исторически сложилось так, что проблема поддержки нескольких языков в нескольких редакторах была O (M · N). У вас есть редакторы M (Eclipse IDE, VS Code, Sublime, Atom, Emacs, Vim и т. Д.) И N языков (Java, JavaScript, Go, TypeScript, Python и т. Д.). Исторически сложилось так, что вам нужен отдельный плагин Code Intelligence для каждой комбинации редактора и языка. Писать такие плагины дорого - вы должны понимать внутреннее устройство компилятора и интегрироваться с различными системами сборки и разбираться в тонкостях пользовательского интерфейса. В результате вы попадаете в мир, в котором гораздо меньше плагинов, чем M · N, - мир, в котором ваш выбор языка сильно ограничивает ваш выбор редактора и наоборот. В идеальном мире вы должны иметь возможность придерживаться выбранного вами редактора независимо от того, на каком языке вы работаете.

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

LSP определяет такой протокол, который находится между плагинами редактора и базовыми библиотеками анализа. Вы создаете один языковой сервер для каждого языка и по одному плагину для каждого редактора. Каждый плагин редактора, говорящий на LSP, теперь будет поддерживать каждый отдельный языковой сервер. Вы свели проблему O (M · N) к проблеме O (M + N).

Теория хорошо претворяется в жизнь. В настоящее время существует реализация LSP почти для каждого основного языка программирования. А это означает, что если ваш плагин редактора говорит на LSP, у вас есть доступ к Code Intelligence на многих языках, и вам не нужно писать ни единой строчки кода синтаксического анализа или проверки типов.

Своевременно и достаточно хорошо

Еще одна ключевая особенность LSP - отсутствие строгой модели структуры кода. Протокол не имеет понятия пространств имен, иерархий классов, определений или ссылок. Как можно представить «переход к определению» без понятия определения? В случае LSP вход - это просто местоположение ссылки (имя файла, номер строки и столбец), а выход - местоположение определения (также имя файла, номер строки и столбец).

LSP вообще не пытается моделировать семантические отношения в коде. Но если мы пытаемся создать Code Intelligence, разве наш протокол не должен знать хотя бы основные семантические отношения в коде? Удивительно, но ответ отрицательный по двум причинам:

  1. Придумать модель данных, не зависящую от языка, сложно. Некоторые языки являются обязательными. Остальные функциональны. Некоторые языки допускают сложные иерархии классов. Другие языки даже не имеют наследования. Очень сложно создать модель данных, которая была бы как достаточно общей, чтобы охватить все языковые особенности, так и достаточно конкретной, чтобы отвечать на запросы пользователей.
  2. Как гласит старая пословица, в компьютерных науках есть только две сложные вещи, и одна из них - это называть вещи. (Другой - аннулирование кеша, это еще одна интересная тема для нас в Sourcegraph, но это уже для другой статьи.) Именование сложно, и именование в коде не исключение. В качестве упражнения попробуйте придумать действительно уникальный универсальный идентификатор символа в коде. «Универсальный» в данном случае означает для всего кода в мире, а не только для вашего локального диска, потому что мы больше не живем в мире, где код на вашем диске является единственным кодом, который имеет значение. LSP решает проблему, полностью обходя ее.

Ничто из этого не препятствует построению семантической модели данных поверх LSP. Фактически, в Sourcegraph мы сделали именно это для более продвинутых функций. Но все это возможно, потому что мы строим поверх слоя, который не делает преждевременных упрощений в коде.

Расширяемость

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

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

Code Intelligence для каждого языка, для каждого редактора и везде, где вы просматриваете код

Мне бы хотелось жить в мире, где использовать Eclipse IDE для написания Python или JavaScript так же просто, как и для Java. Мне также понравился бы мир, в котором изучение кода на любом языке со сверхспособностями, подобными IDE, было таким же простым, как обмен этой гиперссылкой.

Мы думаем, что протокол языкового сервера позволит осуществить обе эти мечты. Code Intelligence - это то, что делает использование вашей IDE волшебным, а LSP делает эту магию гораздо более удобной для реализации. До сих пор мы использовали его с большим успехом в Sourcegraph, и мы настоятельно рекомендуем вам проверить его на наличие плагинов IDE и редактора.

Вопросы, комментарии или отзывы об Sourcegraph или LSP? "Дайте нам знать"!