EmmyLua’s diagnostic system provides real-time feedback on code quality, detecting errors, warnings, and potential issues as you type. The system is built on advanced static analysis techniques and leverages EmmyLua annotations for precise type checking.
Real-time Detection
Instant feedback as you type with no compilation required
Type Safety
Comprehensive type checking using EmmyLua annotations
Flexible Control
Fine-grained control via comments and configuration
Smart Analysis
Context-aware diagnostics that understand Lua semantics
Control diagnostics at file-level or line-level using special comments.
File-level Disable
Next-line Disable
Line Disable
Disable specific diagnostics for an entire file:
---@diagnostic disable: undefined-global---@diagnostic disable: unused-local-- All 'undefined-global' and 'unused-local' warnings-- are suppressed in this fileglobalVar = "allowed"local unusedVar = 42
Usage:
Place at the top of your file
Can disable multiple diagnostic types
Affects entire file scope
Disable diagnostics for the next line only:
---@diagnostic disable-next-line: undefined-globalDEBUG_MODE = true -- This specific line won't trigger warning---@diagnostic disable-next-line: unused-local, undefined-globallocal temp = GLOBAL_CONSTANT -- Multiple diagnostics disabled
Usage:
Place immediately before the target line
Can disable multiple diagnostic types
More precise than file-level control
Disable diagnostics for the current line:
local value = unknownFunc() ---@diagnostic disable-line: undefined-global
-- Error: undefined global 'unknownVar'print(unknownVar)-- Fix: Define or declare the variable---@type stringlocal myVar = "defined"print(myVar)-- Or declare as global---@diagnostic disable-next-line: undefined-global---@type stringGLOBAL_VAR = "global"
type-check
Validates type compatibility in assignments and function calls.
---@param count numberlocal function setCount(count) -- Implementationend-- Error: expected number, got stringsetCount("not a number")-- Correct usagesetCount(42)
undefined-field
Detects access to undefined table fields.
---@class User---@field name string---@field age numberlocal User = {}---@type Userlocal user = { name = "John", age = 30 }-- Error: undefined field 'email'print(user.email)
deprecated
Warns about usage of deprecated functions or fields.
---@deprecated Use newFunction insteadlocal function oldFunction() -- Implementationend-- Warning: oldFunction is deprecatedoldFunction()
local function process() local unusedVar = 42 -- Warning: unused local variable local usedVar = 10 return usedVarend-- Fix: Remove unused variable or prefix with underscorelocal function process() local _unusedVar = 42 -- No warning (convention) local usedVar = 10 return usedVarend
unused-parameter
Detects unused function parameters.
-- Warning: parameter 'b' is unusedlocal function add(a, b) return aend-- Fix: Use underscore prefix for intentionally unused parameterslocal function add(a, _b) return aend
unreachable-code
Detects code that can never be executed.
local function example() return true print("unreachable") -- Warning: unreachable codeend
duplicate-set-field
Detects duplicate field assignments in table constructors.
local config = { timeout = 30, retries = 3, timeout = 60 -- Warning: duplicate field 'timeout'}
-- Changes in this file may affect diagnostics in other files---@class Configlocal Config = {}function Config:getValue() return self.valueendreturn Config
Add type annotations to your code for better diagnostic accuracy:
---@param name string The user's name---@param age number The user's age---@return boolean success Whether the operation succeededlocal function registerUser(name, age) -- Implementation with full type checking return trueend
2
Configure Appropriately
Adjust diagnostic settings to match your project’s needs: