Skip to content

Commit 3cb3721

Browse files
committed
feat(parser): add support for Lua 5.4 attributes in global declarations
1 parent eea104d commit 3cb3721

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

spec/parser_spec.lua

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,48 @@ describe("parser", function()
580580
end)
581581
end)
582582

583+
describe("when parsing global declarations", function()
584+
it("parses global declaration correctly", function()
585+
assert.same({tag = "Global", {
586+
{tag = "Id", "a"}
587+
}
588+
}, get_node("global a"))
589+
assert.same({tag = "Global", {
590+
{tag = "Id", "a"},
591+
{tag = "Id", "b"}
592+
}
593+
}, get_node("global a, b"))
594+
end)
595+
596+
it("accepts Lua 5.4 attributes on global declarations", function()
597+
assert.same({tag = "Global", {
598+
{tag = "Id", "a"}
599+
}
600+
}, get_node("global a <close>"))
601+
assert.same({tag = "Global", {
602+
{tag = "Id", "a"},
603+
{tag = "Id", "b"}
604+
}
605+
}, get_node("global a <close>, b <const>"))
606+
assert.same({
607+
tag = "Global", {
608+
{tag = "Id", "a"}
609+
}, {
610+
{tag = "Id", "b"}
611+
}
612+
}, get_node("global a <close> = b"))
613+
assert.same({
614+
tag = "Global", {
615+
{tag = "Id", "a"},
616+
{tag = "Id", "b"}
617+
}, {
618+
{tag = "Id", "c"},
619+
{tag = "Id", "d"}
620+
}
621+
}, get_node("global a <close>, b <const> = c, d"))
622+
end)
623+
end)
624+
583625
describe("when parsing assignments", function()
584626
it("parses single target assignment correctly", function()
585627
assert.same({

src/luacheck/parser.lua

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,35 @@ statements["local"] = function(state)
837837
return new_inner_node(start_range, rhs and rhs[#rhs] or lhs[#lhs], "Local", {lhs, rhs})
838838
end
839839

840+
statements["global"] = function(state)
841+
local start_range = copy_range(state)
842+
-- Skip "global".
843+
skip_token(state)
844+
845+
-- Global definition, potentially with assignment.
846+
local lhs = {}
847+
local rhs
848+
849+
repeat
850+
lhs[#lhs + 1] = parse_id(state)
851+
852+
-- Check if a Lua 5.4/5.5 attribute is present
853+
if state.token == "<" then
854+
-- Consume and ignore attribute for now
855+
skip_token(state)
856+
check_name(state)
857+
skip_token(state)
858+
check_and_skip_token(state, ">")
859+
end
860+
until not test_and_skip_token(state, ",")
861+
862+
if test_and_skip_token(state, "=") then
863+
rhs = parse_expression_list(state)
864+
end
865+
866+
return new_inner_node(start_range, rhs and rhs[#rhs] or lhs[#lhs], "Global", {lhs, rhs})
867+
end
868+
840869
statements["::"] = function(state)
841870
local start_range = copy_range(state)
842871
-- Skip "::".

0 commit comments

Comments
 (0)