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

feat(examples): Add an example using the Julia type system. #148

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ version = "0.4.5"

[compat]
Aqua = "0.8"
InteractiveUtils = "1"
Test = "1"
julia = "1"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Aqua", "Test"]
test = ["Aqua", "Test", "InteractiveUtils"]
1 change: 1 addition & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,4 @@ repr_node
- [`OneTree`](https://github.com/JuliaCollections/AbstractTrees.jl/blob/master/test/examples/onetree.jl)
- [`FSNode`](https://github.com/JuliaCollections/AbstractTrees.jl/blob/master/test/examples/fstree.jl)
- [`BinaryNode`](https://github.com/JuliaCollections/AbstractTrees.jl/blob/master/test/examples/binarytree.jl)
- [`TypeTree`](https://github.com/JuliaCollections/AbstractTrees.jl/blob/master/test/examples/juliatypes.jl)
42 changes: 42 additions & 0 deletions test/examples/juliatypes.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using AbstractTrees

@static if Base.VERSION ≥ v"1.5"
using InteractiveUtils: subtypes, supertype, supertypes
else
using InteractiveUtils: subtypes, supertype
function supertypes(T::Type)
S = supertype(T)
if S === T
(T,)
else
(T, supertypes(S)...)
end
end
end

"""
TypeTree

The first thing you might think of is using Type{T} as a node directly. However,
this will create many difficulties with components of AbstractTrees.jl that rely
on the type system (in particular `childrentype`). A simple workaround is to
use a wrapper type.
"""
struct TypeTree
t::Type
end
function AbstractTrees.children(t::TypeTree)
t.t === Function ? Vector{TypeTree}() : map(x->TypeTree(x), filter(x -> x !== Any,subtypes(t.t)))
end
AbstractTrees.printnode(io::IO,t::TypeTree) = print(io,t.t)
AbstractTrees.nodevalue(t::TypeTree) = t.t
AbstractTrees.parent(t::TypeTree) = TypeTree(supertype(t.t))
AbstractTrees.ParentLinks(::Type{TypeTree}) = StoredParents()

module JuliaTypesExamples
abstract type AbstractSuperType end
struct DirectDescendant <: AbstractSuperType end
abstract type AbstractFooBar <: AbstractSuperType end
struct Foo <: AbstractFooBar end
struct Bar <: AbstractFooBar end
end
2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ if Base.VERSION >= v"1.6"
@testset "Printing" begin include("printing.jl") end
end

Aqua.test_all(AbstractTrees)
Aqua.test_all(AbstractTrees)
28 changes: 28 additions & 0 deletions test/trees.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,31 @@ include(joinpath(@__DIR__, "examples", "binarytree.jl"))
@test nodevalue.(sbfs) == [0, 1, 2, 3]
end

include(joinpath(@__DIR__, "examples", "juliatypes.jl"))

@testset "TypeTree" begin
t = TypeTree(JuliaTypesExamples.AbstractSuperType)

ls = collect(Leaves(t))
@test issetequal(nodevalue.(ls), [JuliaTypesExamples.DirectDescendant, JuliaTypesExamples.Foo, JuliaTypesExamples.Bar])

predfs = nodevalue.(collect(PreOrderDFS(t)))
for (i,T) in enumerate(predfs)
@test !any(map(x->T <: x, predfs[i+1:end]))
end

postdfs = nodevalue.(collect(PostOrderDFS(t)))
for (i,T) in enumerate(postdfs)
@test !any(map(x->T <: x, postdfs[1:i-1]))
end

sbfs = nodevalue.(collect(StatelessBFS(t)))
for (i,T) in enumerate(sbfs)
parents = collect(supertypes(T)[2:end])
for j in (i+1):length(sbfs)
later_parents = collect(supertypes(sbfs[j])[2:end])
@test (parents ∩ later_parents) == parents
end
end
end

Loading