Skip to content

Commit

Permalink
fix: improve checks of enum and record as soft keywords.
Browse files Browse the repository at this point in the history
Fixes #634.
  • Loading branch information
hishamhm committed Jul 19, 2023
1 parent bd41ad4 commit 58d8615
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 18 deletions.
7 changes: 7 additions & 0 deletions spec/declaration/enum_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,11 @@ describe("enum declaration", function()
]], {
{ y = 2, msg = "syntax error: this syntax is no longer valid; declare nested enum inside a record" },
}))

it("accepts enum as soft keyword", util.check([[
local enum = 2
local t = {
enum = enum,
}
]]))
end)
7 changes: 7 additions & 0 deletions spec/declaration/record_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ for i, name in ipairs({"records", "arrayrecords"}) do
{ y = 2, msg = "syntax error: this syntax is no longer valid; declare nested record inside a record" },
}))

it("accepts record as soft keyword", util.check([[
local record = 2
local t = {
record = record,
}
]]))

it("can be declared with 'global type'", util.check([[
global type Point = record ]]..pick(i, "", "{Point}")..[[
x: number
Expand Down
17 changes: 11 additions & 6 deletions tl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1480,14 +1480,19 @@ end

local function parse_table_value(ps, i)
local next_word = ps.tokens[i].tk
local e
if next_word == "record" then
i = failskip(ps, i, "syntax error: this syntax is no longer valid; declare nested record inside a record", skip_record)
elseif next_word == "enum" then
local skip_i, e = skip(ps, i, skip_record)
if e then
fail(ps, i, "syntax error: this syntax is no longer valid; declare nested record inside a record")
return skip_i, new_node(ps.tokens, i, "error_node")
end
elseif next_word == "enum" and ps.tokens[i + 1].kind == "string" then
i = failskip(ps, i, "syntax error: this syntax is no longer valid; declare nested enum inside a record", skip_enum)
else
i, e = parse_expression(ps, i)
return i, new_node(ps.tokens, i - 1, "error_node")
end

local e
i, e = parse_expression(ps, i)
if not e then
e = new_node(ps.tokens, i - 1, "error_node")
end
Expand Down Expand Up @@ -3022,7 +3027,7 @@ local function parse_type_constructor(ps, i, node_name, type_name, parse_body)
end

local function skip_type_declaration(ps, i)
return (parse_type_declaration(ps, i - 1, "local_type"))
return parse_type_declaration(ps, i - 1, "local_type")
end

local function parse_local(ps, i)
Expand Down
29 changes: 17 additions & 12 deletions tl.tl
Original file line number Diff line number Diff line change
Expand Up @@ -1450,9 +1450,9 @@ local function verify_kind(ps: ParseState, i: integer, kind: TokenKind, node_kin
return fail(ps, i, "syntax error, expected " .. kind)
end

local type SkipFunction = function(ParseState, integer): integer
local type SkipFunction = function(ParseState, integer): integer, Node

local function skip(ps: ParseState, i: integer, skip_fn: SkipFunction): integer
local function skip(ps: ParseState, i: integer, skip_fn: SkipFunction): integer, Node
local err_ps: ParseState = {
filename = ps.filename,
tokens = ps.tokens,
Expand Down Expand Up @@ -1480,14 +1480,19 @@ end

local function parse_table_value(ps: ParseState, i: integer): integer, Node, integer
local next_word = ps.tokens[i].tk
local e: Node
if next_word == "record" then
i = failskip(ps, i, "syntax error: this syntax is no longer valid; declare nested record inside a record", skip_record)
elseif next_word == "enum" then
local skip_i, e = skip(ps, i, skip_record)
if e then
fail(ps, i, "syntax error: this syntax is no longer valid; declare nested record inside a record")
return skip_i, new_node(ps.tokens, i, "error_node")
end
elseif next_word == "enum" and ps.tokens[i + 1].kind == "string" then
i = failskip(ps, i, "syntax error: this syntax is no longer valid; declare nested enum inside a record", skip_enum)
else
i, e = parse_expression(ps, i)
return i, new_node(ps.tokens, i - 1, "error_node")
end

local e: Node
i, e = parse_expression(ps, i)
if not e then
e = new_node(ps.tokens, i - 1, "error_node")
end
Expand Down Expand Up @@ -2083,7 +2088,7 @@ do
local key: Node
i = i + 1
if ps.tokens[i].kind ~= "identifier" then
local skipped = skip(ps, i, parse_type)
local skipped = skip(ps, i, parse_type as SkipFunction)
if skipped > i + 1 then
fail(ps, i, "syntax error, cannot declare a type here (missing 'local' or 'global'?)")
return skipped, failstore(tkop, e1)
Expand Down Expand Up @@ -2725,7 +2730,7 @@ parse_record_body = function(ps: ParseState, i: integer, def: Type, node: Node,
i = i + 1
elseif ps.tokens[i].tk == "{" then
if def.typename == "arrayrecord" then
i = failskip(ps, i, "duplicated declaration of array element type in record", parse_type)
i = failskip(ps, i, "duplicated declaration of array element type in record", parse_type as SkipFunction)
else
i = i + 1
local t: Type
Expand Down Expand Up @@ -2958,7 +2963,7 @@ local function parse_variable_declarations(ps: ParseState, i: integer, node_name
return failskip(ps, i + 1, "syntax error: this syntax is no longer valid; use '" .. scope .. " enum " .. asgn.vars[1].tk .. "'", skip_enum)
elseif next_word == "functiontype" then
local scope = node_name == "local_declaration" and "local" or "global"
return failskip(ps, i + 1, "syntax error: this syntax is no longer valid; use '" .. scope .. " type " .. asgn.vars[1].tk .. " = function('...", parse_function_type)
return failskip(ps, i + 1, "syntax error: this syntax is no longer valid; use '" .. scope .. " type " .. asgn.vars[1].tk .. " = function('...", parse_function_type as SkipFunction)
end

i, asgn = parse_assignment_expression_list(ps, i, asgn)
Expand Down Expand Up @@ -3021,8 +3026,8 @@ local function parse_type_constructor(ps: ParseState, i: integer, node_name: Nod
return i, asgn
end

local function skip_type_declaration(ps: ParseState, i: integer): integer
return (parse_type_declaration(ps, i - 1, "local_type"))
local function skip_type_declaration(ps: ParseState, i: integer): integer, Node
return parse_type_declaration(ps, i - 1, "local_type")
end

local function parse_local(ps: ParseState, i: integer): integer, Node
Expand Down

0 comments on commit 58d8615

Please sign in to comment.