diff --git a/changelog.md b/changelog.md index daefdb5ae..21ae27119 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,7 @@ ## Unreleased +* `FIX` `continue` (LuaJIT extensions or `Lua.runtime.nonstandardSymbol`) followed by a comment on the same line (e.g. `continue -- note`) is now parsed as a `continue` statement instead of reporting `exp-in-action` [#3474](https://github.com/LuaLS/lua-language-server/issues/3474) ## 3.19.2 `2026-10-13` diff --git a/script/parser/compile.lua b/script/parser/compile.lua index e936d52b7..7cfca3b85 100644 --- a/script/parser/compile.lua +++ b/script/parser/compile.lua @@ -4950,16 +4950,25 @@ function parseAction() if token == 'continue' and (State.options.nonstandardSymbol['continue'] or State.luaJITExtensions) then -- continue 是 soft keyword:仅当其后为换行/`;`/块结束符时才视为 continue 语句, - -- 否则(如 `continue = 2`、`continue()`)作为变量名 - local nextToken = Tokens[Index + 3] - if nextToken == nil - or NLMap[nextToken] - or nextToken == ';' - or nextToken == 'end' - or nextToken == 'else' - or nextToken == 'elseif' - or nextToken == 'until' - or nextToken == ')' then + -- 否则(如 `continue = 2`、`continue()`)作为变量名;中间的注释用 skipComment 跳过后再回退 + local savePoint = getSavePoint() + local commCount = #State.comms + Index = Index + 2 + repeat until not skipComment() + local nextToken = Tokens[Index + 1] + local isStatement = nextToken == nil + or NLMap[nextToken] + or nextToken == ';' + or nextToken == 'end' + or nextToken == 'else' + or nextToken == 'elseif' + or nextToken == 'until' + or nextToken == ')' + savePoint() + for i = commCount + 1, #State.comms do + State.comms[i] = nil + end + if isStatement then return parseBreak() end end diff --git a/test/parser_test/luajit_ext.lua b/test/parser_test/luajit_ext.lua index 4367096d1..27afe51b6 100644 --- a/test/parser_test/luajit_ext.lua +++ b/test/parser_test/luajit_ext.lua @@ -134,6 +134,10 @@ TestLuaJITExt 'while true do continue end' TestLuaJITExt 'for i = 1, 10 do continue end' TestLuaJITExt 'repeat continue until false' TestLuaJITExtDisabled 'while true do continue end' +-- continue 后跟注释(#3474) +TestLuaJITExt 'while true do continue -- comment\nend' +TestLuaJITExt 'while true do continue --[[ comment ]] end' +TestLuaJITExt 'while true do continue --[==[ multi\nline ]==]\nend' print('LuaJIT 扩展基本语法用例通过') @@ -244,6 +248,14 @@ TestIndividual('number_underscore', 'local a = 0x1_2') TestIndividual('number_underscore', 'local a = 1_2.3_4') TestIndividual('number_underscore', 'local a = 1e1_0') TestIndividualDisabled('number_underscore', 'local a = 1_234') +-- continue(soft keyword),后跟注释时仍为 continue 语句(#3474) +TestIndividual('continue', 'for i = 1, 2 do continue end') +TestIndividual('continue', 'for i = 1, 2 do\n continue -- trailing comment\nend') +TestIndividual('continue', 'for i = 1, 2 do continue --[[ comment ]] end') +TestIndividual('continue', 'continue = 1') +TestIndividual('continue', 'continue --[[ comment ]] = 1') +TestIndividual('continue', 'continue --[[ multi\nline ]] = 1') +TestIndividualDisabled('continue', 'for i = 1, 2 do continue end') print('LuaJIT 扩展单独启用用例通过')