Skip to content
This repository has been archived by the owner on May 2, 2020. It is now read-only.

Commit

Permalink
Add filtering by exported functor.
Browse files Browse the repository at this point in the history
Also add some documentation for functors and tests for
``FilterBy.Exported``.

Move ``Render.name`` to ``Utilities.name`` since it's now used
in ``Lexicon.Functors.FilterBy`` as well as ``Lexicon.Render``.
  • Loading branch information
MichaelHatherly committed Jun 20, 2015
1 parent fd0b5bf commit e1d138a
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 33 deletions.
51 changes: 48 additions & 3 deletions src/Functors/FilterBy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,24 @@ import ..Functors:
Functor,
applyf

import ...Utilities

# No filtering.

"""
The default filtering does not discard any objects.
"""
immutable Default <: Functor end

applyf(::Default, x) = true


# Only objects from a set of categories.
"""
Filter objects based on their category.
FilterBy.Categories(:function, :method, :macro)
keeps functions, methods, and macros. All other objects are discarded.
"""
immutable Categories <: Functor
categories :: Vector{Symbol}
Categories(cs...) = new(unique(cs))
Expand All @@ -33,11 +43,46 @@ end
applyf(cat::Categories, x) = Cache.getmeta(x.mod, x.obj)[:category] cat.categories


# Passing any appropriate function.
"""
Custom filter based on a user defined anonymous function with one argument.
A ``Custom`` filter may be defined using either ``do``-block syntax
FilterBy.Custom() do x
test_object(x)
end
or
FilterBy.Custom(x -> test_object(x))
``test_object`` is some arbitrary function used for illustrative purposes only.
Return type must be a ``Bool``.
"""
immutable Custom <: Functor
func :: Function
end

applyf(c::Custom, x) = c.func(x)

"""
Filter objects to only include those that have be exported from their modules.
Usage
FilterBy.Exported()
To include only non-exported objects use the ``!`` operator:
!FilterBy.Exported()
"""
immutable Exported <: Functor end

function applyf(::Exported, x)
exports = Cache.getmeta(Cache.getmodule(x.mod))[:exports]
Utilities.name(x.mod, x.obj) exports
end

end
26 changes: 24 additions & 2 deletions src/Functors/GroupBy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,35 @@ import ..Functors:
applyf


# Group by the line number and file.
"""
By default group by the line number and file of each object.
Usage
GroupBy.Default()
"""
immutable Default <: Functor end

applyf(::Default, x) = Cache.getmeta(x.mod, x.obj)[:textsource]


# Passing any appropriate function.
"""
Group by a user-defined anonymous function that returns a key for
each object.
Usage
GroupBy.Custom() do x
# ...
end
Or without using ``do``-block syntax
GroupBy.Custom(x -> generate_key(x))
where ``generate_key`` is an arbitrary function used for illustrative purposes.
"""
immutable Custom <: Functor
func :: Function
end
Expand Down
52 changes: 48 additions & 4 deletions src/Functors/SortBy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,44 @@ import ..Functors:
applyf


# No sorting.
"""
By default we do not sort any objects.
Usage
SortBy.Default()
"""
immutable Default <: Functor end

applyf(::Default, a, b) = false


# Sort by the string representation of an object.
"""
Sort by the ``string`` representation of an object.
Usage
SortBy.StringName()
"""
immutable StringName <: Functor end

applyf(::StringName, a, b) = string(a.obj) < string(b.obj)


# Strict ordering by vector of categories.
"""
Strict ordering by a vector of categories.
*Note:* When an object's category is not listed then an error will be thrown.
Usage
SortBy.CategoryOrder(:type, :global, :bitstype)
will sort types (``abstract``, ``type``, and ``immutable``) first, followed by
globals, and finally ``bitstype`` types.
"""
immutable CategoryOrder <: Functor
order :: Vector{Symbol}
CategoryOrder(cs...) = new(unique(cs))
Expand All @@ -44,7 +69,26 @@ function applyf(c::CategoryOrder, a, b)
end


# Passing any appropriate function.
"""
Any appropriate user-defined anonymous function can be used to sort objects.
The function must take two arguments that are compared to decide if the first is
smaller than the second.
Usage
SortBy.Custom() do a, b
# ...
end
or without ``do``-syntax
SortBy.Custom((a, b) -> sorting_method(a, b))
where ``sorting_method`` is for illustrative purposes only.
The provided function **must** have a ``Bool`` return type.
"""
immutable Custom <: Functor
func :: Function
end
Expand Down
4 changes: 4 additions & 0 deletions src/Render/Render.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ import ..Queries:
Results,
Result

import ..Utilities:

name


import ..Markdown

Expand Down
24 changes: 0 additions & 24 deletions src/Render/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,3 @@

# Hook into Docile's docstring parsing mechanism.
parsedocs(::Format{MarkdownFormatter}, raw, mod, obj) = Markdown.parse(raw)

# Symbolic names. #

name(mod, m::Method) = m.func.code.name

name(mod, m::Module) = module_name(m)

name(mod, t::DataType) = t.name.name

function name(mod, obj::Function)
meta = Cache.getmeta(mod, obj)
if meta[:category] == :macro
symbol(string("@", meta[:signature].args[1]))
else
obj.env.name
end
end

name(mod, q::QualifiedSymbol) = q.sym

function name(mod, obj::Aside)
linenumber, path = Cache.getmeta(mod, obj)[:textsource]
return symbol("aside_$(first(splitext(basename(path))))_L$(linenumber)")
end
34 changes: 34 additions & 0 deletions src/Utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ Utilities

using Compat

import Docile.Collector:

Aside,
QualifiedSymbol

import Docile.Cache:

Cache

# from base/methodshow.jl
function url(linesource::Tuple)
line, file = linesource
Expand All @@ -30,4 +39,29 @@ end

macro s_str(text) Expr(:quote, symbol(text)) end


# Symbolic names. #

name(mod, m::Method) = m.func.code.name

name(mod, m::Module) = module_name(m)

name(mod, t::DataType) = t.name.name

function name(mod, obj::Function)
meta = Cache.getmeta(mod, obj)
if meta[:category] == :macro
symbol(string("@", meta[:signature].args[1]))
else
obj.env.name
end
end

name(mod, q::QualifiedSymbol) = q.sym

function name(mod, obj::Aside)
linenumber, path = Cache.getmeta(mod, obj)[:textsource]
return symbol("aside_$(first(splitext(basename(path))))_L$(linenumber)")
end

end
2 changes: 2 additions & 0 deletions test/Functors/FunctorTestModule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ g_1(x) = x
"..."
g_2(x) = x

export D_1, f_1, g_1

end
14 changes: 14 additions & 0 deletions test/Functors/facts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,20 @@ facts("Functors.") do
for (res, obj) in zip([false, true, false, false, true, false, true], objects)
@fact applyf(f6, obj) => res
end

# Pick only exported objects.
f7 = FilterBy.Exported()

for (res, obj) in zip([true, false, true, true, false, true, false], objects)
@fact applyf(f7, obj) => res
end

# Pick only non-exported objects.
f8 = !FilterBy.Exported()

for (res, obj) in zip([false, true, false, false, true, false, true], objects)
@fact applyf(f8, obj) => res
end
end

context("SortBy.") do
Expand Down

0 comments on commit e1d138a

Please sign in to comment.