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

Commit

Permalink
build based on ae4127f
Browse files Browse the repository at this point in the history
  • Loading branch information
Documenter.jl committed Sep 3, 2023
1 parent 1fd6a53 commit 50cb680
Show file tree
Hide file tree
Showing 31 changed files with 1,780 additions and 2 deletions.
2 changes: 1 addition & 1 deletion stable
1 change: 1 addition & 0 deletions v0.6
180 changes: 180 additions & 0 deletions v0.6.0/advising.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#+title: Data Advising

* Advice

#+begin_src @docs
Advice
#+end_src

* Advisement points

** Parsing and serialisation of data sets and collections

~DataCollection~​s, ~DataSet~​s, and ~AbstractDataTransformer~​s are advised at two
stages during parsing:
1. When calling ~fromspec~ on the ~Dict~ representation, at the start of parsing
2. At the end of the ~fromspec~ function, calling ~identity~ on the object

Serialisation is performed through the ~tospec~ call, which is also advised.

The signatures of the advised function calls are as follows:

#+begin_src julia
fromspec(DataCollection, spec::Dict{String, Any}; path::Union{String, Nothing})::DataCollection
identity(collection::DataCollection)::DataCollection
tospec(collection::DataCollection)::Dict
#+end_src

#+begin_src julia
fromspec(DataSet, collection::DataCollection, name::String, spec::Dict{String, Any})::DataSet
identity(dataset::DataSet)::DataSet
tospec(dataset::DataSet)::Dict
#+end_src

#+begin_src julia
fromspec(ADT::Type{<:AbstractDataTransformer}, dataset::DataSet, spec::Dict{String, Any})::ADT
identity(adt::AbstractDataTransformer)::AbstractDataTransformer
tospec(adt::AbstractDataTransformer)::Dict
#+end_src

** Processing identifiers

Both the parsing of an ~Identifier~ from a string, and the serialisation of an ~Identifier~ to a string are advised. Specifically, the following function calls:
#+begin_src julia
parse(Identifier, spec::AbstractString, advised=true)
string(ident::Identifier)
#+end_src

** The data flow arrows

The reading, writing, and storage of data may all be advised. Specifically,
the following function calls:
#+begin_src julia
load(loader::DataLoader, datahandle, as::Type)
storage(provider::DataStorage, as::Type; write::Bool)
save(writer::DataWriter, datahandle, info)
#+end_src

* Index of advised calls

#+begin_src @eval
using Markdown
content = Any[]

const AdviseRecord = NamedTuple{(:location, :parent, :invocation), Tuple{LineNumberNode, <:Union{Expr, Symbol}, Expr}}
function findadvice!(acc::Vector{AdviseRecord}, expr::Expr; parent=nothing)
if expr.head == :macrocall && first(expr.args) == Symbol("@advise")
!isnothing(parent) || @warn "Macro @$(expr.args[2]) has no parent function"
push!(acc, (; location=expr.args[2], parent, invocation=expr.args[end]))
else
if isnothing(parent) && expr.head == :function
parent = if first(expr.args) isa Expr
first(first(expr.args).args)
else
first(expr.args)
end
elseif isnothing(parent) && expr.head == :(=) &&
first(expr.args) isa Expr && first(expr.args).head == :call
parent = first(first(expr.args).args)
end
findadvice!.(Ref(acc), expr.args; parent)
end
end
findadvice!(acc, ::Any; parent=nothing) = nothing

alladvice = Vector{AdviseRecord}()
for (root, dirs, files) in walkdir("../../src")
for file in files
file == "precompile.jl" && continue
@info "Analysing $file for advise"
path = joinpath(root, file)
expr = Meta.parseall(read(path, String); filename=path)
findadvice!(alladvice, expr)
end
end

AdvItem = NamedTuple{(:line, :parent, :invocation), Tuple{Int, Union{Expr, Symbol}, Expr}}
advbyfunc = Dict{Symbol, Dict{Symbol, Vector{AdvItem}}}()
atypes = first.(getfield.(getfield.(alladvice, :invocation), :args)) |> unique
afiles = getfield.(getfield.(alladvice, :location), :file) |> unique

for atype in atypes
advs = filter(a -> first(a.invocation.args) == atype, alladvice)
advbyfunc[atype] = Dict{Symbol, Vector{AdvItem}}()
for (; location, parent, invocation) in advs
if !haskey(advbyfunc[atype], location.file)
advbyfunc[atype][location.file] = Vector{AdvItem}()
end
push!(advbyfunc[atype][location.file], (; line=location.line, parent, invocation))
end
end

push!(content, Markdown.Paragraph([
"There are ", Markdown.Bold(string(length(alladvice))),
" advised function calls, across ",
Markdown.Bold(string(length(unique(getfield.(getfield.(alladvice, :location), :file))))),
" files, covering ", Markdown.Bold(string(length(advbyfunc))),
" functions (automatically detected)."]))

push!(content, Markdown.Header{3}(["Arranged by function"]))

for fname in sort(keys(advbyfunc) |> collect)
instances = advbyfunc[fname]
nadv = sum(length, values(instances))
push!(content, Markdown.Header{4}([
Markdown.Code(String(fname)),
if nadv == 1
" (1 instance)"
else
" ($nadv instances)"
end]))
list = Markdown.List(Any[], -1, false)
for file in sort(keys(instances) |> collect)
details = instances[file]
sublist = Markdown.List(Any[], -1, false)
for (; line, parent, invocation) in details
push!(sublist.items, Markdown.Paragraph(
["On line ", string(line), " ",
Markdown.Code(string(invocation)),
" is advised within a ",
Markdown.Code(string(parent)), " method."]))
end
push!(list.items, Any[
Markdown.Paragraph([Markdown.Italic(last(splitpath(String(file))))]),
sublist])
end
push!(content, list)
end

push!(content, Markdown.Header{3}(["Arranged by file"]))

advbyfile = Dict{Symbol, Vector{AdvItem}}()
for (; location, parent, invocation) in alladvice
if !haskey(advbyfile, location.file)
advbyfile[location.file] = Vector{AdvItem}()
end
push!(advbyfile[location.file], (; line=location.line, parent, invocation))
end

for file in sort(afiles)
instances = advbyfile[file]
push!(content, Markdown.Header{5}([
Markdown.Code(last(splitpath(String(file)))),
if length(instances) == 1
" (1 instance)"
else
" ($(length(instances)) instances)"
end]))
list = Markdown.List(Any[], -1, false)
for (; line, parent, invocation) in instances
push!(list.items, [Markdown.Paragraph(
["On line ", string(line), " ",
Markdown.Code(string(invocation)),
" is advised within a ",
Markdown.Code(string(parent)), " method."])])
end
push!(content, list)
end

Markdown.MD(content)
#+end_src
40 changes: 40 additions & 0 deletions v0.6.0/advising/index.html

Large diffs are not rendered by default.

Loading

0 comments on commit 50cb680

Please sign in to comment.