Gopls: Веб-функции

Запрос LSP window.showDocument позволяет серверу указать клиенту открыть файл в редакторе или веб-страницу в браузере. Это основа для ряда функций gopls, которые отображают информацию о вашей программе через веб-интерфейс.

Мы признаем, что веб-интерфейс не является идеальным для всех: некоторые пользователи предпочитают полноэкранный макет редактора и не любят переключение окон; другие могут работать в текстовом терминале без графической оболочки, возможно, через удалённый ssh или в консоли Linux. К сожалению, LSP не поддерживает несколько естественных видов расширяемости, включая возможность для серверов определять:

  • запросы, которые обобщают запрос References, отображая результаты с использованием аналогичных элементов пользовательского интерфейса;
  • команды, которые выдают поток текста, как типичная командная оболочка или компилятор, который клиент может перенаправить в обычный терминальный элемент пользовательского интерфейса редактора; или
  • операции рефакторинга, которые, как Rename, запрашивают дополнительную информацию у пользователя.

Веб-интерфейс может помочь заполнить эти пробелы до тех пор, пока LSP не предоставит стандартные способы реализации этих функций.

Веб-сервер gopls слушает порт localhost. Из соображений безопасности все его конечные точки включают случайную строку, выступающую в роли токена аутентификации. Клиент, получивший аутентифицированные URL-адреса от сервера, сможет получить доступ к исходному коду, но произвольные процессы, запущенные на вашей машине, — нет. Перезапуск процесса gopls приводит к изменению этого секрета, делая все предыдущие URL-адреса недействительными; существующие страницы будут отображать баннер, указывающий на то, что они были отключены.

TODO: объединить веб-сервер и отладочный сервер; см. https://go.dev/issue/68229.

Gopls поддерживает двустороннюю связь между веб-браузером и клиентским редактором. Все веб-отчёты содержат ссылки на объявления в исходном коде. При клике по одной из таких ссылок gopls отправляет запрос showDocument в ваш редактор, чтобы открыть соответствующий исходный файл на нужной строке. Это работает даже тогда, когда исходный код был изменён, но ещё не сохранён. (VS Code пользователи: пожалуйста, проголосуйте за microsoft/vscode#208093, если вы хотите, чтобы ваш редактор поднимал своё окно при обработке этого события.)

source.doc: Просмотр документации пакета

В любом исходном файле Go запрос действия с кодом возвращает команду «Просмотр документации пакета». Эта команда открывает окно браузера, отображающее документацию для текущего Go пакета, представленную с использованием аналогичного дизайна, как на https://pkg.go.dev.

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

Нажатие на ссылку для символа уровня пакета или метода, который в pkg.go.dev обычно перенаправляет вас в просмотрщик исходного кода, например, на GitHub или Google Code Search, приводит к переходу в редакторе к соответствующему исходному файлу и строке.

Поддержка клиентов:

source.freesymbols: Просмотр свободных символов

При изучении кода, чтобы понять его или оценить другую организацию или факторинг, часто возникает необходимость знать «входные данные» для заданного фрагмента кода, либо потому, что вы рассматриваете возможность выделения его в отдельную функцию и хотите узнать, какие параметры она будет принимать, либо просто чтобы понять, как одна часть длинной функции связана с предыдущими частями.

Если вы выберете фрагмент кода и вызовете действие с кодом «Browse free symbols» (code action), ваш редактор откроет браузер с отчётом о свободных символах в выбранном фрагменте. Символ считается «свободным», если он ссылается внутри выбранного фрагмента, но определён вне его. По сути, это входные данные для выбранного фрагмента.

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

TODO: объяснить точечные пути.

Поддержка клиентов:

source.assembly: Просмотр ассемблерного кода

При оптимизации производительности кода или анализе неожиданного сбоя может быть полезно изучить ассемблерный код, сгенерированный компилятором для заданной функции Go.

Если вы размещаете курсор или выделение внутри функции f, gopls предлагает действие с кодом «Browse assembly for f» (Просмотр ассемблера для f). Оно открывает веб-список ассемблерного кода для функции и любых вложенных в неё функций.

Каждый раз при редактировании исходного кода и перезагрузке страницы текущий пакет перекомпилируется, и список обновляется. Нет необходимости сохранять изменённые файлы.

Архитектура цели компилятора совпадает с архитектурой, используемой gopls при анализе файла: обычно это архитектура вашей машины (GOARCH), но при просмотре файла с тегом сборки, например, с именем foo_amd64.go или содержащего комментарий //go:build amd64, архитектура определяется тегами.

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

Приведённый выше пример показывает ассемблерный список для time.NewTimer в архитектуре arm64. Обратите внимание, что указанная инструкция ссылается на местоположение в другую функцию, syncTimer, поскольку компилятор встроил вызов из NewTimer в syncTimer.

Просмотр ассемблерного кода пока не поддерживается для дженерик-функций, инициализаторов пакетов (func init) или функций в тестовых пакетах. (Вклад приветствуется!)

Поддержка клиентов:

source.splitPackage: Разделение пакета на компоненты

Веб-инструмент «Разделение пакета» может помочь разделить сложный пакет на две или более компонентов, гарантируя, что зависимости между этими компонентами будут ацикличными.

Следуйте инструкциям на странице, чтобы выбрать набор именованных компонентов, назначить каждое объявление наиболее подходящему компоненту, а затем визуализировать зависимости между этими компонентами, созданные ссылками от одного символа к другому.

На рисунке ниже показано, как работает инструмент на пакете fmt, который (в принципе) можно разделить на три подпакета: один для форматирования (Printf и аналогичные), один для сканирования (Scanf), и один для их общих зависимостей.

(Попробуйте поработать с инструментом на этом пакете: это полезное упражнение. На рисунке ниже показано решение.)

Инструмент в настоящее время не выполняет преобразование кода (перемещение объявлений в новые пакеты, переименование символов для их экспорта по мере необходимости), но мы надеемся добавить эту функциональность в будущем выпуске.

Поддержка клиентов:


Исходные файлы этой документации можно найти в golang.org/x/tools/gopls/doc.

GoRu.dev Golang на русском

На сайте представлена адаптированная под русский язык документация языка программирования Golang