linter

package
v0.1.0 Latest Latest
Warning

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

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

Documentation

Overview

Package linter provides static analysis rules for COB/BOS scripts.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatDiagnostics

func FormatDiagnostics(diags []Diagnostic) string

FormatDiagnostics formats diagnostics for human display.

Types

type AlwaysTrueRule

type AlwaysTrueRule struct{}

func (*AlwaysTrueRule) Check

func (r *AlwaysTrueRule) Check(info *FileInfo) []Diagnostic

func (*AlwaysTrueRule) Name

func (r *AlwaysTrueRule) Name() string

type CallGraph

type CallGraph struct {
	Nodes []CallGraphNode `json:"nodes"`
	Edges []CallGraphEdge `json:"edges"`
}

CallGraph holds the full call/signal graph extracted from source.

type CallGraphEdge

type CallGraphEdge struct {
	From   string `json:"from"`
	To     string `json:"to"`
	Type   string `json:"type"` // "call", "start", "signal", "set-mask"
	Line   int    `json:"line"`
	Script string `json:"script"`
}

CallGraphEdge represents a relationship between functions/signals.

type CallGraphNode

type CallGraphNode struct {
	Name string `json:"name"`
	Type string `json:"type"` // "function", "signal"
}

CallGraphNode represents a function or signal in the call graph.

type CyclomaticComplexityRule

type CyclomaticComplexityRule struct {
	MaxComplexity int
}

CyclomaticComplexityRule reports scripts whose cyclomatic complexity exceeds a threshold. CC is computed as 1 + the number of conditional branch instructions (JUMP_IF_FALSE). Each if/while adds one decision point.

func (*CyclomaticComplexityRule) Check

func (r *CyclomaticComplexityRule) Check(info *FileInfo) []Diagnostic

func (*CyclomaticComplexityRule) Name

func (r *CyclomaticComplexityRule) Name() string

type DeadCodeRule

type DeadCodeRule struct{}

func (*DeadCodeRule) Check

func (r *DeadCodeRule) Check(info *FileInfo) []Diagnostic

func (*DeadCodeRule) Name

func (r *DeadCodeRule) Name() string

type Diagnostic

type Diagnostic struct {
	Rule     string // rule identifier
	Severity Severity
	Script   string // script name ("" for file-level)
	Message  string
	Line     int // 1-based line number in the decompiled output (0 = unknown)
}

Diagnostic is a single lint finding.

func (Diagnostic) String

func (d Diagnostic) String() string

type DuplicateAnimationRule

type DuplicateAnimationRule struct{}

func (*DuplicateAnimationRule) Check

func (r *DuplicateAnimationRule) Check(info *FileInfo) []Diagnostic

func (*DuplicateAnimationRule) Name

func (r *DuplicateAnimationRule) Name() string

type DuplicateIfRule

type DuplicateIfRule struct{}

func (*DuplicateIfRule) Check

func (r *DuplicateIfRule) Check(info *FileInfo) []Diagnostic

func (*DuplicateIfRule) Name

func (r *DuplicateIfRule) Name() string

type EmptyFunctionRule

type EmptyFunctionRule struct{}

func (*EmptyFunctionRule) Check

func (r *EmptyFunctionRule) Check(info *FileInfo) []Diagnostic

func (*EmptyFunctionRule) Name

func (r *EmptyFunctionRule) Name() string

type FileInfo

type FileInfo struct {
	COB          *scripting.COB
	Scripts      []ScriptInfo
	ScriptNames  map[string]bool
	IsDecompiled bool // true when linting decompiled COB output (not raw BOS)
	// Line mappings from decompiled output.
	PieceDeclLine    int            // line of "piece ..." declaration
	StaticDeclLine   int            // line of "static-var ..." declaration
	ScriptStartLines map[string]int // script name → 1-based line
	ScriptParamCount map[string]int // script name → number of parameters (from call sites)
	// Lines where specific patterns occur in the decompiled output.
	AlwaysTrueLines    []decompiledHit // if(1)/while(1) occurrences
	DeadCodeLines      []decompiledHit // if(0)/while(0) occurrences
	SpeedZeroLines     []decompiledHit // move/turn with speed <0>
	EmptyFuncLines     []decompiledHit // functions with only return 0
	SleepOnlyGuards    []decompiledHit // if(x) { sleep N; }
	DuplicateAnimLines []decompiledHit // identical sequential animation commands
	DuplicateIfLines   []decompiledHit // back-to-back identical if conditions
	RawSignalLines     []decompiledHit // signal/set-signal-mask with raw numbers
	UnnamedGlobals     bool            // uses global_N naming
	DecompiledLines    []string        // the full decompiled source lines
	Graph              CallGraph       // call/signal graph
}

FileInfo holds analysis data for the entire COB file.

type InvalidCallRule

type InvalidCallRule struct{}

func (*InvalidCallRule) Check

func (r *InvalidCallRule) Check(info *FileInfo) []Diagnostic

func (*InvalidCallRule) Name

func (r *InvalidCallRule) Name() string

type Linter

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

Linter runs a set of rules against a COB file.

func New

func New() *Linter

New creates a Linter with the default rule set.

func (*Linter) GetCallGraph

func (l *Linter) GetCallGraph(cob *scripting.COB) *CallGraph

GetCallGraph analyzes a COB file and returns its call graph.

func (*Linter) GetCallGraphFromSource

func (l *Linter) GetCallGraphFromSource(cob *scripting.COB, sourceText string) *CallGraph

GetCallGraphFromSource analyzes BOS source text and returns its call graph.

func (*Linter) Lint

func (l *Linter) Lint(cob *scripting.COB) []Diagnostic

Lint analyzes a COB file (decompiled) and returns all diagnostics.

func (*Linter) LintSource

func (l *Linter) LintSource(cob *scripting.COB, sourceText string) []Diagnostic

LintSource analyzes BOS source text (compiled from .bos, not decompiled).

type LongFunctionRule

type LongFunctionRule struct {
	MaxLines int
}

func (*LongFunctionRule) Check

func (r *LongFunctionRule) Check(info *FileInfo) []Diagnostic

func (*LongFunctionRule) Name

func (r *LongFunctionRule) Name() string

type RawSignalRule

type RawSignalRule struct{}

func (*RawSignalRule) Check

func (r *RawSignalRule) Check(info *FileInfo) []Diagnostic

func (*RawSignalRule) Name

func (r *RawSignalRule) Name() string

type RecursiveCallRule

type RecursiveCallRule struct{}

func (*RecursiveCallRule) Check

func (r *RecursiveCallRule) Check(info *FileInfo) []Diagnostic

func (*RecursiveCallRule) Name

func (r *RecursiveCallRule) Name() string

type Rule

type Rule interface {
	Name() string
	Check(info *FileInfo) []Diagnostic
}

Rule is a lint check that produces zero or more diagnostics.

type ScriptInfo

type ScriptInfo struct {
	Name                 string
	Index                int
	Instructions         []scripting.Instruction
	LineCount            int
	LocalCount           int
	CyclomaticComplexity int
	UsedLocals           map[int]bool
	CalledScripts        []scriptCall
	UsedPieces           map[int]bool
	UsedStatics          map[int]bool
}

ScriptInfo holds analysis data for a single script.

type Severity

type Severity int

Severity indicates how serious a diagnostic is.

const (
	Warning Severity = iota
	Error
	Info
)

func (Severity) String

func (s Severity) String() string

type SignalNeverSignalledRule

type SignalNeverSignalledRule struct{}

func (*SignalNeverSignalledRule) Check

func (r *SignalNeverSignalledRule) Check(info *FileInfo) []Diagnostic

func (*SignalNeverSignalledRule) Name

func (r *SignalNeverSignalledRule) Name() string

type SleepOnlyGuardRule

type SleepOnlyGuardRule struct{}

func (*SleepOnlyGuardRule) Check

func (r *SleepOnlyGuardRule) Check(info *FileInfo) []Diagnostic

func (*SleepOnlyGuardRule) Name

func (r *SleepOnlyGuardRule) Name() string

type SpeedZeroRule

type SpeedZeroRule struct{}

func (*SpeedZeroRule) Check

func (r *SpeedZeroRule) Check(info *FileInfo) []Diagnostic

func (*SpeedZeroRule) Name

func (r *SpeedZeroRule) Name() string

type UnnamedGlobalRule

type UnnamedGlobalRule struct{}

func (*UnnamedGlobalRule) Check

func (r *UnnamedGlobalRule) Check(info *FileInfo) []Diagnostic

func (*UnnamedGlobalRule) Name

func (r *UnnamedGlobalRule) Name() string

type UnusedLocalRule

type UnusedLocalRule struct{}

func (*UnusedLocalRule) Check

func (r *UnusedLocalRule) Check(info *FileInfo) []Diagnostic

func (*UnusedLocalRule) Name

func (r *UnusedLocalRule) Name() string

type UnusedPieceRule

type UnusedPieceRule struct{}

func (*UnusedPieceRule) Check

func (r *UnusedPieceRule) Check(info *FileInfo) []Diagnostic

func (*UnusedPieceRule) Name

func (r *UnusedPieceRule) Name() string

type UnusedStaticRule

type UnusedStaticRule struct{}

func (*UnusedStaticRule) Check

func (r *UnusedStaticRule) Check(info *FileInfo) []Diagnostic

func (*UnusedStaticRule) Name

func (r *UnusedStaticRule) Name() string

Jump to

Keyboard shortcuts

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