From aa8ee40a9ea1a93e58114fffd2e2b8c3dd51e04a Mon Sep 17 00:00:00 2001 From: jake bolewski <jakebolewski@gmail.com> Date: Wed, 25 Feb 2015 23:01:17 -0500 Subject: [PATCH] some more fieldname refactoring --- base/deepcopy.jl | 7 ++++--- base/inference.jl | 4 ++-- base/reflection.jl | 17 ++++++++++++++--- base/serialize.jl | 11 ++++++----- base/show.jl | 13 +++++++------ 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/base/deepcopy.jl b/base/deepcopy.jl index 4677cdebc729e5..ef6b4c9a034c07 100644 --- a/base/deepcopy.jl +++ b/base/deepcopy.jl @@ -27,17 +27,18 @@ function deepcopy_internal(x, stackdict::ObjectIdDict) end function _deepcopy_t(x, T::DataType, stackdict::ObjectIdDict) - isbits(T) | isempty(T.names) && return x + nf = nfields(T) + (isbits(T) || nf == 0) && return x if T.mutable y = ccall(:jl_new_struct_uninit, Any, (Any,), T) stackdict[x] = y - for i in 1:length(T.names) + for i in 1:nf if isdefined(x,i) y.(i) = deepcopy_internal(x.(i), stackdict) end end else - fields = Any[deepcopy_internal(x.(i), stackdict) for i in 1:length(T.names)] + fields = Any[deepcopy_internal(x.(i), stackdict) for i in 1:nf] y = ccall(:jl_new_structv, Any, (Any, Ptr{Void}, UInt32), T, pointer(fields), length(fields)) end diff --git a/base/inference.jl b/base/inference.jl index be9337540df011..c0cb447a9daa30 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -343,7 +343,7 @@ const getfield_tfunc = function (A, s0, name) end end end - for i=1:length(s.names) + for i=1:nfields(s) if is(s.names[i],fld) R = s.types[i] if s.parameters === () @@ -360,7 +360,7 @@ const getfield_tfunc = function (A, s0, name) return Bottom end i::Int = A[2] - if i < 1 || i > length(s.names) + if i < 1 || i > nfields(s) return Bottom end return s.types[i] diff --git a/base/reflection.jl b/base/reflection.jl index ab81b66e5abcf3..13ab59623bfef7 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -27,8 +27,8 @@ end fieldnames(m::Module, all::Bool, imported::Bool) = ccall(:jl_module_fieldnames, Array{Symbol,1}, (Any,Int32,Int32), m, all, imported) fieldnames(m::Module, all::Bool) = fieldnames(m, all, false) fieldnames(m::Module) = fieldnames(m, false, false) -fieldnames(t::DataType) = collect(t.names) +fieldnames(t::DataType) = collect(t.names) function fieldnames(v) t = typeof(v) if !isa(t,DataType) @@ -37,6 +37,17 @@ function fieldnames(v) return fieldnames(t) end +fieldname(t::DataType, i::Integer) = t.names[i] + +nfields(t::DataType) = length(t.names) +function nfields(v) + t = typeof(v) + if !isa(DataType) + throw(ArgumentError("cannot call nfields() on a non-composite type")) + end + return nfields(t) +end + isconst(s::Symbol) = ccall(:jl_is_const, Int32, (Ptr{Void}, Any), C_NULL, s) != 0 @@ -48,7 +59,7 @@ object_id(x::ANY) = ccall(:jl_object_id, UInt, (Any,), x) # type predicates isimmutable(x::ANY) = (isa(x,Tuple) || !typeof(x).mutable) -isstructtype(t::DataType) = t.names!=() || (t.size==0 && !t.abstract) +isstructtype(t::DataType) = nfields(t) != 0 || (t.size==0 && !t.abstract) isstructtype(x) = false isbits(t::DataType) = !t.mutable & t.pointerfree & isleaftype(t) isbits(t::Type) = false @@ -59,7 +70,7 @@ typeintersect(a::ANY,b::ANY) = ccall(:jl_type_intersection, Any, (Any,Any), a, b typeseq(a::ANY,b::ANY) = a<:b && b<:a function fieldoffsets(x::DataType) - offsets = Array(Int, length(x.names)) + offsets = Array(Int, nfields(x)) ccall(:jl_field_offsets, Void, (Any, Ptr{Int}), x, offsets) offsets end diff --git a/base/serialize.jl b/base/serialize.jl index d3a12d014067fc..ee1174d0b47ce2 100644 --- a/base/serialize.jl +++ b/base/serialize.jl @@ -315,11 +315,12 @@ function serialize(s, x) return write_as_tag(s, x) end t = typeof(x) + nf = nfields(t) serialize_type(s, t) - if length(t.names)==0 && t.size>0 + if nf == 0 && t.size > 0 write(s, x) else - for i in 1:length(t.names) + for i in 1:nf if isdefined(x, i) serialize(s, getfield(x, i)) else @@ -527,11 +528,11 @@ end # default DataType deserializer function deserialize(s, t::DataType) - if length(t.names)==0 && t.size>0 + nf = nfields(t) + if nf == 0 && t.size > 0 # bits type return read(s, t) end - nf = length(t.names) if nf == 0 return ccall(:jl_new_struct, Any, (Any,Any...), t) elseif isbits(t) @@ -552,7 +553,7 @@ function deserialize(s, t::DataType) end else x = ccall(:jl_new_struct_uninit, Any, (Any,), t) - for i in 1:length(t.names) + for i in 1:nf tag = int32(read(s, UInt8)) if tag==0 || !is(deser_tag[tag], UndefRefTag) ccall(:jl_set_nth_field, Void, (Any, Csize_t, Any), x, i-1, handle_deserialize(s, tag)) diff --git a/base/show.jl b/base/show.jl index 18e8727f6a1e5d..41c5b39cf1e8f5 100644 --- a/base/show.jl +++ b/base/show.jl @@ -6,7 +6,8 @@ function show(io::IO, x::ANY) t = typeof(x)::DataType show(io, t) print(io, '(') - if t.names !== () || t.size==0 + nf = nfields(t) + if nf != 0 || t.size==0 recorded = false oid = object_id(x) shown_set = get(task_local_storage(), :SHOWNSET, nothing) @@ -22,15 +23,15 @@ function show(io::IO, x::ANY) push!(shown_set, oid) recorded = true - n = length(t.names) - for i=1:n - f = t.names[i] + nf = nfields(t) + for i=1:nf + f = fieldname(t, i) if !isdefined(x, f) print(io, undef_ref_str) else show(io, x.(f)) end - if i < n + if i < nf print(io, ',') end end @@ -735,7 +736,7 @@ end function xdump(fn::Function, io::IO, x, n::Int, indent) T = typeof(x) print(io, T, " ") - if isa(T, DataType) && length(T.names) > 0 + if isa(T, DataType) && nfields(T) > 0 println(io) if n > 0 for field in fieldnames(T)