FWIW, this kind of functionality is often easier to implement than it looks. With MacroTools:
using MacroTools: prewalk
using MacroTools
# Your example:
expr = quote
function readfile(filename::String)
a = Dict{String,Int}()
buf = ""
open(filename,"r") do ios
while(!eof(ios))
bud = strip(readline(ios))
items = split(buf,"")
a[items[1]] = length(items)
end
end
return a
end
end
# Gather all local variables
vars = []
prewalk(expr) do x
@match x begin
(lhs_Symbol = b_) => push!(vars, lhs)
for var_Symbol in _ __ end => push!(vars, var)
((args__,) -> _) => push!(vars, [splitarg(a)[1] for a in args]...)
end
x
end
vars
returns [:a, :buf, :ios, :bud, :items]
. It’s by no means a complete solution, but I don’t think you’d need that many more lines to find all local variables in every function in a file. Then if you gather all variable uses with a similar strategy, you can detect that :bud
is never used, and emit a warning…