feat: gasm-devkit 0.1.0 — GAsm lexer, parser, linter, formatter, LSP and amd64 assembler
Assisted-by: Qwen 3.8 Max Preview
This commit is contained in:
+255
@@ -0,0 +1,255 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package lsp implements a Language Server Protocol server for GAsm. It
|
||||
// speaks JSON-RPC 2.0 over any io.Reader/io.Writer pair (normally standard
|
||||
// input/output) and provides completion, hover documentation, document
|
||||
// symbols, diagnostics and semantic-token highlighting — all backed by the
|
||||
// pure-Go lexer, parser, arch and lint packages. It is the vendor-neutral
|
||||
// integration point: any LSP-capable editor can use it with no editor-specific
|
||||
// plugin code.
|
||||
package lsp
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// --- JSON-RPC 2.0 -----------------------------------------------------------
|
||||
|
||||
// rpcMessage is the common envelope for every JSON-RPC message.
|
||||
type rpcMessage struct {
|
||||
JSONRPC string `json:"jsonrpc"`
|
||||
ID *json.RawMessage `json:"id,omitempty"`
|
||||
Method string `json:"method,omitempty"`
|
||||
Params json.RawMessage `json:"params,omitempty"`
|
||||
Result any `json:"result,omitempty"`
|
||||
Error *rpcError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
type rpcError struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// JSON-RPC error codes used by LSP.
|
||||
const (
|
||||
errParse = -32700
|
||||
errInvalidRequest = -32600
|
||||
errMethodNotFound = -32601
|
||||
errInvalidParams = -32602
|
||||
errInternal = -32603
|
||||
)
|
||||
|
||||
// --- LSP positions and ranges ----------------------------------------------
|
||||
|
||||
// Position is a zero-based line/character position, as LSP requires.
|
||||
type Position struct {
|
||||
Line int `json:"line"`
|
||||
Character int `json:"character"`
|
||||
}
|
||||
|
||||
// Range is a pair of positions.
|
||||
type Range struct {
|
||||
Start Position `json:"start"`
|
||||
End Position `json:"end"`
|
||||
}
|
||||
|
||||
// Location is a range within a document URI.
|
||||
type Location struct {
|
||||
URI string `json:"uri"`
|
||||
Range Range `json:"range"`
|
||||
}
|
||||
|
||||
// --- diagnostics ------------------------------------------------------------
|
||||
|
||||
// Diagnostic severities (LSP ordering: 1 = error).
|
||||
const (
|
||||
sevError = 1
|
||||
sevWarning = 2
|
||||
sevInformation = 3
|
||||
sevHint = 4
|
||||
)
|
||||
|
||||
// Diagnostic is one published finding.
|
||||
type Diagnostic struct {
|
||||
Range Range `json:"range"`
|
||||
Severity int `json:"severity"`
|
||||
Code string `json:"code,omitempty"`
|
||||
Source string `json:"source,omitempty"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type publishDiagnosticsParams struct {
|
||||
URI string `json:"uri"`
|
||||
Diagnostics []Diagnostic `json:"diagnostics"`
|
||||
}
|
||||
|
||||
// --- text document synchronisation -----------------------------------------
|
||||
|
||||
type textDocumentItem struct {
|
||||
URI string `json:"uri"`
|
||||
LanguageID string `json:"languageId"`
|
||||
Version int `json:"version"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type didOpenParams struct {
|
||||
TextDocument textDocumentItem `json:"textDocument"`
|
||||
}
|
||||
|
||||
type versionedTextDocumentIdentifier struct {
|
||||
URI string `json:"uri"`
|
||||
Version int `json:"version"`
|
||||
}
|
||||
|
||||
type textDocumentIdentifier struct {
|
||||
URI string `json:"uri"`
|
||||
}
|
||||
|
||||
type contentChangeEvent struct {
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type didChangeParams struct {
|
||||
TextDocument versionedTextDocumentIdentifier `json:"textDocument"`
|
||||
ContentChanges []contentChangeEvent `json:"contentChanges"`
|
||||
}
|
||||
|
||||
type didCloseParams struct {
|
||||
TextDocument textDocumentIdentifier `json:"textDocument"`
|
||||
}
|
||||
|
||||
// --- completion -------------------------------------------------------------
|
||||
|
||||
// Completion item kinds (a useful subset).
|
||||
const (
|
||||
ciFunction = 3
|
||||
ciField = 5
|
||||
ciVariable = 6
|
||||
ciClass = 7
|
||||
ciModule = 9
|
||||
ciKeyword = 14
|
||||
ciConstant = 21
|
||||
ciStruct = 22
|
||||
)
|
||||
|
||||
// CompletionItem is one completion suggestion.
|
||||
type CompletionItem struct {
|
||||
Label string `json:"label"`
|
||||
Kind int `json:"kind,omitempty"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
Documentation string `json:"documentation,omitempty"`
|
||||
InsertText string `json:"insertText,omitempty"`
|
||||
}
|
||||
|
||||
type completionParams struct {
|
||||
TextDocument textDocumentIdentifier `json:"textDocument"`
|
||||
Position Position `json:"position"`
|
||||
}
|
||||
|
||||
// --- hover ------------------------------------------------------------------
|
||||
|
||||
type hoverParams struct {
|
||||
TextDocument textDocumentIdentifier `json:"textDocument"`
|
||||
Position Position `json:"position"`
|
||||
}
|
||||
|
||||
// Hover is the hover response.
|
||||
type Hover struct {
|
||||
Contents markupContent `json:"contents"`
|
||||
Range Range `json:"range,omitempty"`
|
||||
}
|
||||
|
||||
type markupContent struct {
|
||||
Kind string `json:"kind"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// --- document symbols -------------------------------------------------------
|
||||
|
||||
// Symbol kinds (a useful subset).
|
||||
const (
|
||||
symFunction = 12
|
||||
symConstant = 14
|
||||
symVariable = 13
|
||||
)
|
||||
|
||||
// DocumentSymbol is a hierarchical symbol.
|
||||
type DocumentSymbol struct {
|
||||
Name string `json:"name"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
Kind int `json:"kind"`
|
||||
Range Range `json:"range"`
|
||||
SelectionRange Range `json:"selectionRange"`
|
||||
Children []DocumentSymbol `json:"children,omitempty"`
|
||||
}
|
||||
|
||||
type documentSymbolParams struct {
|
||||
TextDocument textDocumentIdentifier `json:"textDocument"`
|
||||
}
|
||||
|
||||
// --- semantic tokens --------------------------------------------------------
|
||||
|
||||
// semanticTokenTypes is the legend of token type names, in index order. The
|
||||
// indices are referenced by the encoder below.
|
||||
var semanticTokenTypes = []string{
|
||||
"comment", // 0
|
||||
"keyword", // 1
|
||||
"function", // 2
|
||||
"variable", // 3
|
||||
"type", // 4
|
||||
"number", // 5
|
||||
"string", // 6
|
||||
"operator", // 7
|
||||
"property", // 8
|
||||
"namespace", // 9
|
||||
"macro", // 10
|
||||
}
|
||||
|
||||
const (
|
||||
stComment = 0
|
||||
stKeyword = 1
|
||||
stFunction = 2
|
||||
stVariable = 3
|
||||
stType = 4
|
||||
stNumber = 5
|
||||
stString = 6
|
||||
stOperator = 7
|
||||
stProperty = 8
|
||||
stNamespace = 9
|
||||
stMacro = 10
|
||||
)
|
||||
|
||||
// SemanticTokensLegend advertises the token classification.
|
||||
type SemanticTokensLegend struct {
|
||||
TokenTypes []string `json:"tokenTypes"`
|
||||
TokenModifiers []string `json:"tokenModifiers"`
|
||||
}
|
||||
|
||||
// SemanticTokens is the encoded token payload.
|
||||
type SemanticTokens struct {
|
||||
Data []int `json:"data"`
|
||||
}
|
||||
|
||||
type semanticTokensParams struct {
|
||||
TextDocument textDocumentIdentifier `json:"textDocument"`
|
||||
}
|
||||
|
||||
// --- initialize -------------------------------------------------------------
|
||||
|
||||
type initializeParams struct {
|
||||
RootURI string `json:"rootUri"`
|
||||
}
|
||||
|
||||
// ServerCapabilities advertises what this server provides.
|
||||
type ServerCapabilities struct {
|
||||
TextDocumentSync int `json:"textDocumentSync"`
|
||||
CompletionProvider map[string]any `json:"completionProvider,omitempty"`
|
||||
HoverProvider bool `json:"hoverProvider,omitempty"`
|
||||
DocumentSymbolProvider bool `json:"documentSymbolProvider,omitempty"`
|
||||
SemanticTokensProvider map[string]any `json:"semanticTokensProvider,omitempty"`
|
||||
DiagnosticProvider map[string]any `json:"diagnosticProvider,omitempty"`
|
||||
}
|
||||
|
||||
type initializeResult struct {
|
||||
Capabilities ServerCapabilities `json:"capabilities"`
|
||||
ServerInfo map[string]string `json:"serverInfo,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user