StaticLint.jl
StaticLint.jl copied to clipboard
Docs?
It would be nice to have a basic readme.
I'm doing a write up for a talk in a week or so, which I'll then put online
@ZacLN link?
Hi, another request for a basic readme. At the very least, documenting the entry points for standalone use would be very useful.
I'm also looking for such a doc (or at least README.md
).
What functions should be called from Julia
- for linting an entire package
- for linting a file
- for linting a string
Is there a CLI to be able to lint a package or a file "directly" from Bash? (similar to https://github.com/ZacLN/DocumentFormat.jl/issues/34 )
I spent few hours to learn this package internals. I got so far that I copied the test and got the linting working but I couldn't figure out how to print/display anything meaningful.
@davidanthoff @ZacLN Any update on this? Could you give us the code that lints a simple file? Something like the following:
lint_file("test.jl")
I'm bumping this thread since have similar question as @aminya and @scls19fr. Could you share a basic usage example? If I understood the ideas behind this package better I could even help with creating a PR with improved documentation, but I would prefer to start by someone commenting what is the intended usage, rather than figuring it myself from the code.
I think the thing that would be most useful for the docs would be to have a little example script that takes a filepath, loads the files, lints them, and prints all warnings to the screen.
I feel like that would make it clear how all the parts fit together
I added convenient functions that do everything for you in: https://github.com/julia-vscode/StaticLint.jl/pull/220
But there has been zero interest from the developers of this repo for reviewing the PR
But there has been zero interest from the developers of this repo for reviewing the PR
Maybe you should ping some of them in the pull request. Nice work by the way, I was missing those functions when I tried to use this repo.
to be honest i think this PR being open 2 years signals that this project is is not actually meant to have community collaboration.
We generally welcome community contributions, but at the moment the core team is just completely overloaded with other things (kids that don't have school, for example). Hopefully this will get better as things normalize a bit during 2021.
I'm also looking for some documentation.
I got something working by doing the following, trying it out on JSON.jl:
using StaticLint, JSON
server = StaticLint.FileServer()
root, hints = StaticLint.lint_file(pkgdir(JSON, "src", "JSON.jl"), server; gethints=true);
hints[1]
#outputs
( 1:11 begin_array, "Missing reference at offset 689 of .julia\\packages\\JSON\\93Ea8\\src\\JSON.jl")
I seem to be mostly getting missing references to external dependencies of the JSON package.
I see that in the LanguageServer you have a LanguageServerInstance which includes the ability to refer to the depot. In this test_shared_server.jl.
I tried that, but:
julia> server = LanguageServerInstance(IOBuffer(), stdout, dirname(Pkg.Types.Context().env.project_file), first(Base.DEPOT_PATH))
julia> StaticLint.lint_file(pkgdir(JSON, "src", "JSON.jl"), server; gethints=true)
ERROR: type LanguageServerInstance has no field files
I'll have to dive deeper into the source code to figure it out.
https://gist.github.com/pfitzseb/22493b0214276d3b65833232aa94bf11
Okay, I got that working, but I still only get missing references on JSON. I'll try on another package as well.
julia> f.diagnostics
4-element Vector{LanguageServer.Diagnostic}:
LanguageServer.Diagnostic(LanguageServer.Range(LanguageServer.Position(21, 60), LanguageServer.Position(21, 71)), 2, missing, missing, "Julia", "Missing reference: begin_array", missing, missing)
LanguageServer.Diagnostic(LanguageServer.Range(LanguageServer.Position(22, 15), LanguageServer.Position(22, 24)), 2, missing, missing, "Julia", "Missing reference: end_array", missing, missing)
LanguageServer.Diagnostic(LanguageServer.Range(LanguageServer.Position(22, 26), LanguageServer.Position(22, 38)), 2, missing, missing, "Julia", "Missing reference: begin_object", missing, missing)
LanguageServer.Diagnostic(LanguageServer.Range(LanguageServer.Position(22, 40), LanguageServer.Position(22, 50)), 2, missing, missing, "Julia", "Missing reference: end_object", missing, missing)
Is (the right version of) JSON in the manifest?
What would be the right version? The version in my environment manifest matches the source code version if that is what you mean.
I'm now trying out DataFrames.jl, a package that does report some problems in VS Code. I get 36 problems in VS code, but 88 diagnostic errors with your script, all of which are missing references.
Here's what VS Code reports
I ]activate static_lint
environment for this purpose
I did ]dev DataFrames
into my static lint environment
(note: with JSON I tried Pkg.add instead of Pkg.develop and it didn't make a difference)
So my environment is like this now:
(static_lint) pkg> st
Status `C:\Users\matcox\Documents\Julia\static_lint\Project.toml`
[a93c6f00] DataFrames v1.5.0 `C:\Users\matcox\.julia\dev\DataFrames`
[2b0e0bc5] LanguageServer v4.4.0
[b3cc710f] StaticLint v8.1.0
[cf896787] SymbolServer v7.2.1
I then run your example as follows:
using LanguageServer, StaticLint, SymbolServer
using DataFrames
path = pkgdir(DataFrames)
root_file = joinpath(path, "src", "DataFrames.jl")
server = LanguageServerInstance(Pipe(), stdout, path)
_, symbols = SymbolServer.getstore(server.symbol_server, path)
server.global_env.symbols = symbols
server.global_env.extended_methods = SymbolServer.collect_extended_methods(server.global_env.symbols)
server.global_env.project_deps = collect(keys(server.global_env.symbols))
f = StaticLint.loadfile(server, root_file)
StaticLint.semantic_pass(LanguageServer.getroot(f))
StaticLint.check_all(LanguageServer.getcst(f), server.lint_options, LanguageServer.getenv(f, server))
empty!(f.diagnostics)
LanguageServer.mark_errors(f, f.diagnostics);
This outputs 88 diagnostics:
julia> length(f.diagnostics)
88
The first is immediately a missing reference.
julia> f.diagnostics[1]
LanguageServer.Diagnostic(LanguageServer.Range(LanguageServer.Position(2, 6), LanguageServer.Position(2, 16)), 2, missing, missing, "Julia", "Missing reference: Statistics", missing, missing)
Seems all are this "Missing reference" message actually.
julia> filter(d -> !contains(d.message, "Missing reference"), f.diagnostics) |> length
0
Anything you'd like me to check?
My main question is whether joinpath(path, "Manifest.toml")
exists. The language server only works with instantiated environments.
I see. That doesn't exist indeed, because the path right now points to DataFrames source code.
I have changed to the following:
package_path = pkgdir(DataFrames)
root_file = joinpath(package_path, "src", "DataFrames.jl")
# use project path instead
path = dirname(Pkg.Types.Context().env.project_file)
Now there is the Manifest.toml of the static_lint
environment
julia> joinpath(path, "Manifest.toml") |> isfile
true
Suddenly I get some warnings
┌ Warning: libblastrampoline_jll not stored on disc
└ @ SymbolServer C:\Users\matcox\.julia\packages\SymbolServer\LMSFX\src\SymbolServer.jl:247
┌ Warning: LibSSH2_jll not stored on disc
└ @ SymbolServer C:\Users\matcox\.julia\packages\SymbolServer\LMSFX\src\SymbolServer.jl:247
┌ Warning: MbedTLS_jll not stored on disc
└ @ SymbolServer C:\Users\matcox\.julia\packages\SymbolServer\LMSFX\src\SymbolServer.jl:247
But I find zero diagnostic errors...
So my next attempt was to rm DataFrames
from the static_lint
environment, and instead copy-paste the DataFrames/src
code and Project dependencies into my static_lint
environment.
I restarted Julia, activated static_lint
again and ran a Pkg.instantiate()
. Then I used the following path:
path = dirname(Pkg.Types.Context().env.project_file)
root_file = joinpath(path, "src", "DataFrames.jl")
Still zero diagnostics errors.
At least both approaches got rid of the missing references :) But how do I gain a list of those problems I see in my VS Code environment?
Yeah, turns out that script was buggy and only looking at the specified file. Try again with the updated gist.
Thanks, that gets me further indeed.
I get a lot of "UnusedFunctionArgument" and "UnusedBinding" errors. I see these are not reported in the Problems tab in VS Code. However I can see those when hovering over the code in the editor. Like here:
Which I can see now inside my REPL:
julia> docs[3]
Document: file:///c%3A/Users/matcox/Documents/Julia/static_lint/src/abstractdataframe/selection.jl
julia> docs[3].diagnostics[1]
LanguageServer.Diagnostic(LanguageServer.Range(LanguageServer.Position(223, 15), LanguageServer.Position(223, 36)), 4, "UnusedFunctionArgument", missing, "Julia", "An argument is included in a function signature but
not used within its body.", [1], missing)
Is it possible that the position starts counting at 0, so the 223 matches with line 224 in VS Code?
Anyway, I guess this solves it!
Yes, the LS uses zero-based indexing for rows/cols.
Would it be worth to update the docs with this example? Or is this not the desired behavior, because we depend on LanguageServer.jl and we'd preferably setup an independent StaticLint server for this CLI-based diagnostics gathering?