Skip to content

Commit

Permalink
Drop v0.5 support, Compat dependency (#217)
Browse files Browse the repository at this point in the history
* Drop v0.5 support, Compat dependency

* Stop testing on 0.5 in CI
  • Loading branch information
TotalVerb authored Sep 25, 2017
1 parent 8105d33 commit a36ec39
Show file tree
Hide file tree
Showing 14 changed files with 66 additions and 94 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ os:
- osx
- linux
julia:
- 0.5
- 0.6
- nightly
notifications:
Expand Down
3 changes: 1 addition & 2 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
julia 0.5
Compat 0.31.0
julia 0.6
2 changes: 0 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
Expand Down
6 changes: 0 additions & 6 deletions src/Common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@ Internal implementation detail.
"""
module Common

using Compat

# The expression head to use for constructing types.
# TODO: Remove this hack when 0.5 support is dropped.
const STRUCTHEAD = VERSION < v"0.7.0-DEV.1263" ? :type : :struct

include("bytes.jl")
include("errors.jl")

Expand Down
2 changes: 0 additions & 2 deletions src/JSON.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ __precompile__()

module JSON

using Compat

export json # returns a compact (or indented) JSON representation as a string

include("Common.jl")
Expand Down
28 changes: 12 additions & 16 deletions src/Parser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ module Parser # JSON

using ..Common

using Compat

"""
Like `isspace`, but work on bytes and includes only the four whitespace
characters defined by the JSON standard: space, tab, line feed, and carriage
Expand All @@ -16,21 +14,19 @@ Like `isdigit`, but for bytes.
"""
isjsondigit(b::UInt8) = DIGIT_ZERO b DIGIT_NINE

@compat abstract type ParserState end
abstract type ParserState end

eval(Expr(Common.STRUCTHEAD, true, :(MemoryParserState <: ParserState),
quote
mutable struct MemoryParserState <: ParserState
utf8data::Vector{UInt8}
s::Int
end))
end

eval(Expr(Common.STRUCTHEAD, true, :(StreamingParserState{T <: IO} <: ParserState),
quote
mutable struct StreamingParserState{T <: IO} <: ParserState
io::T
cur::UInt8
used::Bool
end))
StreamingParserState{T <: IO}(io::T) = StreamingParserState{T}(io, 0x00, true)
end
StreamingParserState(io::IO) = StreamingParserState(io, 0x00, true)

"""
Return the byte at the current position of the `ParserState`. If there is no
Expand Down Expand Up @@ -367,27 +363,27 @@ function parse_number(ps::ParserState)
end


function unparameterize_type{T}(::Type{T})
function unparameterize_type(T::Type)
candidate = typeintersect(T, Associative{String, Any})
candidate <: Union{} ? T : candidate
end

function parse{T<:Associative}(str::AbstractString; dicttype::Type{T}=Dict{String,Any})
function parse(str::AbstractString; dicttype::Type{<:Associative}=Dict{String,Any})
ps = MemoryParserState(Vector{UInt8}(String(str)), 1)
v = parse_value(ps, unparameterize_type(T))
v = parse_value(ps, unparameterize_type(dicttype))
chomp_space!(ps)
if hasmore(ps)
_error(E_EXPECTED_EOF, ps)
end
v
end

function parse{T<:Associative}(io::IO; dicttype::Type{T}=Dict{String,Any})
function parse(io::IO; dicttype::Type{<:Associative}=Dict{String,Any})
ps = StreamingParserState(io)
parse_value(ps, unparameterize_type(T))
parse_value(ps, unparameterize_type(dicttype))
end

function parsefile{T<:Associative}(filename::AbstractString; dicttype::Type{T}=Dict{String, Any}, use_mmap=true)
function parsefile(filename::AbstractString; dicttype::Type{<:Associative}=Dict{String, Any}, use_mmap=true)
sz = filesize(filename)
open(filename) do io
s = use_mmap ? String(Mmap.mmap(io, Vector{UInt8}, sz)) : read(io, String)
Expand Down
16 changes: 7 additions & 9 deletions src/Serializations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,24 @@ implementations, as they relate to JSON.

module Serializations

using Compat
using ..Common

"""
A `Serialization` defines how objects are lowered to JSON format.
"""
@compat abstract type Serialization end
abstract type Serialization end

@compat abstract type CommonSerialization <: Serialization end
@doc """
"""
The `CommonSerialization` comes with a default set of rules for serializing
Julia types to their JSON equivalents. Additional rules are provided either by
packages explicitly defining `JSON.show_json` for this serialization, or by the
`JSON.lower` method. Most concrete implementations of serializers should subtype
`CommonSerialization`, unless it is desirable to bypass the `lower` system, in
which case `Serialization` should be subtyped.
""" CommonSerialization
"""
abstract type CommonSerialization <: Serialization end

eval(Expr(Common.STRUCTHEAD, false, :(StandardSerialization <: CommonSerialization),
quote end))
@doc """
"""
The `StandardSerialization` defines a common, standard JSON serialization format
that is optimized to:
Expand All @@ -37,6 +34,7 @@ that is optimized to:
All serializations defined for `CommonSerialization` are inherited by
`StandardSerialization`. It is therefore generally advised to add new
serialization behaviour to `CommonSerialization`.
""" StandardSerialization
"""
struct StandardSerialization <: CommonSerialization end

end
68 changes: 32 additions & 36 deletions src/Writer.jl
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
module Writer

using Compat
using ..Common
using ..Serializations: Serialization, StandardSerialization,
CommonSerialization

eval(Expr(Common.STRUCTHEAD, false, :(CompositeTypeWrapper{T}),
quote
wrapped::T
fns::Vector{Symbol}
end))
@doc """
"""
Internal JSON.jl implementation detail; do not depend on this type.
A JSON primitive that wraps around any composite type to enable `Dict`-like
serialization.
""" CompositeTypeWrapper
"""
struct CompositeTypeWrapper{T}
wrapped::T
fns::Vector{Symbol}
end

CompositeTypeWrapper(x) = CompositeTypeWrapper(x, fieldnames(typeof(x)))

"""
Expand Down Expand Up @@ -60,7 +59,7 @@ lower(x::Base.AbstractSet) = collect(x)
"""
Abstract supertype of all JSON and JSON-like structural writer contexts.
"""
@compat abstract type StructuralContext <: IO end
abstract type StructuralContext <: IO end

"""
Internal implementation detail.
Expand All @@ -74,46 +73,43 @@ be written to a JSON context in the usual way, but often higher-level operations
such as `begin_array` or `begin_object` are preferred to directly writing bytes
to the stream.
"""
@compat abstract type JSONContext <: StructuralContext end
abstract type JSONContext <: StructuralContext end

eval(Expr(Common.STRUCTHEAD, true, :(PrettyContext{T<:IO} <: JSONContext),
quote
io::T
step::Int # number of spaces to step
state::Int # number of steps at present
first::Bool # whether an object/array was just started
end))
@doc """
"""
Internal implementation detail.
Keeps track of the current location in the array or object, which winds and
unwinds during serialization.
""" PrettyContext
"""
mutable struct PrettyContext{T<:IO} <: JSONContext
io::T
step::Int # number of spaces to step
state::Int # number of steps at present
first::Bool # whether an object/array was just started
end
PrettyContext(io::IO, step) = PrettyContext(io, step, 0, false)

eval(Expr(Common.STRUCTHEAD, true, :(CompactContext{T<:IO} <: JSONContext),
quote
io::T
first::Bool
end))
@doc """
"""
Internal implementation detail.
For compact printing, which in JSON is fully recursive.
""" CompactContext
"""
mutable struct CompactContext{T<:IO} <: JSONContext
io::T
first::Bool
end
CompactContext(io::IO) = CompactContext(io, false)

eval(Expr(Common.STRUCTHEAD, false, :(StringContext{T<:IO} <: IO),
quote
io::T
end))
@doc """
"""
Internal implementation detail.
Implements an IO context safe for printing into JSON strings.
""" StringContext
"""
struct StringContext{T<:IO} <: IO
io::T
end

# These make defining additional methods on `show_json` easier.
# These aliases make defining additional methods on `show_json` easier.
const CS = CommonSerialization
const SC = StructuralContext

Expand All @@ -123,7 +119,7 @@ Base.write(io::StringContext, byte::UInt8) =
write(io.io, ESCAPED_ARRAY[byte + 0x01])
#= turn on if there's a performance benefit
write(io::StringContext, char::Char) =
char <= '\x7f' ? write(io, ESCAPED_ARRAY[@compat UInt8(c) + 0x01]) :
char <= '\x7f' ? write(io, ESCAPED_ARRAY[UInt8(c) + 0x01]) :
Base.print(io, c)
=#

Expand Down Expand Up @@ -312,7 +308,7 @@ end
Serialize a multidimensional array to JSON in column-major format. That is,
`json([1 2 3; 4 5 6]) == "[[1,4],[2,5],[3,6]]"`.
"""
function show_json{T,n}(io::SC, s::CS, A::AbstractArray{T,n})
function show_json(io::SC, s::CS, A::AbstractArray{<:Any,n}) where n
begin_array(io)
newdims = ntuple(_ -> :, n - 1)
for j in indices(A, n)
Expand All @@ -322,7 +318,7 @@ function show_json{T,n}(io::SC, s::CS, A::AbstractArray{T,n})
end

# special case for 0-dimensional arrays
show_json{T}(io::SC, s::CS, A::AbstractArray{T,0}) = show_json(io, s, A[])
show_json(io::SC, s::CS, A::AbstractArray{<:Any,0}) = show_json(io, s, A[])

show_json(io::SC, s::CS, a) = show_json(io, s, lower(a))

Expand Down
2 changes: 1 addition & 1 deletion src/bytes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ for c in 0x00:0xFF
[c] # UTF-8 character copied verbatim
elseif haskey(REVERSE_ESCAPES, c)
[BACKSLASH, REVERSE_ESCAPES[c]]
elseif iscntrl(@compat Char(c)) || !isprint(@compat Char(c))
elseif iscntrl(Char(c)) || !isprint(Char(c))
UInt8[BACKSLASH, LATIN_U, hex(c, 4)...]
else
[c]
Expand Down
4 changes: 1 addition & 3 deletions src/specialized.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# Specialized functions for increased performance when JSON is in-memory
using Compat: StringVector

function parse_string(ps::MemoryParserState)
# "Dry Run": find length of string so we can allocate the right amount of
# memory from the start. Does not do full error checking.
fastpath, len = predict_string(ps)

# Now read the string itself
b = StringVector(len)
b = Base.StringVector(len)

# Fast path occurs when the string has no escaped characters. This is quite
# often the case in real-world data, especially when keys are short strings.
Expand Down
1 change: 1 addition & 0 deletions test/REQUIRE
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
DataStructures
FixedPointNumbers
OffsetArrays
Compat 0.31.0
7 changes: 3 additions & 4 deletions test/lowering.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ module TestLowering

using JSON
using Base.Test
using Compat
using FixedPointNumbers: Fixed

if isdefined(Base, :Dates)
Expand All @@ -12,13 +11,13 @@ end
@test JSON.json(:x) == "\"x\""
@test_throws ArgumentError JSON.json(Base)

eval(Expr(JSON.Common.STRUCTHEAD, false, :(Type151{T}), quote
struct Type151{T}
x::T
end))
end

@test JSON.parse(JSON.json(Type151)) == string(Type151)

JSON.lower{T}(v::Type151{T}) = Dict(:type => T, :value => v.x)
JSON.lower(v::Type151{T}) where {T} = Dict(:type => T, :value => v.x)
@test JSON.parse(JSON.json(Type151(1.0))) == Dict(
"type" => "Float64",
"value" => 1.0)
Expand Down
5 changes: 2 additions & 3 deletions test/regression/issue109.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
eval(Expr(JSON.Common.STRUCTHEAD, true, :t109,
quote
mutable struct t109
i::Int
end))
end

let iob = IOBuffer()
JSON.print(iob, t109(1))
Expand Down
15 changes: 6 additions & 9 deletions test/serializer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ module TestSerializer

using JSON
using Base.Test
using Compat

# to define a new serialization behaviour, import these first
import JSON.Serializations: CommonSerialization, StandardSerialization
Expand All @@ -20,9 +19,8 @@ function sprint_kwarg(f, args...; kwargs...)
end

# issue #168: Print NaN and Inf as Julia would
eval(Expr(JSON.Common.STRUCTHEAD, false, :(NaNSerialization <: CS), quote end))
JSON.show_json(io::SC, ::NaNSerialization, f::AbstractFloat) =
Base.print(io, f)
struct NaNSerialization <: CS end
JSON.show_json(io::SC, ::NaNSerialization, f::AbstractFloat) = Base.print(io, f)

@test sprint(JSON.show_json, NaNSerialization(), [NaN, Inf, -Inf, 0.0]) ==
"[NaN,Inf,-Inf,0.0]"
Expand All @@ -42,11 +40,10 @@ JSON.show_json(io::SC, ::NaNSerialization, f::AbstractFloat) =
"""

# issue #170: Print JavaScript functions directly
eval(Expr(JSON.Common.STRUCTHEAD, false, :(JSSerialization <: CS), quote end))
eval(Expr(JSON.Common.STRUCTHEAD, false, :JSFunction,
quote
struct JSSerialization <: CS end
struct JSFunction
data::String
end))
end

function JSON.show_json(io::SC, ::JSSerialization, f::JSFunction)
first = true
Expand Down Expand Up @@ -74,7 +71,7 @@ end
"""

# test serializing a type without any fields
eval(Expr(JSON.Common.STRUCTHEAD, false, :SingletonType, quote end))
struct SingletonType end
@test_throws ErrorException json(SingletonType())

# test printing to STDOUT
Expand Down

0 comments on commit a36ec39

Please sign in to comment.