Skip to content

Commit

Permalink
feat(examples): Add an example using the Julia type system.
Browse files Browse the repository at this point in the history
Building over #32, this provides an example implementation for a tree
based on the Julia type system.
  • Loading branch information
Klafyvel committed Nov 19, 2024
1 parent af3fabd commit 784c305
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 2 deletions.
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)
38 changes: 38 additions & 0 deletions test/examples/juliatypes.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
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)
return S === T ? (T,) : (T, supertypes(S)...)
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(T .<: predfs[i+1:end])
end

postdfs = nodevalue.(collect(PostOrderDFS(t)))
for (i,T) in enumerate(postdfs)
@test !any(T .<: postdfs[begin: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

0 comments on commit 784c305

Please sign in to comment.