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

chore: add type annotations and resolve LSP warnings #2555

Merged
merged 28 commits into from
Dec 9, 2023

Conversation

Akmadan23
Copy link
Collaborator

@Akmadan23 Akmadan23 commented Nov 24, 2023

Initially discussed in #2455
WIP: There are still some decisions to be made here

Copy link
Collaborator Author

@Akmadan23 Akmadan23 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then there two general discussion points:

  • Style inconsistency: the majority of docs comments is of type ---@ but there are still some --- @. I don't know if one should be enforced instead of the other (---@ should be the official one), unfortunately stylua hasn't an option to check it.
  • Setup functions: this is almost irrelevant, I did not add type annotations to the various M.setup functions since they are all the same and are intuitive, but I would still add them just for completeness

---@class FileNode: BaseNode
---@field extension string

---@alias Node ParentNode|DirNode|FileNode
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the Node type I managed to come up with, let me know if it's ok and most importantly where it should go. I put it here just to put it temporarily somewhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where it should go.

Where is indeed difficult. We could just create nvim-tree/node.lua just to hold the definitions.

When we eventually get to creating proper node classes they can live in there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the Node type I managed to come up with, let me know if it's ok

It's great! It contains all that we know about.

LLS can tell us if we're using an unknown field and we can add as we discover them.

local function remove_dir(cwd)
local handle = vim.loop.fs_scandir(cwd)
if type(handle) == "string" then
return notify.error(handle)
notify.error(handle)
return
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some cases I added an explicit nil return instead of returning the call of a function that returns nil.

else
local newdir = vim.fn.fnamemodify(utils.path_remove_trailing(core.get_cwd()), ":h")
require("nvim-tree.actions.root.change-dir").fn(newdir)
return require("nvim-tree.actions.finders.find-file").fn(node.absolute_path)
require("nvim-tree.actions.finders.find-file").fn(node.absolute_path)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed pointless and misleading returns as well

function Runner:_run_git_job(callback)
local handle, pid
local stdout = vim.loop.new_pipe(false)
local stderr = vim.loop.new_pipe(false)
local timer = vim.loop.new_timer()

if stdout == nil or stderr == nil or timer == nil then
return
end
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this little check to silence the "Need nil check" warnings.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where we really gain the value.

@alex-courtis
Copy link
Member

alex-courtis commented Nov 25, 2023

Style inconsistency: the majority of docs comments is of type ---@ but there are still some --- @. I don't know if one should be enforced instead of the other (---@ should be the official one), unfortunately stylua hasn't an option to check it.

---@ does seem the convention.

It doesn't look like the LLS formatter has it either: https://github.com/CppCXY/EmmyLuaCodeStyle/blob/master/docs/format_config_EN.md

We could run find lua -type f -exec sed -i 's/^--- @/---@/g' {} \; every now and then if people aren't following it.

Alternatively, add grep -r "^--- @" lua to the Makefile.

@alex-courtis
Copy link
Member

Setup functions: this is almost irrelevant, I did not add type annotations to the various M.setup functions since they are all the same and are intuitive, but I would still add them just for completeness

Agreed, minimal value. I'm happy enough to do nothing.

In the future we could do an Options class however that would be a lot of maintenance...

Copy link
Member

@alex-courtis alex-courtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incredible. This will pay off immediately and continually.

---@class ParentNode
---@field name string

---@class BaseNode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fantastic... finding all these bits every time always slows me down.

function Runner:_run_git_job(callback)
local handle, pid
local stdout = vim.loop.new_pipe(false)
local stderr = vim.loop.new_pipe(false)
local timer = vim.loop.new_timer()

if stdout == nil or stderr == nil or timer == nil then
return
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where we really gain the value.

---@class FileNode: BaseNode
---@field extension string

---@alias Node ParentNode|DirNode|FileNode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where it should go.

Where is indeed difficult. We could just create nvim-tree/node.lua just to hold the definitions.

When we eventually get to creating proper node classes they can live in there.

---@class FileNode: BaseNode
---@field extension string

---@alias Node ParentNode|DirNode|FileNode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the Node type I managed to come up with, let me know if it's ok

It's great! It contains all that we know about.

LLS can tell us if we're using an unknown field and we can add as we discover them.

@alex-courtis
Copy link
Member

What do you think about a SymlinkDirNode and SymlinkFileNode? lua does support multiple inheritence...

@Akmadan23
Copy link
Collaborator Author

What do you think about a SymlinkDirNode and SymlinkFileNode?

Right, I completely forgot about symlinks.

Alternatively, add grep -r "^--- @" lua to the Makefile.

Or better yet add it to the style check so that it's done automatically.

We could just create nvim-tree/node.lua just to hold the definitions.

Yeah, I'm not sure if LLS cares about files that are not imported tho...
Otherwise we can put it in the lib module which is the most generic I guess.

@alex-courtis
Copy link
Member

alex-courtis commented Nov 25, 2023

Yeah, I'm not sure if LLS cares about files that are not imported tho...
Otherwise we can put it in the lib module which is the most generic I guess.

It looks like they've added the @meta annotation to handle this case.

Or better yet add it to the style check so that it's done automatically.

Yes please! If you can find a simple way that would be fantastic.

Right, I completely forgot about symlinks.

Only if it's a small amount of effort. We can iterate on this.

@alex-courtis
Copy link
Member

alex-courtis commented Nov 26, 2023

I had a play with #2546 against this branch... down to 16 warnings! Nice work.

uvlib.patch.gz adds libuv so that we can reference uv.uv_fs_t and friends, which takes us to 11.

@Akmadan23
Copy link
Collaborator Author

It looks like they've added the @meta annotation to handle this case.

Nice, I didn't know that.

If you can find a simple way that would be fantastic.

I'm working on it, seems to be pretty straight forward.

uvlib.patch.gz adds libuv so that we can reference uv.uv_fs_t and friends, which takes us to 11.

Feel free to push to this branch if you need to.

@hinell
Copy link
Contributor

hinell commented Nov 26, 2023

Nice. We actually need to document basic strcture: Node.

It seems like there is no class for that.

@alex-courtis
Copy link
Member

Feel free to push to this branch if you need to.

Done.

@alex-courtis
Copy link
Member

I've taken the liberty of adding scripts/luals-check and fixing some nits.

I'd like to free you up to continue the actual work.

Some recipes:
scripts/luals-check | grep "file:"
scripts/luals-check | jq --color-output
scripts/luals-check | yq --colors -p json

@alex-courtis
Copy link
Member

Nice. We actually need to document basic strcture: Node.

It seems like there is no class for that.

Please Seek First To Understand: https://github.com/nvim-tree/nvim-tree.lua/blob/type-annotations/lua/nvim-tree/node.lua

@Akmadan23
Copy link
Collaborator Author

I've taken the liberty of adding scripts/luals-check and fixing some nits.

Will it be added in this PR? I'd rather add it with a separate PR... By the way I haven't commented on #2546 yet because I tested it on this branch and it runs as expected, but on master it doesn't find any problem, where that is clearly not the case. I also experienced a similar behavior when I was adding type annotations in some files, and only then LLS displayed warnings about something completely unrelated to the annotations just added...

@alex-courtis
Copy link
Member

I've taken the liberty of adding scripts/luals-check and fixing some nits.

Will it be added in this PR? I'd rather add it with a separate PR... By the way I haven't commented on #2546 yet because I tested it on this branch and it runs as expected, but on master it doesn't find any problem, where that is clearly not the case. I also experienced a similar behavior when I was adding type annotations in some files, and only then LLS displayed warnings about something completely unrelated to the annotations just added...

Pulling it out now.

Are you cool with the little fixes?

@@ -4,21 +4,24 @@ local NvimTreeMarks = {}

local M = {}

---@param node Node
---@class MinimalNode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow... I like this one... I'm seeing many possibilities.

Copy link
Collaborator Author

@Akmadan23 Akmadan23 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to my tests we should be down to just 4 warnings, 3 of which start from a non-issue in my opinion. More details in the comments

local function create_and_notify(file)
events._dispatch_will_create_file(file)
local ok, fd = pcall(vim.loop.fs_open, file, "w", 420)
if not ok then
notify.error("Couldn't create file " .. notify.render_path(file))
return
end
vim.loop.fs_close(fd)
vim.loop.fs_close(tonumber(fd) or error "This will never happen")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's not the best solution, but it works...

Copy link
Member

@alex-courtis alex-courtis Dec 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is difficult. We're struggling with similar issues at my workplace right now...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we revert this one? It's correct and it passes checks.

Dealing with the vim. luals issues is a job for another day, if we even want to do it.

@@ -31,10 +34,12 @@ function M.reset_explorer()
TreeExplorer = nil
end

---@return string
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be string|nil, but many internal functions rely on always receiving a string, so that's something I need to fix.

---@field link_to string

---@alias SymlinkNode SymlinkDirNode|SymlinkFileNode
---@alias Node ParentNode|DirNode|FileNode|SymlinkNode|Explorer
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding Explorer here seems to be the best solution, otherwise we would have many Node/Explorer inconsistencies.

@@ -81,6 +85,8 @@ function M.get_last_group_node(node)
return next_node
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't get why it complains about a missing nil check here... And consequently a possible nil return

function Explorer.new(cwd)
cwd = vim.loop.fs_realpath(cwd or vim.loop.cwd())
cwd = vim.loop.fs_realpath(cwd or vim.fn.getcwd())
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This always returns a string instead of string|nil

@Akmadan23 Akmadan23 changed the title chore: add type annotations to (almost) all functions chore: add type annotations and resolve LSP warnings Nov 28, 2023
@Akmadan23
Copy link
Collaborator Author

Apologies again for rudely pushing to your branch and interrupting your work!

Oh, don't worry, I was just a bit confused by the unexpected output on my side.

@alex-courtis
Copy link
Member

alex-courtis commented Dec 2, 2023

The issues with vim and uv are getting in the way of the real goal here. I apologise for steering us in that direction.

Could be be practical and remove the libraries for now?
We can add temporary definitions for now and deal with vim, uv etc. later.

node.lua

-- TODO add "${3rd}/luv/library" to "workspace.library"
---@class uv.uv_req_t: table
---@class uv.uv_fs_t: uv.uv_req_t

runner.lua

-- TODO add "${3rd}/luv/library" to "workspace.library"
---@class uv.uv_handle_t: table
---@class uv.uv_stream_t: uv.uv_handle_t
---@class uv.uv_pipe_t: uv.uv_stream_t

We could even back out the changes to get around the spurious warnings from vim.cmd etc.

@Akmadan23
Copy link
Collaborator Author

Could be be practical and remove the libraries for now?
We can add temporary definitions for now and deal with vim, uv etc. later.

Sure, no problem.

@Akmadan23
Copy link
Collaborator Author

Now we should have 0 warnings related to our internal type annotations.

We could even back out the changes to get around the spurious warnings from vim.cmd etc.

Yes, makes sense to do this since those changes aren't directly related to the annotations added here. I can stash them and open a new PR with other corrections of that kind...

end
return next_node

---@diagnostic disable-next-line: return-type-mismatch -- it can't be nil
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see the possibility of a nil return given that the node parameter is not nil, or am I wrong?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like luals is getting confused.

We could refactor but this is fine.

We can revisit suppressions once we have types annotations present and correct.

@Akmadan23
Copy link
Collaborator Author

As for #2575, I'd rather update the various --- @ here so that we can merge it later without collateral changes.

@alex-courtis
Copy link
Member

All the warnings are resolved!

What's left to do?

pcall(vim.cmd, "buffer " .. M.get_bufnr())
pcall(function()
vim.cmd("buffer " .. M.get_bufnr())
end)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we revert this one as well? I'm the idiot who put it in but it's no longer necessary.

This function needs a rewrite anyway - we need to listen for failures and handle them.

@Akmadan23
Copy link
Collaborator Author

What's left to do?

  • Doc comments style
  • Revert unrelated changes

Everything should be good to go now.

@Akmadan23 Akmadan23 marked this pull request as ready for review December 5, 2023 10:30
Copy link
Member

@alex-courtis alex-courtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets go!

---@class SymlinkFileNode: FileNode
---@field link_to string

---@alias SymlinkNode SymlinkDirNode|SymlinkFileNode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do like this inheritence approach; it removes the need for annoying/unnecessary casts.

@@ -9,7 +9,7 @@ local M = {
}

--- Delete nodes; each removal will be optionally notified
--- @param nodes table
---@param nodes Node[]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch

--- @vararg any arguments for string.format
---@param typ string as per log.types config
---@param fmt string for string.format
---@param ... any arguments for string.format
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.

@alex-courtis alex-courtis merged commit 13f967f into master Dec 9, 2023
@alex-courtis alex-courtis deleted the type-annotations branch December 9, 2023 00:34
@alex-courtis
Copy link
Member

Just incredible work @Akmadan23
The devspeed improvements will be immediately gained and the safety is a massive win.

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

Successfully merging this pull request may close these issues.

3 participants