Реализация протокола Language Server Protocol (LSP) на основе CPG, обеспечивающая интеллектуальный анализ кода в реальном времени из базы данных Code Property Graph CodeGraph.
Содержание¶
- Обзор
- Установка
- Быстрый старт
- Диагностика
- Наведение
- CodeLens
- Автоисправление (CodeAction)
- Подключение OpenCode
- Пул подключений
- Конфигурация
- Устранение неполадок
Обзор¶
LSP-сервер CodeGraph соединяет любой LSP-совместимый редактор с CPG (Code Property Graph), которым во время выполнения владеет GoCPG. Сам LSP-сервер работает как gRPC-клиент: он не открывает DuckDB напрямую и создаёт только read-only нагрузку через GoCPG. Сервер предоставляет:
- Диагностика безопасности – результаты 190+ правил шаблонов (привязка к CWE)
- Обнаружение мёртвого кода – методы без вызывающих (fan_in=0)
- Предупреждения о сложности – цикломатическая сложность выше настраиваемого порогового значения
- Нарушения шаблонов – структурные проблемы качества кода
- Метрики метода при наведении – сложность, fan-in/fan-out, вызывающие, результаты безопасности
- Индикаторы CodeLens – количество вызывающих/вызываемых методов и информация о потоках данных (taint) над каждым методом
- Автоисправления – быстрые исправления для 22 правил (SQL-инъекции, переполнение буфера, инъекция команд оболочки)
Поддерживает 11 языков: C, C++, C#, Go, Java, JavaScript, Kotlin, PHP, Python, Ruby, TypeScript.
Установка¶
LSP-сервер входит в пакет CodeGraph:
pip install -e .
Команда регистрирует точку входа CLI codegraph-lsp. Также можно запустить напрямую:
python -m codegraph_lsp --db <path-to-duckdb>
--db задаёт идентификатор целевой CPG-базы, которой владеет GoCPG. Сам процесс LSP не владеет файлом DuckDB и не открывает его напрямую.
Зависимости¶
pygls>=2.0.0– фреймворк Python LSPlsprotocol– определения типов LSP- Запущенный GoCPG gRPC server с доступом к целевой CPG-базе
Быстрый старт¶
- Соберите CPG для вашего проекта (если ещё не собран):
gocpg parse --input=. --output=project.duckdb --lang=python
- Запустите GoCPG, чтобы CPG была доступна по gRPC:
gocpg serve --data-dir .
- Запустите LSP-сервер:
python -m codegraph_lsp --db project.duckdb
- Настройте редактор для работы с сервером (см. разделы для конкретных редакторов ниже).
Диагностика¶
Сервер публикует диагностику при открытии и сохранении файла.
Результаты безопасности (severity: Error)¶
Результаты из cpg_pattern_results с category = 'security'. Каждая диагностика включает:
- Идентификатор правила, привязанный к CWE, в качестве кода диагностики
- Точную строку и столбец из анализа CPG
- Описание уязвимости
Пример в редакторе:
Error [CWE-89]: SQL injection — user input concatenated into query (line 42)
Мёртвые методы (severity: Hint, tag: Unnecessary)¶
Методы, где fan_in = 0 AND is_entry_point = false AND is_external = false AND is_test = false. Отображаются с зачёркиванием в редакторах, поддерживающих тег Unnecessary.
Пример:
Hint [dead-method]: Dead method: 'unused_helper' has no callers (fan_in=0) (line 25)
Предупреждения о сложности¶
Методы, у которых cyclomatic_complexity превышает настроенное пороговое значение:
| Сложность | Уровень серьёзности |
|---|---|
| пороговое значение–19 | Information |
| 20–49 | Warning |
| ≥50 | Error |
Пример:
Warning [high-complexity]: Cyclomatic complexity of 'process_data' is 25 (threshold: 10) (line 100)
Нарушения шаблонов¶
Результаты из cpg_pattern_results, не относящиеся к безопасности. Уровень серьёзности определяется полем severity правила шаблона.
Наведение¶
При наведении на метод отображается таблица в формате Markdown:
| Метрика | Описание |
|---|---|
| Cyclomatic complexity | Оценка сложности метода |
| Fan-in (callers) | Количество уникальных вызывающих методов |
| Fan-out (callees) | Количество уникальных вызываемых методов |
| Callers | Вызывающие из edges_call |
| LOC | Количество строк кода |
| Parameters | Количество параметров |
| Security findings | Количество результатов безопасности в файле |
| Flags | точка входа, внешний, тест, мёртвый код |
CodeLens¶
Каждый метод получает индикатор CodeLens:
3 callers | 5 callees | taint: read_input→execute_query
- Вызывающие/вызываемые из
fan_in/fan_outвnodes_method - Поток данных (taint) отображается, когда метод участвует в пути потока данных (через
edges_reaching_def)
Автоисправление (CodeAction)¶
Для нарушений шаблонов с доступными правилами автоисправления сервер предоставляет действия Quick Fix. 22 правила автоисправления включают:
| Правило | Язык | Описание |
|---|---|---|
autofix-py-format-sql |
Python | Замена %-форматирования SQL на параметризованный запрос |
autofix-py-concat-sql |
Python | Замена конкатенации строк SQL на параметризованный запрос |
autofix-py-fstring-sql |
Python | Замена f-строки SQL на параметризованный запрос |
autofix-py-ctypes-string-at |
Python | Замена ctypes.string_at на безопасную альтернативу |
autofix-py-subprocess-shell |
Python | Замена shell=True на прямую команду |
autofix-go-concat-sql |
Go | Замена конкатенации строк SQL на параметризованный запрос |
autofix-go-sprintf-sql |
Go | Замена fmt.Sprintf SQL на параметризованный запрос |
autofix-go-exec-shell |
Go | Замена выполнения через оболочку на прямую команду |
autofix-go-cgo-strcpy |
Go | Замена CGO strcpy на безопасное копирование буфера |
autofix-c-strcpy-to-strncpy |
C | Замена strcpy на strncpy |
autofix-c-sprintf-to-snprintf |
C | Замена sprintf на snprintf |
autofix-c-null-assert |
C | Добавление проверки NULL после вызова функции |
| … | … | Плюс правила для захардкоженных строк для 10 языков |
Автоисправление применяется, когда match_data в cpg_pattern_results содержит поле fix с кодом замены.
Подключение OpenCode¶
Добавьте LSP-сервер в opencode.json (пример конфигурации):
{
"lsp": {
"codegraph": {
"command": ["python", "-m", "codegraph_lsp", "--db", "project.duckdb"],
"languages": ["python", "go", "javascript", "typescript", "java", "c", "cpp"]
}
}
}
OpenCode автоматически:
- Запускает LSP-сервер при открытии файлов на поддерживаемых языках
- Показывает диагностику в строке и на панели проблем
- Включает диагностику в контекст LLM через experimental.chat.system.transform
- Предлагает быстрые исправления для шаблонов с поддержкой автоисправления
Пул подключений¶
LSP-сервер использует read-only пул запросов поверх GoCPG:
- Максимум логических подключений: 3 (настраиваемо)
- Только gRPC: процесс LSP не открывает DuckDB напрямую
- Только чтение: diagnostics, hover, CodeLens и code actions идут через query RPC GoCPG
- Потокобезопасность: используется
threading.Lock - Отслеживание смены снимка: пул проверяет время модификации файла базы (
mtime) и переподключает простаивающие соединения после обновления снимка CPG
Владение DuckDB остаётся внутри GoCPG. Когда GoCPG обновляет или пересоздаёт CPG, LSP-клиент получает новый снимок на следующих RPC-запросах.
Конфигурация¶
Параметры CLI¶
| Параметр | По умолчанию | Описание |
|---|---|---|
--db |
(обязательный) | Путь к целевой CPG-базе, используемый GoCPG |
--complexity-threshold |
10 | Пороговое значение предупреждения о цикломатической сложности |
--transport |
stdio | Транспорт: stdio или tcp |
--host |
127.0.0.1 | TCP-хост (только для --transport tcp) |
--port |
2087 | TCP-порт (только для --transport tcp) |
--log-level |
info | Уровень логирования: debug, info, warning, error |
Режимы транспорта¶
stdio (по умолчанию): редактор запускает сервер как подпроцесс и обменивается данными через stdin/stdout. Оптимально для локального использования.
python -m codegraph_lsp --db project.duckdb
tcp: сервер слушает TCP-порт. Подходит для удалённых LSP-подключений или общих экземпляров.
python -m codegraph_lsp --db project.duckdb --transport tcp --port 2087
Устранение неполадок¶
Диагностика не отображается¶
- Убедитесь, что GoCPG gRPC доступен и обслуживает нужную базу.
- Убедитесь, что целевой DuckDB-файл существует и содержит CPG-данные, например через GoCPG lifecycle/query endpoints или
gocpg stats --db project.duckdb. - Убедитесь, что пути к файлам в базе данных совпадают с путями в рабочем пространстве (прямые слэши, относительные пути).
Ошибка «Connection Pool Exhausted»¶
Означает, что активны 3 одновременных read-запроса. Это может произойти, если: - GoCPG выполняет медленные запросы к очень большой CPG - Одновременно были открыты несколько файлов
Решение: закройте часть файлов или увеличьте размер пула (требует изменения кода).
Устаревшая диагностика после обновления CPG¶
Если диагностика кажется устаревшей:
- Закройте и откройте файл заново
- Убедитесь, что GoCPG завершил update/reparse и сообщает read_available=true
- Перепроверьте lifecycle status через CodeGraph /status или dogfood status
Сервер не запускается¶
- Убедитесь, что pygls установлен:
python -c "import pygls; print(pygls.__version__)" - Убедитесь, что GoCPG gRPC server запущен и доступен для процесса LSP
- Проверьте сообщения об ошибках в stderr
Проблемы с путями в Windows¶
Сервер нормализует пути из URI файлов (file:///C:/... → C:/...) и использует прямые слэши внутри. Если в базе данных CPG пути содержат обратные слэши, диагностика может не совпадать. Пересоберите CPG для обеспечения единообразия путей.