analysis

package
v0.9.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 14, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package analysis builds a semantic index of a DBML source file suitable for driving LSP requests (hover, completion, definition, references, rename).

All positions are *rune* offsets matching lexer.Token.Start/End. The LSP wire layer is responsible for converting them to UTF-16 line/column.

Index

Constants

This section is empty.

Variables

View Source
var BuiltinTypes = []BuiltinType{
	{"int", "Integer (32-bit in most dialects).", ""},
	{"integer", "Integer (32-bit in most dialects).", ""},
	{"bigint", "64-bit integer.", ""},
	{"smallint", "16-bit integer.", ""},
	{"tinyint", "8-bit integer (MariaDB/MySQL).", ""},
	{"decimal", "Fixed-precision numeric.", "(${1:10},${2:2})"},
	{"numeric", "Fixed-precision numeric (SQL standard alias for decimal).", "(${1:10},${2:2})"},
	{"float", "Single-precision floating point.", ""},
	{"double", "Double-precision floating point.", ""},
	{"real", "Floating point (alias for double in some dialects).", ""},
	{"boolean", "True/false value.", ""},
	{"bool", "True/false value (alias).", ""},
	{"char", "Fixed-length character string.", "(${1:1})"},
	{"varchar", "Variable-length character string.", "(${1:255})"},
	{"text", "Long text.", ""},
	{"mediumtext", "Medium-length text (MariaDB).", ""},
	{"longtext", "Long text (MariaDB).", ""},
	{"binary", "Fixed-length byte string.", "(${1:16})"},
	{"varbinary", "Variable-length byte string.", "(${1:255})"},
	{"blob", "Binary large object.", ""},
	{"bytea", "Byte array (PostgreSQL).", ""},
	{"date", "Calendar date.", ""},
	{"time", "Time of day.", ""},
	{"datetime", "Date + time without timezone.", ""},
	{"timestamp", "Timestamp.", ""},
	{"timestamptz", "Timestamp with timezone (PostgreSQL).", ""},
	{"json", "JSON value.", ""},
	{"jsonb", "Binary JSON (PostgreSQL).", ""},
	{"uuid", "UUID.", ""},
}
View Source
var ColumnAttributes = []ColumnAttribute{
	{"pk", false, "Marks the column as a primary key."},
	{"primary key", false, "Marks the column as a primary key (two-word form)."},
	{"unique", false, "Adds a UNIQUE constraint."},
	{"not null", false, "Disallows NULL values."},
	{"null", false, "Explicitly allows NULL values (the default)."},
	{"increment", false, "Auto-increment / IDENTITY column."},
	{"default", true, "Default value: a literal, identifier (true/false/null), or `expression`."},
	{"note", true, "Inline documentation for this column."},
	{"ref", true, "Inline foreign-key reference: `[ref: > other_table.col]`."},
}
View Source
var Keywords = []Keyword{
	{"Table", "Table declaration — declares a database table with columns and constraints.", "Table ${1:name} {\n\t$0\n}"},
	{"Enum", "Enum declaration — declares an enumerated type with a fixed set of values.", "Enum ${1:name} {\n\t$0\n}"},
	{"Ref", "Ref declaration — declares a foreign-key relationship between two columns.", "Ref: ${1:t1}.${2:c1} > ${3:t2}.${4:c2}"},
	{"Note", "Note declaration — free-form documentation block.", "Note ${1:name} {\n\t'''$0'''\n}"},
	{"Project", "Project declaration — global settings (database_type, name).", "Project ${1:name} {\n\tdatabase_type: '${2|MariaDB,PostgreSQL,SQLite|}'\n}"},
	{"TableGroup", "TableGroup declaration — visual grouping of tables in diagrams.", "TableGroup ${1:name} {\n\t$0\n}"},
	{"TablePartial", "TablePartial declaration — a reusable set of columns/settings mixed into tables with `~name`.", "TablePartial ${1:name} {\n\t$0\n}"},
}
View Source
var ProjectSettings = []ProjectSetting{
	{"database_type", "Target SQL dialect for downstream tools. One of: 'MariaDB', 'PostgreSQL', 'SQLite' (optionally suffixed ' normalized')."},
	{"note", "Free-form description of the project."},
}

Functions

func IsRelationshipOp

func IsRelationshipOp(v string) bool

IsRelationshipOp reports whether v is one of the four DBML relationship operators.

func RelationshipOpDoc

func RelationshipOpDoc(v string) string

RelationshipOpDoc returns a one-line doc for a relationship operator.

Types

type Analysis

type Analysis struct {
	Source   string
	Tokens   []lexer.Token
	Program  *parser.ProgramNode
	Database *interpreter.Database

	Symbols *SymbolIndex
	Refs    []ResolvedRef
	Spans   *SpanIndex

	LineOffsets []int // rune offset of each line start

	LexErrors    []lexer.Error
	ParseErrors  []parser.Error
	InterpErrors []interpreter.Error
}

Analysis is the full semantic snapshot of a source file.

func Analyze

func Analyze(source string) *Analysis

Analyze runs the full lex/parse/interpret pipeline and builds all indices.

func (*Analysis) Completions

func (a *Analysis) Completions(offset int) []Completion

Completions returns the list of completion items at offset. Returns an empty slice when nothing is appropriate.

func (*Analysis) Definition

func (a *Analysis) Definition(offset int) *Range

Definition returns the NameRange of the symbol declared at the use site under offset. If offset is on a declaration, returns that declaration's NameRange. Returns nil for unresolved or non-symbol positions.

func (*Analysis) Hover

func (a *Analysis) Hover(offset int) *HoverResult

Hover returns a HoverResult for the symbol at offset, or nil.

func (*Analysis) OffsetToPosition

func (a *Analysis) OffsetToPosition(offset int) Position

OffsetToPosition converts a rune offset to a 0-based Line/Column.

func (*Analysis) PrepareRename

func (a *Analysis) PrepareRename(offset int) (*PrepareRenameResult, error)

PrepareRename checks whether the symbol at offset is renameable and returns the range to highlight + the suggested placeholder.

func (*Analysis) RefAt

func (a *Analysis) RefAt(offset int) *ResolvedRef

RefAt returns the ResolvedRef whose SiteRange contains offset, if any.

func (*Analysis) ReferencesOf

func (a *Analysis) ReferencesOf(sym *Symbol, includeDecl bool) []Range

ReferencesOf returns the SiteRange of every ResolvedRef whose target is the given symbol. If includeDecl is true, the declaration's own NameRange is included.

For tables, this also returns sites that go through an alias.

func (*Analysis) Rename

func (a *Analysis) Rename(offset int, newName string) ([]TextEdit, error)

Rename returns the edits to rename the symbol at offset to newName.

func (*Analysis) TokenAt

func (a *Analysis) TokenAt(offset int) *lexer.Token

TokenAt returns the significant token whose [Start,End] contains offset.

type BuiltinType

type BuiltinType struct {
	Name string
	Doc  string
	// SnippetArgs, if non-empty, is appended to the bare name on completion.
	SnippetArgs string
}

BuiltinType describes a column type recognised across dialects.

func BuiltinTypeByName

func BuiltinTypeByName(name string) *BuiltinType

type ColumnAttribute

type ColumnAttribute struct {
	Name       string
	TakesValue bool
	Doc        string
}

ColumnAttribute describes a setting allowed inside [ … ] on a column.

func AttributeByName

func AttributeByName(name string) *ColumnAttribute

type Completion

type Completion struct {
	Label        string
	Kind         CompletionKind
	Detail       string
	Doc          string
	InsertText   string // may include $-snippet placeholders; falls back to Label
	ReplaceRange Range
}

Completion is a proposed item with text, kind, doc, and the replacement range.

type CompletionKind

type CompletionKind int

CompletionKind tags completion items so the LSP wire layer can map them to the LSP CompletionItemKind enum.

const (
	CompletionKeyword CompletionKind = iota + 1
	CompletionTable
	CompletionColumn
	CompletionEnum
	CompletionEnumValue
	CompletionTypeName
	CompletionAttribute
	CompletionOperator
	CompletionValue
	CompletionAlias
)

type HoverResult

type HoverResult struct {
	Markdown string
	Range    Range
}

HoverResult is the markdown payload and the range of the hovered token.

type Keyword

type Keyword struct {
	Name   string
	Doc    string
	Insert string // snippet body
}

Keyword is a top-level declaration keyword.

func KeywordByName

func KeywordByName(name string) *Keyword

type Position

type Position struct {
	Line   int
	Column int
}

Position is a 0-based line/column pair derived from a rune offset.

type PrepareRenameResult

type PrepareRenameResult struct {
	Range       Range
	Placeholder string
}

PrepareRenameResult is what `textDocument/prepareRename` returns.

type ProjectSetting

type ProjectSetting struct {
	Name string
	Doc  string
}

ProjectSettings catalogues legal keys inside Project { … }.

type Range

type Range struct {
	Start int
	End   int
}

Range is a half-open rune offset range [Start, End).

func TokenRange

func TokenRange(t lexer.Token) Range

Token-level utility for callers that need a token's range.

type RefSiteKind

type RefSiteKind int
const (
	RefSiteTable RefSiteKind = iota
	RefSiteColumn
	RefSiteEnumType
	RefSiteTableInGroup
)

func (RefSiteKind) String

func (k RefSiteKind) String() string

type ResolvedRef

type ResolvedRef struct {
	Kind       RefSiteKind
	SiteRange  Range   // identifier(s) at the use site (just the name token)
	SourceText string  // verbatim text at the site
	Target     *Symbol // nil if unresolved
	// ParentTableHint is the bare table name from the site context (e.g. "users"
	// in "users.id"); used by completion to know which table's columns to offer.
	ParentTableHint string
}

ResolvedRef is a single use site of a symbol, with its resolution attempt.

func ResolveRefs

func ResolveRefs(prog *parser.ProgramNode, idx *SymbolIndex) []ResolvedRef

ResolveRefs walks all reference sites in the program and resolves them against the symbol index.

type SpanIndex

type SpanIndex struct {
	// contains filtered or unexported fields
}

SpanIndex maps a rune offset to the chain of AST nodes that contain it.

func BuildSpanIndex

func BuildSpanIndex(prog *parser.ProgramNode) *SpanIndex

BuildSpanIndex walks the program and indexes every node by its rune range.

func (*SpanIndex) Innermost

func (s *SpanIndex) Innermost(offset int) []parser.Node

Innermost returns the chain of nodes containing offset, outermost first.

func (*SpanIndex) Leaf

func (s *SpanIndex) Leaf(offset int) parser.Node

Leaf returns the innermost node (last in Innermost). May be nil.

type Symbol

type Symbol struct {
	Kind      SymbolKind
	Name      string  // original casing
	Qualified string  // schema.table or table.column or enum.value
	Parent    *Symbol // column → its table; enum value → its enum
	// DefRange is the full declaration extent (table + body, column + settings, …).
	DefRange Range
	// NameRange is just the identifier token at the declaration site.
	NameRange Range

	// Hover-facing metadata
	TypeName string // for columns
	TypeArgs []string
	PK       bool
	Unique   bool
	NotNull  bool
	Note     string

	// For enums: the value list
	EnumValues []*Symbol
	// For tables: ordered columns
	Columns []*Symbol
}

Symbol describes a single declared entity.

type SymbolIndex

type SymbolIndex struct {
	Tables      map[string]*Symbol            // key: lowercased qualified name
	Columns     map[string]map[string]*Symbol // tableKey → colKey → symbol
	Enums       map[string]*Symbol
	EnumValues  map[string]map[string]*Symbol
	Aliases     map[string]*Symbol // alias key → underlying table symbol
	TableGroups map[string]*Symbol
	RefNames    map[string]*Symbol

	// AllTables / AllEnums preserve declaration order for stable iteration.
	AllTables []*Symbol
	AllEnums  []*Symbol
}

SymbolIndex is the name-keyed dictionary for the whole file.

func BuildSymbolIndex

func BuildSymbolIndex(prog *parser.ProgramNode, db *interpreter.Database) *SymbolIndex

BuildSymbolIndex walks the AST and resolved interpreter output to populate the index.

func (*SymbolIndex) ResolveColumn

func (idx *SymbolIndex) ResolveColumn(table, col string) *Symbol

ResolveColumn looks up a column on a table (resolves aliases first).

func (*SymbolIndex) ResolveTable

func (idx *SymbolIndex) ResolveTable(name string) *Symbol

ResolveTable looks up a table by name or alias.

type SymbolKind

type SymbolKind int
const (
	SymTable SymbolKind = iota
	SymColumn
	SymEnum
	SymEnumValue
	SymTableGroup
	SymAlias
	SymRefName
)

func (SymbolKind) String

func (k SymbolKind) String() string

type TextEdit

type TextEdit struct {
	Range   Range
	NewText string
}

TextEdit is a single text-replacement edit.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL