Skip to content

updated repository to Julia v1.0 #4

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

Merged
merged 3 commits into from
Jan 23, 2019
Merged
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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ They are simply intended as demonstrations of `ComputedFieldTypes`.
For simple cases, a default constructor will be added, if none is specified:

```julia
@computed type A{V <: AbstractVector}
@computed struct A{V <: AbstractVector}
a::eltype(V)
end
a = A{Vector{Int}}(3.0)
Expand All @@ -21,13 +21,13 @@ It is also possible to declare your own constructor,
with extra type variables, parameterized, etc.:

```julia
@computed type B{N, M, T}
@computed struct B{N, M, T}
a::NTuple{N + M, T}
B(x::T) = new{N, M, T}(ntuple(i -> x, N + M))
B{S}(x::S) = B{N, M, T}(convert(T, x))
end

@computed type C{T <: Number}
@computed struct C{T <: Number}
a::typeof(one(T) / one(T))
C() = new(0)
function C(x)
Expand Down
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1 +1 @@
julia 0.6-
julia 0.7
33 changes: 19 additions & 14 deletions src/ComputedFieldTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ end
# the bulk of the work to
"
function _computed(typeexpr::Expr)
typeexpr.head === :type || error("expected a type expression")
typeexpr.head === :struct || error("expected a type expression")
curly = make_curly(typeexpr.args[2])
typeexpr.args[2] = curly
tname = curly.args[1]::Symbol
Expand Down Expand Up @@ -54,7 +54,7 @@ function _computed(typeexpr::Expr)
if f.head === :(::) && isa(f.args[1], Symbol)
push!(fieldnames, f.args[1]::Symbol)
f.args[2] = getenv!(f.args[2], curly.args, def)
elseif f.head !== :line
elseif typeof(f) !== :LineNumberNode
push!(ctors, f)
end
end
Expand All @@ -64,7 +64,7 @@ function _computed(typeexpr::Expr)
if isempty(ctors)
# normally, Julia would add 3 default constructors here
# however, two of those are not computable, so we don't add them
push!(fields, Expr(:function, Expr(:call, Expr(:curly, make_Type_expr(tname, decl_tvars), decl_tvars...), fieldnames...),
push!(fields, Expr(:function, Expr(:where, Expr(:call, make_Type_expr(tname, decl_tvars), fieldnames...), decl_tvars...),
Expr(:block, Expr(:return, Expr(:call, make_new_expr(:new, decl_tvars, def), fieldnames...)))))
else
for e in ctors
Expand All @@ -79,7 +79,7 @@ end
"
# given an apply-type expression (`T` or `T{...}`), return `Expr(:curly, T, ...)`
"
make_curly(curly::ANY) = error("expected an apply-type expression")
make_curly(@nospecialize curly) = error("expected an apply-type expression")
function make_curly(curly::Expr)
if curly.head !== :curly || !isa(curly.args[1], Symbol)
make_curly(nothing)
Expand All @@ -94,7 +94,7 @@ end
# replace anything that isn't computable by apply_type
# with a dummy type-variable
"
getenv!(e::ANY, tvars, def) = e
getenv!(@nospecialize(e), tvars, def) = e
function getenv!(e::Expr, tvars, def)
if e.head === :curly || e.head === :where
for i = 1:length(e.args)
Expand Down Expand Up @@ -123,15 +123,15 @@ make_new_expr(tname, decl_tvars, def) = Expr(:curly, tname, decl_tvars..., def..
# compute the leaf `T{def}` expression that is equivalent for the new type declaration
"
function make_fulltype_expr(tname, decl_tvars, def)
return Expr(:function, Expr(:call, Expr(:curly, Core.GlobalRef(ComputedFieldTypes, :fulltype), decl_tvars...),
make_Type_expr(tname, decl_tvars)),
return Expr(:function, Expr(:where, Expr(:call, Core.GlobalRef(ComputedFieldTypes, :fulltype), make_Type_expr(tname, decl_tvars)),
decl_tvars...),
Expr(:block, Expr(:return, make_new_expr(tname, decl_tvars, def))))
end

"
# rewrite the constructors to capture only the intended values
"
rewrite_new!(e::ANY, tname::Symbol, decl_tvars, def) = nothing
rewrite_new!(@nospecialize(e), tname::Symbol, decl_tvars, def) = nothing
function rewrite_new!(e::Expr, tname::Symbol, decl_tvars, def)
if e.head !== :line
for i = 1:length(e.args)
Expand All @@ -151,20 +151,25 @@ function rewrite_new!(e::Expr, tname::Symbol, decl_tvars, def)
end

# rewrite constructor declarations to explicitly only involve the declared type-variables
# this involves rewriting `A` as `(::Type{A{T}}){T}`
# this involves rewriting `A` as `(::Type{A{T...}}) where {T...}`
if e.head === :function || (e.head === :(=) && isa(e.args[1], Expr) && e.args[1].head === :call)
pfname = e.args[1].args
if isa(pfname[1], Expr) && pfname[1].head === :curly
pfname = pfname[1].args
end
if pfname[1] === tname
pfname[1] = make_Type_expr(tname, decl_tvars)
curly = e.args[1].args[1]
if !(isa(curly, Expr) && curly.head === :curly)
curly = Expr(:curly, curly)
e.args[1].args[1] = curly
param = e.args[1].args[1]
if !(isa(param, Expr) && param.head === :curly)
param = Expr(:where, e.args[1])
e.args[1] = param
elseif isa(param, Expr) && param.head === :curly
vars = param.args[2:end]
param = Expr(:where, Expr(:call, e.args[1].args[1].args[1], e.args[1].args[2]))
e.args[1] = param
append!(param.args, vars)
end
append!(curly.args, decl_tvars)
append!(param.args, decl_tvars)
end
end
end
Expand Down