Skip to content

Annotations

carsakiller edited this page Aug 10, 2023 · 36 revisions

⚠️Warning

This wiki has been replaced by the wiki on our website. This wiki will be removed in the future.

Annotations

The language server does its best to infer types through contextual analysis, however, sometimes manual documentation is necessary to improve completion and signature information.

Annotations are prefixed with ---, like a Lua comment with one extra dash. To learn more, check out Formatting Annotations.

Note The annotations used by the server are based off of EmmyLua annotations but a rename is in progress.

⚠️ Warning: The annotations used by the server are no longer cross-compatible with EmmyLua annotations since v3.0.0.

The annotations are also described in script.lua which can be found in multiple languages in locale/. Corrections and translations can be provided in these script.lua files and submitted through a pull request.

Tips

  • If you type --- one line above a function, you will receive a suggested snippet that includes @param and @return annotations for each parameter and return value found in the function.

Documenting Types

Properly documenting types with the language server is very important and where a lot of the features and advantages are. Below is a list of all recognized Lua types (regardless of version in use):

  • nil
  • any
  • boolean
  • string
  • number
  • integer
  • function
  • table
  • thread
  • userdata
  • lightuserdata

You can also simulate classes and fields and even create your own types.

Adding a question mark ? after a type like boolean? or number? is the same as saying boolean|nil or number|nil. This can be used to specify that something is either a specified type or nil. This can be very useful for function returns where a value or nil can be returned.

Below is a list of how you can document more advanced types:

TypeDocument As
Union TypeTYPE_1 | TYPE_2
ArrayVALUE_TYPE[]
Dictionary{ [string]: VALUE_TYPE }
Key-Value Tabletable<KEY_TYPE, VALUE_TYPE>
Table Literal{ key1: VALUE_TYPE, key2: VALUE_TYPE }
Functionfun(PARAM: TYPE): RETURN_TYPE

Unions may need to be placed in parentheses in certain situations, such as when defining an array that contains multiple value types:

---@type (string | integer)[]localmyArray= {}

Understanding This Page

To get an understanding of how to use the annotations described on this page, you'll need to know how to read the Syntax sections of each annotation.

SymbolMeaning
<value_name>A required value that you provide
[value_name]Everything inside is optional
[value_name...]This value is repeatable
value_name | value_nameThe left or right side are valid

Any other symbols are syntactically required and should be copied verbatim.

If this is confusing, take a look at a couple examples under an annotation and it should make more sense.

Annotations List

Below is a list of all annotations recognized by the language server:

@alias

An alias can be useful when re-using a type. It can also be used to provide an enum. If you are looking for an enum and already have the values defined in a Lua table, take a look at @enum.

Syntax

---@alias <name> <type>

or

---@alias <name>---| '<value>' [# description]

Note The above pipe character (|) on the left is necessary for each line and does not signify an "or".

Examples

Simple Alias
---@aliasuserIDinteger The ID of a user
Custom Type
---@aliasmodes"r" | "w"
Custom Type with Descriptions
---@aliasside---| '"left"' # The left side of the device---| '"right"' # The right side of the device---| '"top"' # The top side of the device---| '"bottom"' # The bottom side of the device---| '"front"' # The front side of the device---| '"back"' # The back side of the device---@paramsidesidelocalfunctioncheckSide(side) end
Literal Custom Type
localA="Hello"localB="World"---@aliasmyLiteralAlias`A` | `B`---@paramxmyLiteralAliasfunctionfoo(x) end
Literal Custom Type with Descriptions
localA="Hello"localB="World"---@aliasmyLiteralAliases---|`A` # Will offer completion for A, which has a value of "Hello"---|`B` # Will offer completion for B, which has a value of "World"---@paramxmyLiteralAliasesfunctionfoo(x) end

alias


@as

Force a type onto an expression.

⚠️ Warning: This annotation cannot be added using ---@as <type> - it must be done like --[[@as <type>]].

Note When marking an expression as an array, such as string[], you must use --[=[@as string[]]=] due to the extra square brackets causing parsing issues.

Syntax

--[[@as <type>]]

Note The square brackets in the above syntax definition do not refer to it being optional. Those square brackets must be used verbatim.

Examples

Override Type
---@paramkeystring Must be a stringlocalfunctiondoSomething(key) endlocalx=nildoSomething(x--[[@as string]])

as


@async

Mark a function as being asynchronous. When hint.await is true, functions marked with @async will have an await hint displayed next to them. Used by diagnostics from the await group.

Syntax

---@async

Examples

Asynchronous Declaration
---@async---Perform an asynchronous HTTP GET requestfunctionhttp.get(url) end

async


@cast

Cast a variable to a different type or types

Syntax

---@cast <value_name> [+|-]<type|?>[, [+|-]<type|?>...]

Examples

Simple Cast
---@typeintegerlocalx---@castxstringprint(x) --> x: string
Add Type
---@typeintegerlocalx---@castx+booleanprint(x) --> x: integer | boolean
Remove Type
---@typeinteger|stringlocalx---@castx-integerprint(x) --> x: string
Cast multiple types
---@typestringlocalx--> x: string---@castx+boolean, +numberprint(x) --> x:string | boolean | number
Cast unknown
---@typestringlocalx---@castx+?print(x) --> x:string?

@class

Define a class. Can be used with @field to define a table structure. Once a class is defined, it can be used as a type for parameters, returns, and more. A class can also inherit from a parent class.

Syntax

---@class <name>[: <parent>]

Examples

Define a Class
---@classCarlocalCar= {}
Class Inheritance
---@classVehiclelocalVehicle= {}
---@classPlane:VehiclelocalPlane= {}

@deprecated

Mark a function as deprecated. This will trigger the deprecated diagnostic, displaying it as struck through.

Syntax

---@deprecated

Examples

Mark function as deprecated
---@deprecatedfunctionoutdated() end

@diagnostic

Toggle diagnostics for the next line, current line, or whole file.

Syntax---@diagnostic <state>:<diagnostic>

state options:

  • disable-next-line (Disable diagnostic on the following line)
  • disable-line (Disable diagnostic on this line)
  • disable (Disable diagnostic in this file)
  • enable (Enable diagnostic in this file)

Examples

Disable diagnostic on next line
---@diagnosticdisable-next-line:unused-local

Enable spell checking in this file
---@diagnosticenable:spell-check

@enum

Mark a Lua table as an enum, giving it similar functionality to @alias, only the table is still usable at runtime.

View Original Request

Syntax

---@enum <name>

Examples

Define table as enum
---@enumcolorslocalCOLORS= {
black=0,
red=2,
green=4,
yellow=8,
blue=16,
white=32
}
---@paramcolorcolorslocalfunctionsetColor(color) endsetColor(COLORS.green)

enum


@field

Define a field within a table. Should be immediately following a @class. As of v3.6.0, you can mark a field as private, protected, public, or package.

Syntax

Note\[ and \] below mean literal [ and ]


---@field [scope] <name> <type> [description]
---@field [scope] \[<type>\] <type> [description]

Examples

Simple documentation of class
---@classPerson---@fieldheightnumber The height of this person in cm---@fieldweightnumber The weight of this person in kg---@fieldfirstNamestring The first name of this person---@fieldlastNamestring The last name of this person---@fieldageinteger The age of this person---@parampersonPersonlocalfunctionhire(person) end

field

Mark field as private
---@classAnimal---@fieldprivatelegs integer---@fieldeyesinteger---@classDog:AnimallocalmyDog= {}
---Child class Dog CANNOT use private field legsfunctionmyDog:legCount()
returnself.legsend
Mark field as protected
---@classAnimal---@fieldprotectedlegs integer---@fieldeyesinteger---@classDog:AnimallocalmyDog= {}
---Child class Dog can use protected field legsfunctionmyDog:legCount()
returnself.legsend
Typed field

Note Named fields must be declared before typed field if type is string

---@classNumbers---@fieldnamedstring---@field[string] integerlocalNumbers= {}

@generic

Generics allow code to be reused and serve as a sort of "placeholder" for a type. Surrounding the generic in backticks (`) will capture the value and use it for the type. Generics are still WIP.

Syntax

---@generic <name> [:parent_type] [, <name> [:parent_type]]

Examples

Generic Function
---@genericT:integer---@paramp1T---@returnT, T[]functionGeneric(p1) end-- v1: string-- v2: string[]localv1, v2=Generic("String")
-- v3: integer-- v4: integer[]localv3, v4=Generic(10)
Capture with Backticks
---@classVehiclelocalVehicle= {}
functionVehicle:drive() end---@genericT---@paramclass`T` # the type is captured using `T`---@returnT # generic type is returnedlocalfunctionnew(class) end-- obj: Vehiclelocalobj=new("Vehicle")
How the Table Class is Implemented
---@classtable<K,V>: { [K]:V }
Array Class Using Generics
---@classArray<T>: { [integer]:T }---@typeArray<string>localarr= {}
-- Warns that I am assigning a boolean to a stringarr[1] =falsearr[3] ="Correct"

See #734

Dictionary class using generics
---@classDictionary<T>: { [string]:T }---@typeDictionary<boolean>localdict= {}
-- no warning despite assigning a stringdict["foo"] ="bar?"dict["correct"] =true

See #734


@meta

Marks a file as "meta", meaning it is used for definitions and not for its functional Lua code. Used internally by the language server for defining the built-in Lua libraries. If you are writing your own definition files, you will probably want to include this annotation in them. If you specify a name, it will only be able to be required by the given name. Giving the name _ will make it unable to be required. Files with the @meta tag in them behave a little different:

  • Completion will not display context in a meta file
  • Hovering a require of a meta file will show [meta] instead of its absolute path
  • Find Reference ignores meta files

Syntax

---@meta [name]

Examples

Mark Meta File
---@meta

@module

Simulates require-ing a file.

Syntax

---@module '<module_name>'

Examples

"Require" a File
---@module'http'--The above provides the same asrequire'http'--within the language server
"Require" a File and Assign to a Variable
---@module'http'localhttp--The above provides the same aslocalhttp=require'http'--within the language server

@nodiscard

Mark a function as having return values that cannot be ignored/discarded. This can help users understand how to use the function as if they do not capture the returns, a warning will be raised.

Syntax

---@nodiscard

Examples

Prevent Ignoring a Function's Returns
---@returnstring username---@nodiscardfunctiongetUsername() end

@operator

Provides type declarations for an operator metamethod.

View Original Request

Syntax

---@operator <operation>[(input_type)]:<resulting_type>

ℹ️ Note: This syntax differs slightly from the fun() syntax used for defining functions. Notice that the parentheses are optional here, so @operator call:integer is valid.

Examples

Declare __add Metamethod
---@classVector---@operatoradd(Vector): Vector---@typeVectorlocalv1---@typeVectorlocalv2--> v3: Vectorlocalv3=v1+v2
Declare Unary Minus Metamethod
---@classPasscode---@operation unm:integer---@typePasscodelocalpAlocalpB=-pA--> integer
Declare __call Metamethod

ℹ️ Note: it is recommended to instead use @overload to specify the call signature for a class.

---@classURL---@operatorcall:stringlocalURL= {}

@overload

Define an additional signature for a function. This does not allow descriptions to be provided for the new signature being defined - if you want descriptions, you are better off writing out an entire function with the same name but different @param and @return annotations.

Syntax

---@overload fun([param: type[, param: type...]]): [return_value[, return_value]]

Examples

Define Function Overload
---@paramobjectIDinteger The id of the object to remove---@paramwhenOutOfViewboolean Only remove the object when it is not visible---@returnboolean success If the object was successfully removed---@overloadfun(objectID: integer): booleanlocalfunctionremoveObject(objectID, whenOutOfView) end
Define Class Call Signature
---@overloadfun(a: string): booleanlocalfoo=setmetatable({}, {
__call=function(a)
print(a)
returntrueend,
})
localbool=foo("myString")

@package

Mark a function as private to the file it is defined in. A packaged function cannot be accessed from another file.

Syntax

---@package

Examples

Mark a function as package-private
---@classAnimal---@fieldprivateeyes integerlocalAnimal= {}
---@package---This cannot be accessed in another filefunctionAnimal:eyesCount()
returnself.eyesend

@param

Define a parameter for a function. This tells the language server what types are expected and can help enforce types and provide completion. Putting a question mark (?) after the parameter name will mark it as optional, meaning nil is an accepted type. The type provided can be an @alias, @enum, or @class as well.

Syntax

---@param <name[?]> <type[|type...]> [description]

Examples

Simple Function Parameter
---@paramusernamestring The name to set for this userfunctionsetUsername(username) end
Parameter Union Type
---@paramsettingstring The name of the setting---@paramvaluestring|number|boolean The value of the settinglocalfunctionsettings.set(setting, value) end
Optional Parameter
---@paramrolestring The name of the role---@paramisActive?boolean If the role is currently active---@returnRolefunctionRole.new(role, isActive) end
Variable Number of Parameters
---@paramindexinteger---@param ... stringTags to add to this entrylocalfunctionaddTags(index, ...) end
Generic Function Parameter
---@classBox---@genericT---@paramobjectIDinteger The ID of the object to set the type of---@paramtype`T` The type of object to set---@return`T` object The object as a Lua objectlocalfunctionsetObjectType(objectID, type) end--> boxObject: BoxlocalboxObject=setObjectType(1, "Box")

See @generic for more info.

Custom Type Parameter
---@parammodestring---|"'immediate'" # comment 1---|"'async'" # comment 2functionbar(mode) end
Literal Custom Type Parameter
localA=0localB=1---@paramactiveinteger---| `A` # Has a value of 0---| `B` # Has a value of 1functionset(active) end

Looking to do this with a table? You probably want to use @enum


@private

Mark a function as private to a @class. Private functions can be accessed only from within their class and are not accessable from child classes.

Syntax

---@private

Examples

Mark a function as private
---@classAnimal---@fieldprivateeyes integerlocalAnimal= {}
---@privatefunctionAnimal:eyesCount()
returnself.eyesend---@classDog:AnimallocalmyDog= {}
---NOT PERMITTED!myDog:eyesCount();

@protected

Mark a function as protected within a @class. Protected functions can be accessed only from within their class or from child classes.

Syntax

---@protected

Examples

Mark a function as protected
---@classAnimal---@fieldprivateeyes integerlocalAnimal= {}
---@protectedfunctionAnimal:eyesCount()
returnself.eyesend---@classDog:AnimallocalmyDog= {}
---Permitted because function is protected, not private.myDog:eyesCount();

@return

Define a return value for a function. This tells the language server what types are expected and can help enforce types and provide completion.

Syntax

---@return <type> [<name> [comment] | [name] #<comment>]

Examples

Simple Function Return
---@returnbooleanlocalfunctionisEnabled() end
Named Function Return
---@returnboolean enabledlocalfunctionisEnabled() end
Named, Described Function Return
---@returnboolean enabled If the item is enabledlocalfunctionisEnabled() end
Described Function Return
---@returnboolean # If the item is enabledlocalfunctionisEnabled() end
Optional Function Return
---@returnboolean|nil errorlocalfunctionmakeRequest() end
Variable Function Returns
---@returninteger count Number of nicknames found---@returnstring ...localfunctiongetNicknames() end

@see

Currently has no function other than allowing you to add a basic comment. This is not shown when hovering and has no additional functionality yet.

Syntax

---@see

Examples

Basic Usage
---@seehttp.getfunctionrequest(url) end

@source

Provide a reference to some source code which lives in another file. When searching for the defintion of an item, its @source will be used.

Syntax

@source <path>

Examples

Link to file using absolute path
---@source C:/Users/me/Documents/program/myFile.clocala
Link to file using URI
---@source file:///C:/Users/me/Documents/program/myFile.c:10localb
Link to file using relative path
---@source local/file.clocalc
Link to line and character in file
---@source local/file.c:10:8locald

@type

Mark a variable as being of a certain type. Union types are separated with a pipe character |. The type provided can be an @alias, @enum, or @class as well. Please note that you cannot add a field to a class using @type, you must instead use @class.

Syntax

---@type <type>

Examples

Basic Type Definition
---@typebooleanlocalx
Union Type Definition
---@typeboolean|numberlocalx
Array Type Definition
---@typestring[]localnames
Dictionary Type Definition
---@type{ [string]: boolean }localstatuses
Table Type Definition
---@typetable<userID, Player>localplayers
Union Type Definition
---@typeboolean|number|"yes"|"no"localx
Function Type Definition
---@typefun(name: string, value: any): booleanlocalx

@vararg


🚮 DEPRECATED 🚮

This annotation has been deprecated and is purely for legacy support for EmmyLua annotations.

You should instead use @param for documenting parameters, variable or not.

Mark a function as having variable arguments. For variable returns, see @return.

Syntax

---@vararg <type>

Examples

Basic Variable Function Arguments
---@varargstringfunctionconcat(...) end

@version

Mark the required Lua version for a function or @class.

Syntax

---@version [<|>]<version> [, [<|>]version...]

Possible version values:

  • 5.1
  • 5.2
  • 5.3
  • 5.4
  • JIT

Examples

Declare Function Version
---@version>5.2,JITfunctionhello() end
Declare Class Version
---@version5.4---@classEntry

See @class for more info

Links

Found an issue? Report it on the issue tracker.

Unit tests for the annotations can be found in test/definition/luadoc.lua.

Clone this wiki locally