LuaLS / LuaLS/lua-language-server
Add `upvalue` semantic token modifier
Nobody has claimed this yet.
- Dominant language
- Lua
- Stars
- 4.4k
- Forks
- 442
- PR merge metrics
- No merged PRs in 30d
Description
LuaLS should expose whether a `variable` reference is an upvalue through a new `upvalue` semantic token modifier.
Currently, local variables and upvalues are both reported as:
```text
semantic token type: variable
modifiers: -
```
while globals are already distinguished using:
```text
semantic token type: variable
modifiers: global
```
This makes it impossible for editors such as VS Code to visually distinguish local variables from upvalues.
## Example
```lua
local function outer()
local value = 123
return function()
print(value) -- upvalue
end
end
```
Currently the `value` reference inside the inner function is:
```text
variable
```
It would be useful for LuaLS to report it as:
```text
variable + upvalue
```
while the declaration remains:
```text
variable
```
## Proposed semantic token model
```text
variable -> local variable
variable + upvalue -> upvalue
variable + global -> global variable
parameter -> function parameter
```
For example:
```lua
local foo = 1
local function outer(bar)
local baz = 2
return function(qux)
print(foo) -- upvalue
print(bar) -- upvalue
print(baz) -- upvalue
print(qux) -- parameter
print(print) -- global
end
end
```
would produce approximately:
```text
foo -> variable + upvalue
bar -> variable + upvalue
baz -> variable + upvalue
qux -> parameter
print -> variable + global
```
Ordinary locals would remain simply:
```text
variable
```
## Why a modifier?
A modifier seems preferable to introducing a new semantic token type because `upvalue` describes a property of a variable reference rather than a fundamentally different kind of symbol.
It also fits the existing LuaLS representation of globals:
```text
variable + global
```
This gives editor themes a simple way to distinguish all four cases:
```text
variable
variable + upvalue
variable + global
parameter
```
## Scope
The `upvalue` modifier should be applied to references resolved to a variable declared in an enclosing lexical scope.
For example:
```lua
local x = 1
local function f()
print(x)
end
```
would be:
```text
x declaration -> variable
x reference -> variable + upvalue
```
Nested closures should work recursively.
## Motivation
This would allow VS Code themes to use different colors for locals, parameters, upvalues, and globals, making lexical scope much easier to understand in closure-heavy Lua/LuaJIT code.
LuaLS already performs the necessary lexical-scope resolution; this proposal would expose that information through semantic tokens.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue names no files or tests. Start by locating LuaLS semantic-token generation and the lexical-scope resolution used for variable references; trace how the existing global modifier is assigned. Done means references resolved to enclosing-scope variables receive an upvalue modifier, declarations and ordinary locals remain unchanged, and nested closures are covered by tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- lua
- Domain
- devtools
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100