Skip to content
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

grabbag of subtyping punchlist items #20407

Merged
merged 13 commits into from
Feb 11, 2017
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
simplify process of printing UnionAll type-variables
Since UnionAll bounds are encountered recursively,
it's easiest to represent this the same way in the IOContext.

Also avoid the performance / allocation overhead of using
`IOContext(io)` as a no-op convert (not a no-op since keyword support was added)
  • Loading branch information
vtjnash committed Feb 7, 2017
commit 893a65bddea0bd89c3df2eb0cf8727b1f967738d
8 changes: 6 additions & 2 deletions base/methodshow.jl
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ end

function arg_decl_parts(m::Method)
tv = m.tvars
if !isa(tv,SimpleVector)
if !isa(tv, SimpleVector)
tv = Any[tv]
else
tv = Any[tv...]
@@ -59,7 +59,11 @@ function arg_decl_parts(m::Method)
if src !== nothing && src.slotnames !== nothing
argnames = src.slotnames[1:m.nargs]
sig = unwrap_unionall(m.sig)
decls = Any[argtype_decl(:tvar_env => tv, argnames[i], sig, i, m.nargs, m.isva)
show_env = ImmutableDict{Symbol, Any}()
for t in tv
show_env = ImmutableDict(show_env, :unionall_env => t)
end
decls = Any[argtype_decl(show_env, argnames[i], sig, i, m.nargs, m.isva)
for i = 1:m.nargs]
else
decls = Any[("", "") for i = 1:length(unwrap_unionall(m.sig).parameters)]
2 changes: 1 addition & 1 deletion base/multimedia.jl
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ mimewritable{mime}(::MIME{mime}, x) =
show(io::IO, m::AbstractString, x) = show(io, MIME(m), x)
mimewritable(m::AbstractString, x) = mimewritable(MIME(m), x)

verbose_show(io, m, x) = show(IOContext(io,limit=false), m, x)
verbose_show(io, m, x) = show(IOContext(io, :limit => false), m, x)

"""
reprmime(mime, x)
2 changes: 1 addition & 1 deletion base/range.jl
Original file line number Diff line number Diff line change
@@ -254,7 +254,7 @@ function print_range(io::IO, r::Range,
limit = get(io, :limit, false)
sz = displaysize(io)
if !haskey(io, :compact)
io = IOContext(io, compact=true)
io = IOContext(io, :compact => true)
end
screenheight, screenwidth = sz[1] - 4, sz[2]
screenwidth -= length(pre) + length(post)
2 changes: 1 addition & 1 deletion base/replutil.jl
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ function show{K,V}(io::IO, ::MIME"text/plain", t::Associative{K,V})
recur_io = IOContext(io, :SHOWN_SET => t)
limit::Bool = get(io, :limit, false)
if !haskey(io, :compact)
recur_io = IOContext(recur_io, compact=true)
recur_io = IOContext(recur_io, :compact => true)
end

print(io, summary(t))
69 changes: 28 additions & 41 deletions base/show.jl
Original file line number Diff line number Diff line change
@@ -24,21 +24,24 @@ end

The same as `IOContext(io::IO, KV::Pair)`, but accepting properties as keyword arguments.
"""
IOContext(io::IO; kws...) = IOContext(IOContext(io, ImmutableDict{Symbol,Any}()); kws...)
IOContext(io::IO; kws...) = IOContext(convert(IOContext, io); kws...)
function IOContext(io::IOContext; kws...)
for (k, v) in kws
io = IOContext(io, k, v)
end
io
return io
end

convert(::Type{IOContext}, io::IOContext) = io
convert(::Type{IOContext}, io::IO) = IOContext(io, ImmutableDict{Symbol, Any}())

IOContext(io::IOContext, dict::ImmutableDict) = typeof(io)(io.io, dict)
IOContext(io::IO, dict::ImmutableDict) = IOContext{typeof(io)}(io, dict)

IOContext(io::IOContext, key, value) = IOContext(io.io, ImmutableDict{Symbol, Any}(io.dict, key, value))
IOContext(io::IO, key, value) = IOContext(io, ImmutableDict{Symbol, Any}(key, value))
IOContext(io::IOContext, key, value) = IOContext(io, ImmutableDict{Symbol, Any}(io.dict, key, value))

IOContext(io::IO, context::IO) = IOContext(io)
IOContext(io::IO, context::IO) = convert(IOContext, io)

"""
IOContext(io::IO, context::IOContext)
@@ -183,32 +186,14 @@ function show(io::IO, x::UnionAll)
if print_without_params(x)
return show(io, unwrap_unionall(x).name)
end
tvar_env = get(io, :tvar_env, false)
if tvar_env !== false && isa(tvar_env, AbstractVector)
tvar_env = Any[tvar_env..., x.var]
else
tvar_env = Any[x.var]
end
show(IOContext(io, tvar_env = tvar_env), x.body)
show(IOContext(io, :unionall_env => x.var), x.body)
print(io, " where ")
show(io, x.var)
end

function show_type_parameter(io::IO, p::ANY, has_tvar_env::Bool)
if has_tvar_env
show(io, p)
else
show(IOContext(io, :tvar_env, true), p)
end
end

show(io::IO, x::DataType) = show_datatype(io, x)

function show_datatype(io::IO, x::DataType)
# tvar_env is a `::Vector{Any}` when we are printing a method signature
# and `true` if we are printing type parameters outside a method signature.
has_tvar_env = get(io, :tvar_env, false) !== false

if (!isempty(x.parameters) || x.name === Tuple.name) && x !== Tuple
n = length(x.parameters)

@@ -223,7 +208,7 @@ function show_datatype(io::IO, x::DataType)
# since this information is still useful.
print(io, '{')
for (i, p) in enumerate(x.parameters)
show_type_parameter(io, p, has_tvar_env)
show(io, p)
i < n && print(io, ',')
end
print(io, '}')
@@ -1063,16 +1048,12 @@ function ismodulecall(ex::Expr)
end

function show(io::IO, tv::TypeVar)
# If `tvar_env` exist and we are in it, the type constraint are
# already printed and we don't need to print it again.
# If we are in the `unionall_env`, the type-variable is bound
# and the type constraints are already printed.
# We don't need to print it again.
# Otherwise, the lower bound should be printed if it is not `Bottom`
# and the upper bound should be printed if it is not `Any`.
tvar_env = isa(io, IOContext) && get(io, :tvar_env, false)
if isa(tvar_env, Vector{Any})
in_env = (tv in tvar_env::Vector{Any})
else
in_env = false
end
in_env = (:unionall_env => tv) in io
function show_bound(io::IO, b::ANY)
parens = isa(b,UnionAll) && !print_without_params(b)
parens && print(io, "(")
@@ -1191,16 +1172,22 @@ function dump(io::IO, x::DataType, n::Int, indent)
if x !== Any
print(io, " <: ", supertype(x))
end
if !(x <: Tuple)
tvar_io = IOContext(io, :tvar_env => Any[x.parameters...])
fields = fieldnames(x)
if n > 0
for idx in 1:length(fields)
println(io)
print(io, indent, " ", fields[idx], "::")
print(tvar_io, fieldtype(x, idx))
if n > 0 && !(x <: Tuple)
tvar_io::IOContext = io
for tparam in x.parameters
# approximately recapture the list of tvar parameterization
# that may be used by the internal fields
if isa(tparam, TypeVar)
tvar_io = IOContext(tvar_io, :unionall_env => tparam)
end
end
fields = fieldnames(x)
fieldtypes = x.types
for idx in 1:length(fields)
println(io)
print(io, indent, " ", fields[idx], "::")
print(tvar_io, fieldtypes[idx])
end
end
nothing
end
@@ -1634,7 +1621,7 @@ function showarray(io::IO, X::AbstractArray, repr::Bool = true; header = true)
return show_vector(io, X, "[", "]")
end
if !haskey(io, :compact)
io = IOContext(io, compact=true)
io = IOContext(io, :compact => true)
end
if !repr && get(io, :limit, false) && eltype(X) === Method
# override usual show method for Vector{Method}: don't abbreviate long lists
4 changes: 2 additions & 2 deletions base/sparse/sparsematrix.jl
Original file line number Diff line number Diff line change
@@ -124,7 +124,8 @@ function Base.show(io::IO, ::MIME"text/plain", S::SparseMatrixCSC)
end
end

function Base.show(io::IO, S::SparseMatrixCSC)
Base.show(io::IO, S::SparseMatrixCSC) = Base.show(convert(IOContext, io), S::SparseMatrixCSC)
function Base.show(io::IOContext, S::SparseMatrixCSC)
if nnz(S) == 0
return show(io, MIME("text/plain"), S)
end
@@ -139,7 +140,6 @@ function Base.show(io::IO, S::SparseMatrixCSC)
pad = ndigits(max(S.m,S.n))
k = 0
sep = "\n "
io = IOContext(io)
if !haskey(io, :compact)
io = IOContext(io, :compact => true)
end
4 changes: 2 additions & 2 deletions base/sparse/sparsevector.jl
Original file line number Diff line number Diff line change
@@ -682,7 +682,8 @@ function show(io::IO, ::MIME"text/plain", x::AbstractSparseVector)
show(io, x)
end

function show(io::IO, x::AbstractSparseVector)
show(io::IO, x::AbstractSparseVector) = show(convert(IOContext, io), x)
function show(io::IOContext, x::AbstractSparseVector)
# TODO: make this a one-line form
n = length(x)
nzind = nonzeroinds(x)
@@ -693,7 +694,6 @@ function show(io::IO, x::AbstractSparseVector)
half_screen_rows = limit ? div(displaysize(io)[1] - 8, 2) : typemax(Int)
pad = ndigits(n)
sep = "\n\t"
io = IOContext(io)
if !haskey(io, :compact)
io = IOContext(io, :compact => true)
end
1 change: 0 additions & 1 deletion doc/src/stdlib/io-network.md
Original file line number Diff line number Diff line change
@@ -51,7 +51,6 @@ Base.readavailable
Base.IOContext
Base.IOContext(::IO, ::Pair)
Base.IOContext(::IO, ::IOContext)
Base.IOContext(::IO)
```

## Text I/O
6 changes: 3 additions & 3 deletions test/dict.jl
Original file line number Diff line number Diff line change
@@ -268,7 +268,7 @@ for d in (Dict("\n" => "\n", "1" => "\n", "\n" => "2"),
for cols in (12, 40, 80), rows in (2, 10, 24)
# Ensure output is limited as requested
s = IOBuffer()
io = Base.IOContext(s, limit=true, displaysize=(rows, cols))
io = Base.IOContext(Base.IOContext(s, :limit => true), :displaysize => (rows, cols))
Base.show(io, MIME("text/plain"), d)
out = split(String(take!(s)),'\n')
for line in out[2:end]
@@ -278,7 +278,7 @@ for d in (Dict("\n" => "\n", "1" => "\n", "\n" => "2"),

for f in (keys, values)
s = IOBuffer()
io = Base.IOContext(s, limit=true, displaysize=(rows, cols))
io = Base.IOContext(Base.IOContext(s, :limit => true), :displaysize => (rows, cols))
Base.show(io, MIME("text/plain"), f(d))
out = split(String(take!(s)),'\n')
for line in out[2:end]
@@ -311,7 +311,7 @@ end
type Alpha end
Base.show(io::IO, ::Alpha) = print(io,"α")
let sbuff = IOBuffer(),
io = Base.IOContext(sbuff, limit=true, displaysize=(10, 20))
io = Base.IOContext(Base.IOContext(sbuff, :limit => true), :displaysize => (10, 20))

Base.show(io, MIME("text/plain"), Dict(Alpha()=>1))
@test !contains(String(sbuff), "…")
6 changes: 3 additions & 3 deletions test/nullable.jl
Original file line number Diff line number Diff line change
@@ -103,13 +103,13 @@ for (i, T) in enumerate(types)
@test String(take!(io1)) == @sprintf("Nullable{%s}(%s)", T, String(take!(io2)))

a1 = [x2]
show(IOContext(io1, compact=false), a1)
show(IOContext(io2, compact=false), x2)
show(IOContext(io1, :compact => false), a1)
show(IOContext(io2, :compact => false), x2)
@test String(take!(io1)) ==
@sprintf("Nullable{%s}[%s]", string(T), String(take!(io2)))

show(io1, a1)
show(IOContext(io2, compact=true), x2)
show(IOContext(io2, :compact => true), x2)
@test String(take!(io1)) ==
@sprintf("Nullable{%s}[%s]", string(T), String(take!(io2)))
end
6 changes: 3 additions & 3 deletions test/offsetarray.jl
Original file line number Diff line number Diff line change
@@ -139,7 +139,7 @@ smry = summary(v)
@test contains(smry, "OffsetArray{Float64,1")
@test contains(smry, "with indices -1:1")
function cmp_showf(printfunc, io, A)
ioc = IOContext(io, limit=true, compact=true)
ioc = IOContext(IOContext(io, :limit => true), :compact => true)
printfunc(ioc, A)
str1 = String(take!(io))
printfunc(ioc, parent(A))
@@ -162,9 +162,9 @@ targets2 = ["(1.0, 1.0)",
"([1.0], [1.0])"]
for n = 0:4
a = OffsetArray(ones(Float64,ntuple(d->1,n)), ntuple(identity,n))
show(IOContext(io, limit=true), MIME("text/plain"), a)
show(IOContext(io, :limit => true), MIME("text/plain"), a)
@test String(take!(io)) == targets1[n+1]
show(IOContext(io, limit=true), MIME("text/plain"), (a,a))
show(IOContext(io, :limit => true), MIME("text/plain"), (a,a))
@test String(take!(io)) == targets2[n+1]
end
P = OffsetArray(rand(8,8), (1,1))
2 changes: 1 addition & 1 deletion test/ranges.jl
Original file line number Diff line number Diff line change
@@ -595,7 +595,7 @@ end

# stringmime/show should display the range or linspace nicely
# to test print_range in range.jl
replstrmime(x) = sprint((io,x) -> show(IOContext(io, limit=true), MIME("text/plain"), x), x)
replstrmime(x) = sprint((io,x) -> show(IOContext(io, :limit => true), MIME("text/plain"), x), x)
@test replstrmime(1:4) == "1:4"
@test stringmime("text/plain", 1:4) == "1:4"
@test stringmime("text/plain", linspace(1,5,7)) == "1.0:0.6666666666666666:5.0"
6 changes: 3 additions & 3 deletions test/show.jl
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ const curmod = current_module()
const curmod_name = fullname(curmod)
const curmod_prefix = "$(["$m." for m in curmod_name]...)"

replstr(x) = sprint((io,x) -> show(IOContext(io, limit=true), MIME("text/plain"), x), x)
replstr(x) = sprint((io,x) -> show(IOContext(io, :limit => true), MIME("text/plain"), x), x)

@test replstr(Array{Any}(2)) == "2-element Array{Any,1}:\n #undef\n #undef"
@test replstr(Array{Any}(2,2)) == "2×2 Array{Any,2}:\n #undef #undef\n #undef #undef"
@@ -533,14 +533,14 @@ end

# PR #16651
@test !contains(repr(ones(10,10)), "\u2026")
@test contains(sprint((io,x)->show(IOContext(io,:limit=>true), x), ones(30,30)), "\u2026")
@test contains(sprint((io, x) -> show(IOContext(io, :limit => true), x), ones(30, 30)), "\u2026")

# showcompact() also sets :multiline=>false (#16817)
let io = IOBuffer()
x = [1, 2]
showcompact(io, x)
@test String(take!(io)) == "[1, 2]"
showcompact(IOContext(io, :compact=>true), x)
showcompact(IOContext(io, :compact => true), x)
@test String(take!(io)) == "[1, 2]"
end