Skip to content

Commit

Permalink
Add @kw_only macro
Browse files Browse the repository at this point in the history
`@kw_only` behaves the same as `@with_kw` but does not declare a default
constructor when no inner constructor is found.
  • Loading branch information
frankier committed Aug 24, 2022
1 parent 029dad2 commit 0c4a321
Showing 1 changed file with 24 additions and 7 deletions.
31 changes: 24 additions & 7 deletions src/Parameters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import Base: @__doc__
import OrderedCollections: OrderedDict
using UnPack: @unpack, @pack!

export @with_kw, @with_kw_noshow, type2dict, reconstruct, @unpack, @pack!, @pack, @consts
export @with_kw, @kw_only, @with_kw_noshow, type2dict, reconstruct, @unpack, @pack!, @pack, @consts

## Parser helpers
#################
Expand Down Expand Up @@ -326,7 +326,7 @@ macro pack_MM(varname)
end
```
"""
function with_kw(typedef, mod::Module, withshow=true)
function with_kw(typedef, mod::Module, withshow=true, allow_default=true)
if typedef.head==:tuple # named-tuple
withshow==false && error("`@with_kw_noshow` not supported for named tuples")
return with_kw_nt(typedef, mod)
Expand Down Expand Up @@ -486,18 +486,27 @@ function with_kw(typedef, mod::Module, withshow=true)
push!(args, k)
push!(kwargs.args, Expr(:kw,k,w))
end
if length(typparas)>0
tps = stripsubtypes(typparas)
innerc = :( $tn{$(tps...)}($kwargs) where {$(tps...)} = $tn{$(tps...)}($(args...)))
if allow_default
if length(typparas)>0
tps = stripsubtypes(typparas)
innerc = :( $tn{$(tps...)}($kwargs) where {$(tps...)} = $tn{$(tps...)}($(args...)))
else
innerc = :($tn($kwargs) = $tn($(args...)) )
end
else
innerc = :($tn($kwargs) = $tn($(args...)) )
if length(typparas)>0
tps = stripsubtypes(typparas)
innerc = :( $tn{$(tps...)}($kwargs) where {$(tps...)} = new{$(tps...)}($(args...)))
else
innerc = :($tn($kwargs) = new($(args...)) )
end
end
push!(typ.args[3].args, innerc)

# Inner positional constructor: only make it if no inner
# constructors are user-defined. If one or several are defined,
# assume that one has the standard positional signature.
if length(inner_constructors)==0
if length(inner_constructors)==0 && allow_default
if length(typparas)>0
tps = stripsubtypes(typparas)
innerc2 = :( $tn{$(tps...)}($(args...)) where {$(tps...)} = new{$(tps...)}($(args...)) )
Expand Down Expand Up @@ -679,6 +688,14 @@ macro with_kw(args...)
""")
end

"""
As `@with_kw` but does not declare a default constructor when no inner
constructor is found.
"""
macro kw_only(typedef)
return esc(with_kw(typedef, __module__, true, false))
end

"""
As `@with_kw` but does not define a `show` method to avoid annoying
redefinition warnings.
Expand Down

0 comments on commit 0c4a321

Please sign in to comment.