Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alias doesn't handle # character in string #3016

Open
hraytilakhealthcare opened this issue Dec 30, 2024 · 1 comment
Open

Alias doesn't handle # character in string #3016

hraytilakhealthcare opened this issue Dec 30, 2024 · 1 comment

Comments

@hraytilakhealthcare
Copy link

How are you using the lua-language-server?

NeoVim

Which OS are you using?

Linux

What is the issue affecting?

Diagnostics/Syntax Checking

Expected Behaviour

Enum members can contain # character

Actual Behaviour

The LSP diagnostic reports an error on using it

Reproduction steps

  1. Create an enum alias with members containing #
    Given the following alias
---| "/vfx#impact_fx_creator"
---| "/sfx"
---| "/player#player_upgrader"
---| "/cauli"
---| "/game_over_ui"
---| "/in_game_ui"

  1. Notice that the type check considers the right-hand of # as a comment even though it's in the string
---@type component_url
local d =  "/vfx#impact_fx_creator"
  1. See error
Diagnostics:
1. Cannot assign `string` to parameter `"/cauli"|"/game_over_ui"|"/in_game_ui"|"/player#"|"/sfx"...(+1)`.
   - `string` cannot match `"/cauli"|"/game_over_ui"|"/in_game_ui"|"/player#"|"/sfx"...(+1)`

Additional Notes

No response

Log File

No response

@tomlau10
Copy link
Contributor

Root cause

After some debugging, this is related to how a multi-line alias annotation is parsed:

local resumeHead = nextComm.text:match '^%-%s*%|'
if resumeHead then
NextComment(i)
row = row + i + 1
local finishPos = nextComm.text:find('#', #resumeHead + 1) or #nextComm.text
parseTokens(nextComm.text:sub(#resumeHead + 1, finishPos), nextComm.start + #resumeHead + 1)
local resume = parseResume(result)
if resume then
if comments then
resume.comment = table.concat(comments, '\n')
else
resume.comment = nextComm.text:match('%s*#?%s*(.+)', resume.finish - nextComm.start)
end

---@alias DeviceSide
---| '"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
  • in the above parsing logic, it simply finds the position of a # to determine the start of the description part, which is the root cause

Observation

But actually I don't quite understand the need of this logic (finding the position of #) 😕
Because a description doesn't need to be preceded by a #.
The following will work too:

---@alias DeviceSide
---| '"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

Possible fix

I just remove the find('#') logic in line 945, and let parseTokens() to always be parse the whole line, seems can fix this issue 🤔

-    local finishPos = nextComm.text:find('#', #resumeHead + 1) or #nextComm.text
-    parseTokens(nextComm.text:sub(#resumeHead + 1, finishPos), nextComm.start + #resumeHead + 1)
+    parseTokens(nextComm.text:sub(#resumeHead + 1), nextComm.start + #resumeHead + 1)
  • let the parser always parse the whole line (without the --| head of course)
  • then the later logic at line 952 can still find a possible description starting from any unparsed resume.finish offset
  • works for both descriptions with or without preceding #
    image

I didn't dive deep to test it. Maybe you or others would like to finish it from there and open PR 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants