Dev Build Status Coverage PkgEval Aqua

CodeSearch.jl is a package for semantically searching Julia code. Unlike plain string search and regex search, CodeSearch performs search operations after parsing. Thus the search patterns j"a + b" and j"a+b" are equivalent, and both match the code a +b.

julia> using CodeSearch

julia> j"a + b" == j"a+b"

julia> findfirst(j"a+b", "sqrt(a +b)/(a+ b)")

The other key feature in this package is wildcard matching. You can use the character * to match any expression. For example, the pattern j"a + *" matches both a + b and a + (b + c) .

julia> Expr.(eachmatch(j"a + *", "a + (a + b), a + sqrt(2)"))
3-element Vector{Expr}:
 :(a + (a + b))
 :(a + b)
 :(a + sqrt(2))

Here we can see that j"a + *" matches multiple places, even some that nest within eachother!

Finally, it is possible to extract the "captured values" that match the wildcards.

julia> m = match(j"a + *", "a + (a + b), a + sqrt(2)")
CodeSearch.Match((call-i a + (call-i a + b)), captures=[(call-i a + b)])

julia> m.captures
1-element Vector{JuliaSyntax.SyntaxNode}:
 (call-i a + b)

julia> Expr(only(m.captures))
:(a + b)

How to use this package

  1. Create Patterns with the @j_str macro or the CodeSearch.pattern function.
  2. Search an AbstractString or a JuliaSyntax.SyntaxNode for whether and where that pattern occurs with generic functions like occursin, findfirst, findlast, or findall OR extract the actual Matches with generic functions like eachmatch and match.
  3. If you extracted an actual match, access relevant information using the public syntax_node and captures fields, convert to a SyntaxNode, Expr, or AbstractString via constructors, index into the captures directly with getindex, or extract the indices in the original string that match the capture with indices.