diff --git a/.travis.yml b/.travis.yml index 611178404..faeb961ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ os: - linux - osx julia: - - 0.4 - 0.5 - 0.6 - nightly diff --git a/README.md b/README.md index 8228fafef..34f172808 100644 --- a/README.md +++ b/README.md @@ -49,18 +49,10 @@ Please check the list below for the specific syntax you need. Currently, the `@compat` macro supports the following syntaxes: -* `@compat foo.:bar` — `foo.(:bar)` in 0.4 ([#15032]) - -* `@compat f.(args...)` — `broadcast(f, args...)` in 0.4 ([#15032]) - * `@compat (a::B{T}){T}(c) = d` — the Julia 0.5-style call overload * `@compat(get(io, s, false))`, with `s` equal to `:limit`, `:compact` or `:multiline`, to detect the corresponding print settings (performs useful work only on Julia 0.5, defaults to `false` otherwise) -* `@compat import Base.show` and `@compat function show(args...)` for handling the deprecation of `writemime` in Julia 0.5 ([#16563]). See https://github.com/JuliaLang/Compat.jl/pull/219. - -* `@compat @boundscheck checkbounds(...)` rewrites to unconditionally call `checkbounds(...)` in 0.4. The 0.4-style two-argument form of `@boundscheck` is left unchanged. - * `@compat Nullable(value, hasvalue)` to handle the switch from the `Nullable` `:isnull` field to `:hasvalue` field ([#18510]) * `@compat x .= y` converts to an in-place assignment to `x` (via `broadcast!`) ([#17510]). @@ -70,7 +62,7 @@ Currently, the `@compat` macro supports the following syntaxes: assignment operators (`.*=` and so on). * `@compat Array{<:Real}`, `@compat Array{>:Int}`, and similar uses of `<:T` (resp. `>:T`) to define a set of "covariant" (resp. "contravariant") parameterized types ([#20414]). - In 0.4 and 0.5, this only works for non-nested usages (e.g. you can't define `Array{<:Array{<:Real}}`). + In 0.5, this only works for non-nested usages (e.g. you can't define `Array{<:Array{<:Real}}`). * `@compat abstract type T end` and `@compat primitive type T 8 end` to declare abstract and primitive types. [#20418] @@ -81,7 +73,7 @@ Currently, the `@compat` macro supports the following syntaxes: * `@compat Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()` and `@compat Base.IndexStyle(::Type{<:MyArray}) = IndexCartesian()` to define traits for abstract arrays, replacing the former `Base.linearindexing{T<:MyArray}(::Type{T}) = Base.LinearFast()` and `Base.linearindexing{T<:MyArray}(::Type{T}) = Base.LinearSlow()`, respectively. -* `Compat.collect(A)` returns an `Array`, no matter what indices the array `A` has (Julia 0.5 and higher). [#21257] +* `Compat.collect(A)` returns an `Array`, no matter what indices the array `A` has. [#21257] ## Module Aliases @@ -89,23 +81,6 @@ Currently, the `@compat` macro supports the following syntaxes: module. Code can be written to work on both 0.5 and 0.6 by `import`ing or `using` the `Compat.Iterators` module instead. ([#18839]) -* The `Compat.Iterators` module is also available on 0.4, including the - iterator functions `partition`, `product`, and `flatten`, which were - introduced in Julia 0.5. However, because of a variety of other changes to - the iterator system between 0.4 and 0.5, these functions behave slightly - differently. For example, the `Iterators.product` function on 0.4 does not - return objects with shapes. ([#14596], [#14805], [#15409]) - -## Type Aliases - -* In 0.5, `ASCIIString` and `ByteString` were deprecated, and `UTF8String` was renamed to the (now concrete) type `String`. - - Compat provides unexported `Compat.UTF8String` and `Compat.ASCIIString` type aliases which are equivalent to the same types from Base on Julia 0.4, but to `String` on Julia 0.5. In most cases, using these types by calling `import Compat: UTF8String, ASCIIString` should be enough. Note that `Compat.ASCIIString` does **not** guarantee that the string only contains ASCII characters on Julia 0.5: call `isascii` to check if the string is pure ASCII if needed. - - Compat also provides an unexported `Compat.String` type which is equivalent to `ByteString` on Julia 0.4, and to `String` on Julia 0.5. This type should be used only in places where `ByteString` was used on Julia 0.4, i.e. where either `ASCIIString` or `UTF8String` should be accepted. It should **not** be used as the default type for variables or fields holding strings, as it introduces type-instability in Julia 0.4: use `Compat.UTF8String` or `Compat.ASCIIString` instead. - -* `bytestring` has been replaced in most cases with additional `String` construction methods; for 0.4 compatibility, the usage involves replacing `bytestring(args...)` with `Compat.String(args...)`. However, for converting a `Ptr{UInt8}` to a string, use the new `unsafe_string(...)` method to make a copy or `unsafe_wrap(String, ...)` to avoid a copy. - ## New functions, macros, and methods * `@views` takes an expression and converts all slices to views ([#20164]), while @@ -117,14 +92,6 @@ Currently, the `@compat` macro supports the following syntaxes: For this to work in older versions of Julia (prior to 0.5) that don't have dot calls, you should instead use `@dotcompat`, which combines the `@__dot__` and `@compat` macros. -* `foreach`, similar to `map` but when the return value is not needed ([#13744]) - -* `walkdir`, returns an iterator that walks the directory tree of a directory ([#13707]) - -* `allunique`, checks whether all elements in an iterable appear only once ([#15914]) - -* `Base.promote_eltype_op` is available as `Compat.promote_eltype_op` - * [`normalize`](http://docs.julialang.org/en/latest/stdlib/linalg/?highlight=normalize#Base.normalize) and [`normalize!`](http://docs.julialang.org/en/latest/stdlib/linalg/?highlight=normalize#Base.normalize!), normalizes a vector with respect to the p-norm ([#13681]) * `redirect_stdout`, `redirect_stderr`, and `redirect_stdin` take an optional function as a first argument, `redirect_std*(f, stream)`, so that one may use `do` block syntax (as first available for Julia 0.6) @@ -167,7 +134,7 @@ Currently, the `@compat` macro supports the following syntaxes: * `bswap` is supported for `Complex` arguments on 0.5 and below. ([#21346]) * `Compat.invokelatest` is equivalent to `Base.invokelatest` in Julia 0.6, - but works in Julia 0.4+, and allows you to guarantee that a function call + but works in Julia 0.5+, and allows you to guarantee that a function call invokes the latest version of a function ([#19784]). * `Compat.StringVector` is supported on 0.5 and below. On 0.6 and later, it aliases `Base.StringVector`. This function allocates a `Vector{UInt8}` whose data can be made into a `String` in constant time; that is, without copying. On 0.5 and later, use `String(...)` with the vector allocated by `StringVector` as an argument to create a string without copying. Note that if 0.4 support is needed, `Compat.UTF8String(...)` should be used instead. ([#19449]) @@ -178,40 +145,6 @@ Currently, the `@compat` macro supports the following syntaxes: ## Renamed functions -* `pointer_to_array` and `pointer_to_string` have been replaced with `unsafe_wrap(Array, ...)` and `unsafe_wrap(String, ...)` respectively - -* `bytestring(::Ptr, ...)` has been replaced with `unsafe_string` - -* `super` is now `supertype` ([#14338]) - -* `qr(A, pivot=b)` is now `qr(A, Val{b})`, likewise for `qrfact` and `qrfact!` - -* `readall` and `readbytes` are now `readstring` and `read` ([#14660]) - -* `get_bigfloat_precision` is now `precision(BigFloat)`, `set_precision` is `setprecision` and `with_bigfloat_precision` is now also `setprecision` -([#13232]) - -* `get_rounding` is now `rounding`. `set_rounding` and `with_rounding` are now `setrounding` ([#13232]) - -* `Base.tty_size` (which was not exported) is now `displaysize` in Julia 0.5 - -* `Compat.LinAlg.checksquare` ([#14601]) - -* `issym` is now `issymmetric` ([#15192]) - -* `istext` is now `istextmime` ([#15708]) - -* `symbol` is now `Symbol` ([#16154]) - -* `write(::IO, ::Ptr, len)` is now `unsafe_write` ([#14766]) - -* `slice` is now `view` ([#16972]); do `import Compat.view` and then use `view` normally without the `@compat` macro - -* `fieldoffsets` has been deprecated in favor of `fieldoffset` ([#14777]) - -* `print_escaped` is now another method of `escape_string`, `print_unescaped` a method of `unescape_string`, and `print_joined` a method of `join` ([#16603]) - -* `writemime` has been merged into `show` ([#16563]). Note that to extend this function requires `@compat`; see the [Supported Syntax](#supported-syntax) section for more information * `$` is now `xor` or `⊻` ([#18977]) @@ -221,12 +154,6 @@ Currently, the `@compat` macro supports the following syntaxes: ## New macros -* `@static` has been added ([#16219]) - -* `@functorize` (not present in any Julia version) takes a function (or operator) and turns it into a functor object if one is available in the used Julia version. E.g. something like `mapreduce(Base.AbsFun(), Base.MulFun(), x)` can now be written as `mapreduce(@functorize(abs), @functorize(*), x)`, and `f(::Base.AbsFun())` as `f(::typeof(@functorize(abs)))`, to work across different Julia versions. `Func{1}` can be written as `supertype(typeof(@functorize(abs)))` (and so on for `Func{2}`), which will fall back to `Function` on Julia 0.5. - -* `Compat.@blasfunc` makes functionality of `Base.LinAlg.BLAS.@blasfunc` available on older Julia versions - * `@__DIR__` has been added ([#18380]) * `@vectorize_1arg` and `@vectorize_2arg` are deprecated on Julia 0.6 in favor @@ -241,32 +168,8 @@ Currently, the `@compat` macro supports the following syntaxes: ## Other changes -* `remotecall`, `remotecall_fetch`, `remotecall_wait`, and `remote_do` have the function to be executed remotely as the first argument in Julia 0.5. Loading `Compat` defines the same methods in older versions of Julia ([#13338]) - -* `Base.FS` is now `Base.Filesystem` ([#12819]) - Compat provides an unexported `Compat.Filesystem` module that is aliased to - `Base.FS` on Julia 0.4 and `Base.Filesystem` on Julia 0.5. - -* `cov` and `cor` don't allow keyword arguments anymore. Loading Compat defines compatibility methods for the new API ([#13465]) - * On versions of Julia that do not contain a Base.Threads module, Compat defines a Threads module containing a no-op `@threads` macro. -* `Base.SingleAsyncWork` is now `Base.AsyncCondition` - Compat provides an unexported `Compat.AsyncCondition` type that is aliased to - `Base.SingleAsyncWork` on Julia 0.4 and `Base.AsyncCondition` on Julia 0.5. - -* `repeat` now accepts any `AbstractArray` ([#14082]): `Compat.repeat` supports this new API on Julia 0.4, and calls `Base.repeat` on 0.5. - -* `OS_NAME` is now `Sys.KERNEL`. OS information available as `is_apple`, `is_bsd`, `is_linux`, `is_unix`, and `is_windows` ([#16219]) - -* `cholfact`, `cholfact!`, and `chol` require that input is either `Hermitian`, `Symmetric` -or that the elements are perfectly symmetric or Hermitian on 0.5. Compat now defines methods -for `HermOrSym` such that using the new methods are backward compatible. - -* `Diagonal` and `*` methods support `SubArray`s even on 0.4. - -* Single-argument `min`, `max` and `minmax` are defined on 0.4. - * The `Expr(:macrocall)` has an extra initial argument `__source__`, which can be tested for with `Compat.macros_have_sourceloc`. ## New types diff --git a/REQUIRE b/REQUIRE index d5d646713..94237c0ff 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1 +1 @@ -julia 0.4 +julia 0.5 diff --git a/appveyor.yml b/appveyor.yml index d27a17ace..523447ddc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,5 @@ environment: matrix: - - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.4/julia-0.4-latest-win32.exe" - - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.4/julia-0.4-latest-win64.exe" - 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" diff --git a/src/Compat.jl b/src/Compat.jl index baec4dc06..c65f49e4f 100644 --- a/src/Compat.jl +++ b/src/Compat.jl @@ -7,48 +7,6 @@ using Base.Meta """Get just the function part of a function declaration.""" withincurly(ex) = isexpr(ex, :curly) ? ex.args[1] : ex -if VERSION < v"0.5.0-dev+961" - export walkdir - - function walkdir(root; topdown=true, follow_symlinks=false, onerror=throw) - content = nothing - try - content = readdir(root) - catch err - isa(err, SystemError) || throw(err) - onerror(err) - #Need to return an empty task to skip the current root folder - return Task(()->()) - end - dirs = Array(eltype(content), 0) - files = Array(eltype(content), 0) - for name in content - if isdir(joinpath(root, name)) - push!(dirs, name) - else - push!(files, name) - end - end - - function _it() - if topdown - produce(root, dirs, files) - end - for dir in dirs - path = joinpath(root,dir) - if follow_symlinks || !islink(path) - for (root_l, dirs_l, files_l) in walkdir(path, topdown=topdown, follow_symlinks=follow_symlinks, onerror=onerror) - produce(root_l, dirs_l, files_l) - end - end - end - if !topdown - produce(root, dirs, files) - end - end - Task(_it) - end -end if VERSION < v"0.6.0-dev.2043" Base.take!(t::Task) = consume(t) end @@ -96,36 +54,6 @@ function rewrite_ordereddict(ex) newex end -# rewrite Julia 0.4-style split or rsplit (str, splitter; kws...) -# into 0.2/0.3-style positional arguments -function rewrite_split(ex, f) - limit = nothing - keep = nothing - for i in 4:length(ex.args) - if isexpr(ex.args[i], :kw) - kw = ex.args[i].args - if kw[1] == :limit - limit = kw[2] - elseif kw[1] == :keep - keep = kw[2] - end - end - end - if limit == nothing - if keep == nothing - return Expr(:call, f, ex.args[2], ex.args[3]) - else - return Expr(:call, f, ex.args[2], ex.args[3], keep) - end - else - if keep == nothing - return Expr(:call, f, ex.args[2], ex.args[3], limit) - else - return Expr(:call, f, ex.args[2], ex.args[3], limit, keep) - end - end -end - # rewrites all subexpressions of the form `a => b` to `(a, b)` function rewrite_pairs_to_tuples!(expr::Expr) if expr.head == :(=>) @@ -191,169 +119,13 @@ end import Base.unsafe_convert -if VERSION < v"0.5.0-dev+3831" - Base.Symbol(args...) = symbol(args...)::Symbol -end - -if VERSION < v"0.5.0-dev+2396" - function new_style_call_overload(ex::Expr) - # Not a function call - ((ex.head === :(=) || ex.head === :function) && - length(ex.args) == 2 && isexpr(ex.args[1], :call)) || return false - callee = (ex.args[1]::Expr).args[1] - # Only Expr function name can be call overload - isa(callee, Expr) || return false - callee = callee::Expr - # (a::A)() = ... - callee.head === :(::) && return true - # The other case is with type parameter. - # Filter out everything without one. - (callee.head === :curly && length(callee.args) >= 1) || return false - # Check what the type parameter applies to is a Expr(:(::)) - return isexpr(callee.args[1], :(::)) - end -else - new_style_call_overload(ex::Expr) = false +function new_style_call_overload(ex::Expr) + Base.depwarn("new_style_call_overload is deprecated.", :new_style_call_overload) + false end istopsymbol(ex, mod, sym) = ex in (sym, Expr(:(.), mod, Expr(:quote, sym))) -if VERSION < v"0.5.0-dev+4002" - @inline broadcast_getindex(arg, idx) = arg[(idx - 1) % length(arg) + 1] - # Optimize for single element - @inline broadcast_getindex(arg::Number, idx) = arg - @inline broadcast_getindex{T}(arg::Array{T,0}, idx) = arg[1] - - # If we know from syntax level that we don't need wrapping - @inline broadcast_getindex_naive(arg, idx) = arg[idx] - @inline broadcast_getindex_naive(arg::Number, idx) = arg - @inline broadcast_getindex_naive{T}(arg::Array{T,0}, idx) = arg[1] - - # For vararg support - @inline getindex_vararg(idx) = () - @inline getindex_vararg(idx, arg1) = (broadcast_getindex(arg1, idx),) - @inline getindex_vararg(idx, arg1, arg2) = - (broadcast_getindex(arg1, idx), broadcast_getindex(arg2, idx)) - @inline getindex_vararg(idx, arg1, arg2, arg3, args...) = - (broadcast_getindex(arg1, idx), broadcast_getindex(arg2, idx), - broadcast_getindex(arg3, idx), getindex_vararg(idx, args...)...) - - @inline getindex_naive_vararg(idx) = () - @inline getindex_naive_vararg(idx, arg1) = - (broadcast_getindex_naive(arg1, idx),) - @inline getindex_naive_vararg(idx, arg1, arg2) = - (broadcast_getindex_naive(arg1, idx), - broadcast_getindex_naive(arg2, idx)) - @inline getindex_naive_vararg(idx, arg1, arg2, arg3, args...) = - (broadcast_getindex_naive(arg1, idx), - broadcast_getindex_naive(arg2, idx), - broadcast_getindex_naive(arg3, idx), - getindex_naive_vararg(idx, args...)...) - - # Decide if the result should be scalar or array - # `size() === ()` is not good enough since broadcasting on - # a scalar should return a scalar where as broadcasting on a 0-dim - # array should return a 0-dim array. - @inline should_return_array(::Val{true}, args...) = Val{true}() - @inline should_return_array(::Val{false}) = Val{false}() - @inline should_return_array(::Val{false}, arg1) = Val{false}() - @inline should_return_array(::Val{false}, arg1::AbstractArray) = Val{true}() - @inline should_return_array(::Val{false}, arg1::AbstractArray, - arg2::AbstractArray) = Val{true}() - @inline should_return_array(::Val{false}, arg1, - arg2::AbstractArray) = Val{true}() - @inline should_return_array(::Val{false}, arg1::AbstractArray, - arg2) = Val{true}() - @inline should_return_array(::Val{false}, arg1, arg2) = Val{false}() - @inline should_return_array(::Val{false}, arg1, arg2, args...) = - should_return_array(should_return_array(Val{false}(), arg1, arg2), - args...) - - @inline broadcast_return(res1d, shp, ret_ary::Val{false}) = res1d[1] - @inline broadcast_return(res1d, shp, ret_ary::Val{true}) = reshape(res1d, shp) - - @inline need_full_getindex(shp) = false - @inline need_full_getindex(shp, arg1::Number) = false - @inline need_full_getindex{T}(shp, arg1::Array{T,0}) = false - @inline need_full_getindex(shp, arg1) = shp != size(arg1) - @inline need_full_getindex(shp, arg1, arg2) = - need_full_getindex(shp, arg1) || need_full_getindex(shp, arg2) - @inline need_full_getindex(shp, arg1, arg2, arg3, args...) = - need_full_getindex(shp, arg1, arg2) || need_full_getindex(shp, arg3) || - need_full_getindex(shp, args...) - - function rewrite_broadcast(f, args) - nargs = length(args) - # This actually allows multiple splatting..., - # which is now allowed on master. - # The previous version that simply calls broadcast so removing that - # will be breaking. Oh, well.... - is_vararg = Bool[isexpr(args[i], :...) for i in 1:nargs] - names = [gensym("broadcast") for i in 1:nargs] - new_args = [is_vararg[i] ? Expr(:..., names[i]) : names[i] - for i in 1:nargs] - # Optimize for common case where we know the index doesn't need - # any wrapping - naive_getidx_for = function (i, idxvar) - if is_vararg[i] - Expr(:..., :($Compat.getindex_naive_vararg($idxvar, - $(names[i])...))) - else - :($Compat.broadcast_getindex_naive($(names[i]), $idxvar)) - end - end - always_naive = nargs == 1 && !is_vararg[1] - getidx_for = if always_naive - naive_getidx_for - else - function (i, idxvar) - if is_vararg[i] - Expr(:..., :($Compat.getindex_vararg($idxvar, - $(names[i])...))) - else - :($Compat.broadcast_getindex($(names[i]), $idxvar)) - end - end - end - @gensym allidx - @gensym newshape - @gensym res1d - @gensym idx - @gensym ret_ary - - res1d_expr = quote - $res1d = [$f($([naive_getidx_for(i, idx) for i in 1:nargs]...)) - for $idx in $allidx] - end - if !always_naive - res1d_expr = quote - if $Compat.need_full_getindex($newshape, $(new_args...)) - $res1d = [$f($([getidx_for(i, idx) for i in 1:nargs]...)) - for $idx in $allidx] - else - $res1d_expr - end - end - end - - return quote - # The `local` makes sure type inference can infer the type even - # in global scope as long as the input is type stable - local $(names...) - $([:($(names[i]) = $(is_vararg[i] ? args[i].args[1] : args[i])) - for i in 1:nargs]...) - local $newshape = $(Base.Broadcast).broadcast_shape($(new_args...)) - # `eachindex` is not generic enough - local $allidx = 1:prod($newshape) - local $ret_ary = $Compat.should_return_array(Val{false}(), - $(new_args...)) - local $res1d - $res1d_expr - $Compat.broadcast_return($res1d, $newshape, $ret_ary) - end - end -end - if VERSION < v"0.6.0-dev.2782" function new_style_typealias(ex::ANY) isexpr(ex, :(=)) || return false @@ -367,16 +139,10 @@ end function _compat(ex::Expr) if ex.head === :call f = ex.args[1] - if VERSION < v"0.5.0-dev+4340" && length(ex.args) > 3 && - istopsymbol(withincurly(ex.args[1]), :Base, :show) - ex = rewrite_show(ex) - elseif VERSION < v"0.6.0-dev.826" && length(ex.args) == 3 && # julia#18510 + if VERSION < v"0.6.0-dev.826" && length(ex.args) == 3 && # julia#18510 istopsymbol(withincurly(ex.args[1]), :Base, :Nullable) ex = Expr(:call, f, ex.args[2], Expr(:call, :(Compat._Nullable_field2), ex.args[3])) end - if VERSION < v"0.5.0-dev+4305" - rewrite_iocontext!(ex) - end elseif ex.head === :curly f = ex.args[1] if ex == :(Ptr{Void}) @@ -391,85 +157,14 @@ function _compat(ex::Expr) end elseif ex.head === :macrocall f = ex.args[1] - if VERSION < v"0.5.0-dev+2129" && f === symbol("@boundscheck") && length(ex.args) == 2 - # Handle 0.5 single argument @boundscheck syntax. (0.4 has a two - # arguments and a very diffferent meaning). `nothing` is included - # so we have a consistent return type. - ex = :($(ex.args[2]); nothing) - end elseif ex.head === :quote && isa(ex.args[1], Symbol) # Passthrough return ex - elseif new_style_call_overload(ex) - callexpr = ex.args[1]::Expr - callee = callexpr.args[1]::Expr - is_kw = (length(callexpr.args) >= 2 && - isexpr(callexpr.args[2], :parameters)) - if callee.head === :(::) - # (:function, (:call, :(:(::), <1>), <2>), ) -> - # (:function, (:call, :(Base.call), :(:(::), <1>), <2>), ) - unshift!(callexpr.args, :(Base.call)) - else - # (:function, (:call, :(curly, :(:(::), <1>), <3>), <2>), ) -> - # (:function, (:call, :(curly, :(Base.call), <3>), :(:(::), <1>), <2>), ) - obj = callee.args[1]::Expr - callee.args[1] = :(Base.call) - insert!(callexpr.args, 2, obj) - end - if is_kw - # Expr(:parameters) is moved to the 3rd argument - params = callexpr.args[3] - @assert isexpr(params, :parameters) - obj = callexpr.args[2] - callexpr.args[2] = params - callexpr.args[3] = obj - end - elseif VERSION < v"0.5.0-dev+4002" && ex.head == :. && length(ex.args) == 2 # 15032 - if isexpr(ex.args[2], :quote) && isa(ex.args[2].args[1], QuoteNode) - # foo.:bar -> foo.(:bar) in older Julia - return Expr(ex.head, _compat(ex.args[1]), ex.args[2].args[1]) - elseif isexpr(ex.args[2], :quote) && isexpr(ex.args[2].args[1], :quote) && - isa(ex.args[2].args[1].args[1], Symbol) - # foo.:bar -> foo.(:bar) in older Julia - return Expr(ex.head, _compat(ex.args[1]), QuoteNode(ex.args[2].args[1].args[1])) - elseif isexpr(ex.args[2], :tuple) - # f.(arg1, arg2...) -> broadcast(f, arg1, arg2...) - return rewrite_broadcast(_compat(ex.args[1]), - map(_compat, ex.args[2].args)) - elseif !isa(ex.args[2], QuoteNode) && - !(isexpr(ex.args[2], :quote) && isa(ex.args[2].args[1], Symbol)) - # f.(arg) -> broadcast(f, arg) - return rewrite_broadcast(_compat(ex.args[1]), [_compat(ex.args[2])]) - end elseif new_style_typealias(ex) ex.head = :typealias elseif ex.head === :const && length(ex.args) == 1 && new_style_typealias(ex.args[1]) ex = ex.args[1]::Expr ex.head = :typealias - elseif ex.head === :import - if VERSION < v"0.5.0-dev+4340" && length(ex.args) == 2 && ex.args[1] === :Base && ex.args[2] === :show - return quote - import Base.show - import Base.writemime - end - end - elseif VERSION < v"0.5.0-dev+5575" #17510 - if isexpr(ex, :comparison) - if length(ex.args) == 3 && ex.args[2] == :.= - return :(Base.broadcast!(Base.identity, $(_compat(todotview(ex.args[1]))), $(_compat(ex.args[3])))) - elseif length(ex.args) > 3 && ex.args[2] == :.= - return :(Base.broadcast!(Base.identity, $(_compat(todotview(ex.args[1]))), $(_compat(Expr(:comparison, ex.args[3:end]...))))) - end - elseif ex.head == :.= && length(ex.args) == 2 # may arise in macro-constructed expressions - return :(Base.broadcast!(Base.identity, $(_compat(todotview(ex.args[1]))), $(_compat(ex.args[2])))) - end - end - if VERSION < v"0.5.0-dev+5575" #17510 - # transform e.g. x .+= y into x .= x .+ y: - shead = string(ex.head) - if first(shead) == '.' && length(shead) > 2 && last(shead) == '=' && length(ex.args) == 2 - return _compat(Expr(:comparison, ex.args[1], :.=, Expr(:call, Symbol(shead[1:end-1]), ex.args...))) - end end if VERSION < v"0.6.0-dev.2840" if ex.head == :(=) && isa(ex.args[1], Expr) && ex.args[1].head == :call @@ -485,12 +180,7 @@ function _compat(ex::Expr) end return Expr(ex.head, map(_compat, ex.args)...) end -function _compat(ex::Symbol) - if VERSION < v"0.5.0-dev+1343" && (ex == :Future || ex == :RemoteChannel) - return :RemoteRef - end - return ex -end + _compat(ex) = ex function _get_typebody(ex::Expr) @@ -547,132 +237,8 @@ export @compat, @inline, @noinline import Base.@irrational import Base: remotecall, remotecall_fetch, remotecall_wait, remote_do -if VERSION < v"0.5.0-dev+431" - for f in (:remotecall, :remotecall_fetch, :remotecall_wait, :remote_do) - @eval begin - ($f)(f::Function, w::Base.LocalProcess, args...) = ($f)(w, f, args...) - ($f)(f::Function, w::Base.Worker, args...) = ($f)(w, f, args...) - ($f)(f::Function, id::Integer, args...) = ($f)(id, f, args...) - end - end -end - -if VERSION < v"0.5.0-dev+763" - export SparseArrays - const SparseArrays = Base.SparseMatrix -end - -if VERSION < v"0.5.0-dev+1229" - const Filesystem = Base.FS -else - import Base.Filesystem -end - -if VERSION < v"0.5.0-dev+1946" - const supertype = super - export supertype -end - -if VERSION < v"0.5.0-dev+679" - import Base: cov, cor - - cov(x::AbstractVector, corrected::Bool) = cov(x, corrected=corrected) - cov(X::AbstractMatrix, vardim::Integer) = cov(X, vardim=vardim) - cov(X::AbstractMatrix, vardim::Integer, corrected::Bool) = cov(X, vardim=vardim, corrected=corrected) - cov(x::AbstractVector, y::AbstractVector, corrected::Bool) = cov(x, y, corrected=corrected) - cov(X::AbstractMatrix, Y::AbstractMatrix, vardim::Integer) = cov(X, Y, vardim=vardim) - cov(X::AbstractMatrix, Y::AbstractMatrix, vardim::Integer, corrected::Bool) = cov(X, Y, vardim=vardim, corrected=corrected) - - cor(X::AbstractMatrix, vardim::Integer) = cor(X, vardim=vardim) - cor(X::AbstractMatrix, Y::AbstractMatrix, vardim::Integer) = cor(X, Y, vardim=vardim) -end - -if VERSION < v"0.5.0-dev+2228" - const readstring = readall - export readstring - - Base.read(s::IO) = readbytes(s) - Base.read(s::IO, nb) = readbytes(s, nb) - - Base.write(filename::AbstractString, args...) = open(io->write(io, args...), filename, "w") - - Base.read(filename::AbstractString, args...) = open(io->read(io, args...), filename) - Base.read!(filename::AbstractString, a) = open(io->read!(io, a), filename) - Base.readuntil(filename::AbstractString, args...) = open(io->readuntil(io, args...), filename) - Base.readline(filename::AbstractString) = open(Base.readline, filename) - Base.readlines(filename::AbstractString) = open(Base.readlines, filename) - Base.readavailable(s::IOStream) = read!(s, @compat Vector{UInt8}(nb_available(s))) - Base.readavailable(s::IOBuffer) = read(s) - - function Base.write(to::IO, from::IO) - while !eof(from) - write(to, readavailable(from)) - end - end - - function Base.eachline(filename::AbstractString) - s = open(filename) - EachLine(s, ()->close(s)) - end -end - -if VERSION < v"0.5.0-dev+2023" - const displaysize = Base.tty_size - export displaysize -end - - -# Pull Request https://github.com/JuliaLang/julia/pull/13232 -# Rounding and precision functions: - -if VERSION >= v"0.5.0-dev+1182" - import Base: - setprecision, setrounding, rounding - -else # if VERSION < v"0.5.0-dev+1182" - - export setprecision - export setrounding - export rounding - setprecision(f, ::Type{BigFloat}, prec) = with_bigfloat_precision(f, prec) - setprecision(::Type{BigFloat}, prec) = set_bigfloat_precision(prec) - - # assume BigFloat if type not explicit: - setprecision(prec) = setprecision(BigFloat, prec) - setprecision(f, prec) = setprecision(f, BigFloat, prec) - - Base.precision(::Type{BigFloat}) = get_bigfloat_precision() - - setrounding(f, T, rounding_mode) = - with_rounding(f, T, rounding_mode) - - setrounding(T, rounding_mode) = set_rounding(T, rounding_mode) - - rounding(T) = get_rounding(T) - -end - -module LinAlg - if VERSION < v"0.5.0-dev+2022" - const checksquare = Base.LinAlg.chksquare - else - import Base.LinAlg.checksquare - end -end - -if VERSION < v"0.5.0-dev+2915" - const issymmetric = issym - export issymmetric -end - -if VERSION < v"0.5.0-dev+977" - export foreach - - foreach(f) = (f(); nothing) - foreach(f, itr) = (for x in itr; f(x); end; nothing) - foreach(f, itrs...) = (for z in zip(itrs...); f(z...); end; nothing) -end +import Base.Filesystem if !isdefined(Base, :istextmime) export istextmime @@ -688,83 +254,6 @@ function primarytype(t::ANY) end end -export @functorize -macro functorize(f) - if VERSION >= v"0.5.0-dev+3701" - f === :scalarmax ? :(Base.scalarmax) : - f === :scalarmin ? :(Base.scalarmin) : - f === :centralizedabs2fun ? :(primarytype(typeof(Base.centralizedabs2fun(0)))) : - f - else - f = f === :identity ? :(Base.IdFun()) : - f === :abs ? :(Base.AbsFun()) : - f === :abs2 ? :(Base.Abs2Fun()) : - f === :exp ? :(Base.ExpFun()) : - f === :log ? :(Base.LogFun()) : - f === :& ? :(Base.AndFun()) : - f === :| ? :(Base.OrFun()) : - f === :+ ? :(Base.AddFun()) : - f === :* ? :(Base.MulFun()) : - f === :scalarmax ? :(Base.MaxFun()) : - f === :scalarmin ? :(Base.MinFun()) : - f === :centralizedabs2fun ? :(Base.CentralizedAbs2Fun) : - f - if VERSION >= v"0.4.0-dev+4902" - f = f === :< ? :(Base.LessFun()) : - f === :> ? :(Base.MoreFun()) : - f - end - if VERSION >= v"0.4.0-dev+4902" - f = f === :conj ? :(Base.ConjFun()) : - f - end - if VERSION >= v"0.4.0-dev+6254" - f = f === :- ? :(Base.SubFun()) : - f === :^ ? :(Base.PowFun()) : - f - end - if VERSION >= v"0.4.0-dev+6256" - f = f === :/ ? :(Base.RDivFun()) : - f === :\ ? :(Base.LDivFun()) : - f === :div ? :(Base.IDivFun()) : - f - end - if VERSION >= v"0.4.0-dev+6353" - f = f === :$ ? :(Base.XorFun()) : - f === :.+ ? :(Base.DotAddFun()) : - f === :.- ? :(Base.DotSubFun()) : - f === :.* ? :(Base.DotMulFun()) : - f === :mod ? :(Base.ModFun()) : - f === :rem ? :(Base.RemFun()) : - # DotRemFun is defined, but ::call(::DotRemFun, ...) is not until later - #f === :.% ? :(Base.DotRemFun()) : - f === :.<< ? :(Base.DotLSFun()) : - f === :.>> ? :(Base.DotRSFun()) : - f - end - if VERSION >= v"0.4.0-dev+6359" - f = f === :./ ? :(Base.DotRDivFun()) : - f - end - if VERSION >= v"0.4.0-rc1+59" - f = f === :max ? :(Base.ElementwiseMaxFun()) : - f === :min ? :(Base.ElementwiseMinFun()) : - f - end - if VERSION >= v"0.5.0-dev+741" - f = f === :complex ? :(Base.SparseArrays.ComplexFun()) : - f === :dot ? :(Base.SparseArrays.DotFun()) : - f - end - if VERSION >= v"0.5.0-dev+1472" - f = f === Symbol(".÷") ? :(Base.DotIDivFun()) : - f === :.% ? :(Base.DotRemFun()) : - f - end - f - end -end - if !isdefined(Base, :Threads) @eval module Threads macro threads(expr) @@ -815,161 +304,9 @@ if !isdefined(Base, :normalize) export normalize, normalize! end -if !isdefined(Base, :AsyncCondition) - include_string(""" - type AsyncCondition - cond::Condition - handle::Ptr{Void} - - function AsyncCondition(func=nothing) - this = new(Condition()) - # the callback is supposed to be called with this AsyncCondition - # as the argument, so we need to create a wrapper callback - if func == nothing - function wrapfunc(data) - notify(this.cond) - - nothing - end - else - function wrapfunc(data) - notify(this.cond) - func(this) - - nothing - end - end - work = Base.SingleAsyncWork(wrapfunc) - this.handle = work.handle - - this - end - end - """) - - Base.wait(c::AsyncCondition) = wait(c.cond) -else - import Base.AsyncCondition -end - -# 0.5.0-dev+2301, JuliaLang/julia#14766 -if !isdefined(Base, :unsafe_write) - const unsafe_write = write - export unsafe_write -end - -# JuliaLang/julia#16219 -if !isdefined(Base, @compat Symbol("@static")) - macro static(ex) - if isa(ex, Expr) - if ex.head === :if - cond = eval(current_module(), ex.args[1]) - if cond - return esc(ex.args[2]) - elseif length(ex.args) == 3 - return esc(ex.args[3]) - else - return nothing - end - end - end - throw(ArgumentError("invalid @static macro")) - end - export @static -end - -# JuliaLang/julia#14082 -if VERSION < v"0.5.0-dev+4295" - function repeat(A::AbstractArray; - inner=ntuple(x->1, ndims(A)), - outer=ntuple(x->1, ndims(A))) - ndims_in = ndims(A) - length_inner = length(inner) - length_outer = length(outer) - - length_inner >= ndims_in || throw(ArgumentError("number of inner repetitions ($(length(inner))) cannot be less than number of dimensions of input ($(ndims(A)))")) - length_outer >= ndims_in || throw(ArgumentError("number of outer repetitions ($(length(outer))) cannot be less than number of dimensions of input ($(ndims(A)))")) - - ndims_out = max(ndims_in, length_inner, length_outer) - - inner = vcat(collect(inner), ones(Int,ndims_out-length_inner)) - outer = vcat(collect(outer), ones(Int,ndims_out-length_outer)) - - size_in = size(A) - size_out = ntuple(i->inner[i]*size(A,i)*outer[i],ndims_out)::Dims - inner_size_out = ntuple(i->inner[i]*size(A,i),ndims_out)::Dims - - indices_in = Array(Int, ndims_in) - indices_out = Array(Int, ndims_out) - - length_out = prod(size_out) - R = similar(A, size_out) - - for index_out in 1:length_out - indices_out = ind2sub(size_out, index_out) - for t in 1:ndims_in - # "Project" outer repetitions into inner repetitions - indices_in[t] = mod1(indices_out[t], inner_size_out[t]) - # Find inner repetitions using flooring division - indices_in[t] = Base.fld1(indices_in[t], inner[t]) - end - index_in = sub2ind(size_in, indices_in...) - R[index_out] = A[index_in] - end - - return R - end -else - const repeat = Base.repeat -end - -if VERSION < v"0.5.0-dev+4267" - if OS_NAME == :Windows - const KERNEL = :NT - else - const KERNEL = OS_NAME - end - - @eval is_apple() = $(KERNEL == :Darwin) - @eval is_linux() = $(KERNEL == :Linux) - @eval is_bsd() = $(KERNEL in (:FreeBSD, :OpenBSD, :NetBSD, :Darwin, :Apple)) - @eval is_unix() = $(is_linux() || is_bsd()) - @eval is_windows() = $(KERNEL == :NT) - export is_apple, is_linux, is_bsd, is_unix, is_windows -else - const KERNEL = Sys.KERNEL -end - +import Base.AsyncCondition import Base: srand, rand, rand! -if isdefined(Core, :String) && isdefined(Core, :AbstractString) - # Not exported in order to not break code on 0.5 - const UTF8String = Core.String - const ASCIIString = Core.String -else - const String = Base.ByteString - if VERSION >= v"0.4.0-dev+5243" - @compat (::Type{Base.ByteString})(io::Base.AbstractIOBuffer) = bytestring(io) - elseif VERSION >= v"0.4.0-dev+1246" - @compat (::Type{Base.ByteString})(io::IOBuffer) = bytestring(io) - end - if VERSION >= v"0.4.0-dev+1246" - @compat (::Type{Base.ByteString})(s::Cstring) = bytestring(s) - @compat (::Type{Base.ByteString})(v::Vector{UInt8}) = bytestring(v) - @compat (::Type{Base.ByteString})(p::Union{Ptr{Int8},Ptr{UInt8}}) = bytestring(p) - @compat (::Type{Base.ByteString})(p::Union{Ptr{Int8},Ptr{UInt8}}, len::Integer) = bytestring(p, len) - @compat (::Type{Base.ByteString})(s::AbstractString) = bytestring(s) - end -end - -if VERSION < v"0.5.0-dev+2285" - fieldoffset(T, i) = @compat UInt(fieldoffsets(T)[i]) - export fieldoffset -end - -if !isdefined(Base, :view) - const view = slice -end if !isdefined(Base, :pointer_to_string) @@ -984,71 +321,9 @@ if !isdefined(Base, :pointer_to_string) end -if VERSION < v"0.5.0-dev+4612" - export unsafe_string, unsafe_wrap - unsafe_wrap(::Type{Compat.String}, p::@compat(Union{Ptr{Int8},Ptr{UInt8}}), own::Bool=false) = pointer_to_string(convert(Ptr{UInt8}, p), own) - unsafe_wrap(::Type{Compat.String}, p::@compat(Union{Ptr{Int8},Ptr{UInt8}}), len, own::Bool=false) = pointer_to_string(convert(Ptr{UInt8}, p), len, own) - unsafe_wrap(::Type{Array}, p::Ptr, dims, own::Bool=false) = pointer_to_array(p, dims, own) - unsafe_string(p::@compat(Union{Ptr{Int8},Ptr{UInt8}})) = bytestring(p) - unsafe_string(p::@compat(Union{Ptr{Int8},Ptr{UInt8}}), len) = bytestring(p, len) - if Cstring != Ptr{UInt8} - unsafe_string(p::Cstring) = unsafe_string(Ptr{UInt8}(p)) - end -end +import Base.promote_eltype_op -if !isdefined(Base, :allunique) - allunique(itr) = length(itr) == length(unique(itr)) - export allunique -end - -if !isdefined(Base, :promote_eltype_op) - if isdefined(Base, :promote_op) - promote_eltype_op(::Any) = Union{} - promote_eltype_op{T}(op, ::AbstractArray{T}) = Base.promote_op(op, T) - promote_eltype_op{T}(op, ::T ) = Base.promote_op(op, T) - promote_eltype_op{R,S}(op, ::AbstractArray{R}, ::AbstractArray{S}) = Base.promote_op(op, R, S) - promote_eltype_op{R,S}(op, ::AbstractArray{R}, ::S) = Base.promote_op(op, R, S) - promote_eltype_op{R,S}(op, ::R, ::AbstractArray{S}) = Base.promote_op(op, R, S) - promote_eltype_op(op, A, B, C, D...) = Base.promote_op(op, eltype(A), promote_eltype_op(op, B, C, D...)) - else - promote_eltype_op(::Any) = Union{} - promote_eltype_op{T}(op, ::AbstractArray{T}) = T - promote_eltype_op{T}(op, ::T ) = T - promote_eltype_op{R,S}(op, ::AbstractArray{R}, ::AbstractArray{S}) = Base.promote_type(R, S) - promote_eltype_op{R,S}(op, ::AbstractArray{R}, ::S) = Base.promote_type(R, S) - promote_eltype_op{R,S}(op, ::R, ::AbstractArray{S}) = Base.promote_type(R, S) - promote_eltype_op(op, A, B, C, D...) = Base.promote_type(eltype(A), promote_eltype_op(op, B, C, D...)) - end -else - import Base.promote_eltype_op -end - -if VERSION < v"0.5.0-dev+4351" - Base.join(io::IO, items) = - print_joined(io, items) - Base.join(io::IO, items, delim) = - print_joined(io, items, delim) - Base.join(io::IO, items, delim, last) = - print_joined(io, items, delim, last) - Base.unescape_string(io, s::AbstractString) = - print_unescaped(io, s) - Base.escape_string(io, str::AbstractString, esc::AbstractString) = - print_escaped(io, str, esc) -end - -if VERSION < v"0.5.0-dev+4340" - Base.show(io::IO, mime, x) = writemime(io, mime, x) -end - -if VERSION >= v"0.5.0-dev+4338" - import Base.LinAlg.BLAS.@blasfunc -elseif VERSION >= v"0.5.0-dev+1871" - import Base.@blasfunc -else - macro blasfunc(x) - Expr(:quote, Base.blasfunc(x)) - end -end +import Base.LinAlg.BLAS.@blasfunc import Base: redirect_stdin, redirect_stdout, redirect_stderr if VERSION < v"0.6.0-dev.374" @@ -1107,18 +382,8 @@ macro dep_vectorize_2arg(S, f) end end -if VERSION < v"0.5.0-dev+4677" - using Base.LinAlg: HermOrSym - Base.chol(A::HermOrSym) = Base.LinAlg.chol!(A.uplo == 'U' ? copy(A.data) : A.data') - Base.cholfact(A::HermOrSym) = cholfact(A.data, Symbol(A.uplo)) - Base.cholfact!(A::HermOrSym) = cholfact!(A.data, Symbol(A.uplo)) - - Base.cholfact(A::HermOrSym, T::Type) = cholfact(A.data, Symbol(A.uplo), T) - Base.cholfact!(A::HermOrSym, T::Type) = cholfact!(A.data, Symbol(A.uplo), T) -end - # broadcast over same length tuples, from julia#16986 -if v"0.5.0-dev+4002" ≤ VERSION < v"0.6.0-dev.693" +if VERSION < v"0.6.0-dev.693" Base.Broadcast.broadcast{N}(f, t::NTuple{N}, ts::Vararg{NTuple{N}}) = map(f, t, ts...) end @@ -1172,32 +437,6 @@ if VERSION < v"0.6.0-dev.1256" Base.take!(io::Base.AbstractIOBuffer) = takebuf_array(io) end -# julia #17323 -if VERSION < v"0.5.0-dev+5380" - export transcode - transcode{T<:Compat.String}(::Type{T}, src::Union{Compat.String,Vector{UInt8}}) = utf8(src) - transcode{T<:Compat.String}(::Type{T}, src::Vector{UInt16}) = utf8(utf16(src)) - transcode{T<:Compat.String}(::Type{T}, src::Vector{UInt32}) = utf8(utf32(src)) - transcode(::Type{UInt8}, src::Vector{UInt8}) = src - transcode(::Type{UInt8}, src) = transcode(Compat.String, src).data - function transcode(::Type{UInt16}, src::Union{Compat.String,Vector{UInt8}}) - d = utf16(utf8(src)).data - return resize!(d, length(d)-1) # strip off trailing NUL codeunit - end - function transcode(::Type{UInt32}, src::Union{Compat.String,Vector{UInt8}}) - d = utf32(utf8(src)).data - return resize!(d, length(d)-1) # strip off trailing NUL codeunit - end - transcode(::Type{UInt16}, src::Vector{UInt16}) = src - transcode(::Type{UInt32}, src::Vector{UInt32}) = src - if Cwchar_t == Int32 - transcode(::Type{Cwchar_t}, src::Vector{Cwchar_t}) = src - transcode(::Type{Cwchar_t}, src) = reinterpret(Cwchar_t, transcode(UInt32, src)) - transcode(::Type{UInt8}, src::Vector{Cwchar_t}) = transcode(UInt8, reinterpret(UInt32, src)) - transcode(T, src::Vector{Cwchar_t}) = transcode(T, reinterpret(UInt32, src)) - end -end - # julia #17155 function composition and negation if VERSION < v"0.6.0-dev.1883" export ∘ @@ -1205,20 +444,8 @@ if VERSION < v"0.6.0-dev.1883" @compat Base.:!(f::Function) = (x...)->!f(x...) end -if VERSION < v"0.5.0-dev+1450" - Base.Diagonal(v::AbstractVector) = Diagonal(collect(v)) -end -if VERSION < v"0.5.0-dev+3669" - using Base: promote_op - import Base: * - eval(Expr(:typealias, :(SubMatrix{T}), :(SubArray{T,2}))) - (*)(A::SubMatrix, D::Diagonal) = - scale!(similar(A, promote_op(*, eltype(A), eltype(D.diag))), A, D.diag) - (*)(D::Diagonal, A::SubMatrix) = - scale!(similar(A, promote_op(*, eltype(A), eltype(D.diag))), D.diag, A) -end -if VERSION >= v"0.5.0-dev+5509" && VERSION < v"0.6.0-dev.1632" +if VERSION < v"0.6.0-dev.1632" # To work around unsupported syntax on Julia 0.4 include_string("export .&, .|") include_string(".&(xs...) = broadcast(&, xs...)") @@ -1234,15 +461,7 @@ else import Base.isapprox end -# julia #13998 single-argument min and max -if VERSION < v"0.5.0-dev+1279" - Base.min(x::Real) = x - Base.max(x::Real) = x - Base.minmax(x::Real) = (x, x) -end - module TypeUtils - using ..Compat: @static @static if isdefined(Base, :isabstract) using Base: isabstract, parameter_upper_bound, typename else @@ -1272,151 +491,9 @@ if VERSION < v"0.6.0-dev.1024" zip using Compat - # julia #14805 - if VERSION < v"0.5.0-dev+3256" - include_string(""" - immutable Flatten{I} - it::I - end - """) - - flatten(itr) = Flatten(itr) - - eltype{I}(::Type{Flatten{I}}) = eltype(eltype(I)) - - function start(f::Flatten) - local inner, s2 - s = start(f.it) - d = done(f.it, s) - # this is a simple way to make this function type stable - d && throw(ArgumentError("argument to Flatten must contain at least one iterator")) - while !d - inner, s = next(f.it, s) - s2 = start(inner) - !done(inner, s2) && break - d = done(f.it, s) - end - return s, inner, s2 - end - - @inline function next(f::Flatten, state) - s, inner, s2 = state - val, s2 = next(inner, s2) - while done(inner, s2) && !done(f.it, s) - inner, s = next(f.it, s) - s2 = start(inner) - end - return val, (s, inner, s2) - end - - @inline function done(f::Flatten, state) - s, inner, s2 = state - return done(f.it, s) && done(inner, s2) - end - else - using Base: flatten - end - - # julia #14596 - if VERSION < v"0.5.0-dev+2305" - # Product -- cartesian product of iterators - @compat abstract type AbstractProdIterator end - - include_string(""" - immutable Prod2{I1, I2} <: AbstractProdIterator - a::I1 - b::I2 - end - """) - - product(a) = Zip1(a) - product(a, b) = Prod2(a, b) - eltype{I1,I2}(::Type{Prod2{I1,I2}}) = Tuple{eltype(I1), eltype(I2)} - length(p::AbstractProdIterator) = length(p.a)*length(p.b) - - function start(p::AbstractProdIterator) - s1, s2 = start(p.a), start(p.b) - s1, s2, Nullable{eltype(p.b)}(), (done(p.a,s1) || done(p.b,s2)) - end - - @inline function prod_next(p, st) - s1, s2 = st[1], st[2] - v1, s1 = next(p.a, s1) - - nv2 = st[3] - if isnull(nv2) - v2, s2 = next(p.b, s2) - else - v2 = nv2.value - end - - if done(p.a, s1) - return (v1,v2), (start(p.a), s2, oftype(nv2,nothing), done(p.b,s2)) - end - return (v1,v2), (s1, s2, Nullable(v2), false) - end - - @inline next(p::Prod2, st) = prod_next(p, st) - @inline done(p::AbstractProdIterator, st) = st[4] - - include_string(""" - immutable Prod{I1, I2<:AbstractProdIterator} <: AbstractProdIterator - a::I1 - b::I2 - end - """) - - product(a, b, c...) = Prod(a, product(b, c...)) - eltype{I1,I2}(::Type{Prod{I1,I2}}) = tuple_type_cons(eltype(I1), eltype(I2)) - - @inline function next{I1,I2}(p::Prod{I1,I2}, st) - x = prod_next(p, st) - ((x[1][1],x[1][2]...), x[2]) - end - else - using Base: product - end - - # julia #15409 - if VERSION < v"0.5.0-dev+3510" - partition{T}(c::T, n::Int) = PartitionIterator{T}(c, n) - - include_string(""" - type PartitionIterator{T} - c::T - n::Int - end - """) - - eltype{T}(::Type{PartitionIterator{T}}) = Vector{eltype(T)} - - function length(itr::PartitionIterator) - l = length(itr.c) - return div(l, itr.n) + ((mod(l, itr.n) > 0) ? 1 : 0) - end - - start(itr::PartitionIterator) = start(itr.c) - - done(itr::PartitionIterator, state) = done(itr.c, state) - - function next{T<:Vector}(itr::PartitionIterator{T}, state) - l = state - r = min(state + itr.n-1, length(itr.c)) - return sub(itr.c, l:r), r + 1 - end - - function next(itr::PartitionIterator, state) - v = Vector{eltype(itr.c)}(itr.n) - i = 0 - while !done(itr.c, state) && i < itr.n - i += 1 - v[i], state = next(itr.c, state) - end - return resize!(v, i), state - end - else - using Base: partition - end + using Base: flatten + using Base: product + using Base: partition end else using Base: Iterators @@ -1503,7 +580,7 @@ else end # https://github.com/JuliaLang/julia/pull/21257 -if v"0.5.0-rc1+46" <= VERSION < v"0.6.0-pre.beta.28" +if VERSION < v"0.6.0-pre.beta.28" collect(A) = collect_indices(indices(A), A) collect_indices(::Tuple{}, A) = copy!(Array{eltype(A)}(), A) collect_indices(indsA::Tuple{Vararg{Base.OneTo}}, A) = @@ -1530,7 +607,7 @@ if VERSION < v"0.6.0-pre.beta.455" isless(x::Dates.OtherPeriod, y::Dates.FixedPeriod) = throw(MethodError(isless, (x, y))) end -include("to-be-deprecated.jl") +include("deprecated.jl") # https://github.com/JuliaLang/julia/pull/21746 const macros_have_sourceloc = VERSION >= v"0.7-" && length(:(@test).args) == 2 diff --git a/src/arraymacros.jl b/src/arraymacros.jl index 0bd32c425..7435ddda7 100644 --- a/src/arraymacros.jl +++ b/src/arraymacros.jl @@ -68,25 +68,6 @@ if VERSION < v"0.6.0-dev.2406" end end -# convert x[...] on lhs of .= to a view in broadcast! call -if VERSION < v"0.5.0-dev+5575" #17510 - dotview(args...) = getindex(args...) - dotview(A::AbstractArray, args...) = view(A, args...) - dotview{T<:AbstractArray}(A::AbstractArray{T}, args::Integer...) = getindex(A, args...) - todotview(x) = x - function todotview(ex::Expr) - if ex.head == :ref - ex = replace_ref_end!(ex) - if Meta.isexpr(ex, :ref) - ex = Expr(:call, dotview, ex.args...) - else # ex replaced by let ...; foo[...]; end - assert(Meta.isexpr(ex, :let) && Meta.isexpr(ex.args[1], :ref)) - ex.args[1] = Expr(:call, dotview, ex.args[1].args...) - end - end - end -end - if !isdefined(Base, Symbol("@view")) macro view(ex) if Meta.isexpr(ex, :ref) @@ -121,15 +102,6 @@ if !isdefined(Base, Symbol("@views")) Expr(ex.head, Meta.isexpr(lhs, :ref) ? Expr(:ref, map(_views, lhs.args)...) : _views(lhs), _views(ex.args[2])) - elseif VERSION < v"0.5.0-dev+5575" && isexpr(ex, :comparison) && ex.args[2] == :.= #17510 - # as above, but in Julia 0.4 a .= produces a comparison expression - lhs_ = ex.args[1] - lhs = Meta.isexpr(lhs_, :ref) ? Expr(:ref, map(_views, lhs_.args)...) : _views(lhs_) - if length(ex.args) == 3 - Expr(:.=, lhs, _views(ex.args[3])) - else - Expr(:.=, lhs, _views(Expr(:comparison, ex.args[3:end]...))) - end elseif ex.head == :ref Expr(:call, maybeview, map(_views, ex.args)...) else diff --git a/src/ngenerate.jl b/src/deprecated.jl similarity index 69% rename from src/ngenerate.jl rename to src/deprecated.jl index 0e8552c13..36b54ec84 100644 --- a/src/ngenerate.jl +++ b/src/deprecated.jl @@ -1,7 +1,25 @@ -# Uncomment the depwarns when we drop 0.4 support +function depwarn_ex(msg, name) + return quote + if VERSION >= v"0.6.0" + Base.depwarn($msg, Symbol($name)) + end + end +end + +macro Dict(pairs...) + esc(Expr(:block, depwarn_ex("@Dict is deprecated, use Dict instead", "@Dict"), + Expr(:call, :Dict, pairs...))) +end + +macro AnyDict(pairs...) + esc(Expr(:block, depwarn_ex("@AnyDict is deprecated, use Dict{Any,Any} instead", "@AnyDict"), + Expr(:call, :(Base.AnyDict), pairs...))) +end module CompatCartesian +import ..Compat: depwarn_ex + export @ngenerate, @nsplat macro ngenerate(itersym, returntypeexpr, funcexpr) @@ -9,7 +27,7 @@ macro ngenerate(itersym, returntypeexpr, funcexpr) funcexpr = Base._inline(funcexpr.args[2]) end isfuncexpr(funcexpr) || error("Requires a function expression") - esc(Expr(:block, # :(Base.depwarn("@ngenerate is deprecated, used @generated function or (preferably) tuples/CartesianIndex instead", Symbol("@ngenerate"))), + esc(Expr(:block, depwarn_ex("@ngenerate is deprecated, used @generated function or (preferably) tuples/CartesianIndex instead", "@ngenerate"), _ngenerate(itersym, funcexpr))) end @@ -44,7 +62,7 @@ macro nsplat(itersym, args...) varname, T = get_splatinfo(prototype, itersym) isempty(varname) && error("Last argument must be a splat") prototype, body = _nsplat(prototype, body, varname, T, itersym) - esc(Expr(:block, # :(Base.depwarn("@nsplat is deprecated, using inlining instead", Symbol("@nsplat"))), + esc(Expr(:block, depwarn_ex("@nsplat is deprecated, using inlining instead", "@nsplat"), Expr(:stagedfunction, prototype, body))) end @@ -121,3 +139,34 @@ end sreplace!(s::Symbol, sym, val) = s == sym ? val : s end + +using .CompatCartesian +export @ngenerate, @nsplat + +export @functorize +macro functorize(f) + code = f === :scalarmax ? :(Base.scalarmax) : + f === :scalarmin ? :(Base.scalarmin) : + f === :centralizedabs2fun ? :(primarytype(typeof(Base.centralizedabs2fun(0)))) : + f + warning = depwarn_ex("@functorize is deprecated as functor objects are no longer supported in julia", "@functorize") + return quote + $warning + $code + end +end + +if VERSION >= v"0.6.0" + Base.@deprecate_binding KERNEL Sys.KERNEL + Base.@deprecate_binding UTF8String Core.String + Base.@deprecate_binding ASCIIString Core.String +else + const KERNEL = Sys.KERNEL + const UTF8String = Core.String + const ASCIIString = Core.String +end + +# More things that could be removed in Compat.jl +# - new_style_call_overload +# - import Base.Filesystem +# - import Base.LinAlg.BLAS.@blasfunc diff --git a/src/to-be-deprecated.jl b/src/to-be-deprecated.jl deleted file mode 100644 index e7767d7d6..000000000 --- a/src/to-be-deprecated.jl +++ /dev/null @@ -1,18 +0,0 @@ -# Uncomment the depwarns when we drop 0.4 support -# See also ngenerate.jl. - -macro Dict(pairs...) - esc(Expr(:block, # :(Base.depwarn("@Dict is deprecated, use Dict instead", Symbol("@Dict"))), - Expr(:call, :Dict, pairs...))) -end -macro AnyDict(pairs...) - esc(Expr(:block, # :(Base.depwarn("@AnyDict is deprecated, use Dict{Any,Any} instead", - # Symbol("@AnyDict"))), - Expr(:call, :(Base.AnyDict), pairs...))) -end - -if VERSION >= v"0.4.0-dev+3184" - include("ngenerate.jl") - using .CompatCartesian - export @ngenerate, @nsplat -end diff --git a/test/to-be-deprecated.jl b/test/deprecated.jl similarity index 82% rename from test/to-be-deprecated.jl rename to test/deprecated.jl index 7e2762a25..32ba79f8f 100644 --- a/test/to-be-deprecated.jl +++ b/test/deprecated.jl @@ -59,3 +59,17 @@ end @test CartesianTest.f(1,2,3) == (1,2,3) @test CartesianTest.f(1,2,3,4) == (1,2,3,4) @test CartesianTest.f(1,2,3,4,5) == (1,2,3,4,5) + +@test Compat.KERNEL == Sys.KERNEL + +@test String == @compat(Union{Compat.UTF8String,Compat.ASCIIString}) + +let x = fill!(StringVector(5), 0x61) + @test pointer(x) == pointer(Compat.UTF8String(x)) +end + +foostring(::String) = 1 +@test foostring("hello") == 1 +@test foostring("λ") == 1 +@test isa("hello", Compat.ASCIIString) +@test isa("λ", Compat.UTF8String) diff --git a/test/runtests.jl b/test/runtests.jl index 116780b9a..5b86d7e2e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -670,10 +670,10 @@ mktempdir() do dir for text in [ old_text, - convert(Compat.UTF8String, Char['A' + i % 52 for i in 1:(div(SZ_UNBUFFERED_IO,2))]), - convert(Compat.UTF8String, Char['A' + i % 52 for i in 1:( SZ_UNBUFFERED_IO -1)]), - convert(Compat.UTF8String, Char['A' + i % 52 for i in 1:( SZ_UNBUFFERED_IO )]), - convert(Compat.UTF8String, Char['A' + i % 52 for i in 1:( SZ_UNBUFFERED_IO +1)]) + convert(String, Char['A' + i % 52 for i in 1:(div(SZ_UNBUFFERED_IO,2))]), + convert(String, Char['A' + i % 52 for i in 1:( SZ_UNBUFFERED_IO -1)]), + convert(String, Char['A' + i % 52 for i in 1:( SZ_UNBUFFERED_IO )]), + convert(String, Char['A' + i % 52 for i in 1:( SZ_UNBUFFERED_IO +1)]) ] write(filename, text) @@ -1177,12 +1177,6 @@ if VERSION ≥ v"0.4.0-dev+3732" @test Symbol(1) === Symbol("1") end -foostring(::String) = 1 -@test foostring("hello") == 1 -@test foostring("λ") == 1 -@test isa("hello", Compat.ASCIIString) -@test isa("λ", Compat.UTF8String) - let async, c = false run = Condition() async = Compat.AsyncCondition(x->(c = true; notify(run))) @@ -1223,27 +1217,12 @@ let io = IOBuffer(), s = "hello" @test unsafe_string(pointer(s),sizeof(s)) == s @test string(s, s, s) == "hellohellohello" @test @compat(String(s)) == s - @test String == @compat(Union{Compat.UTF8String,Compat.ASCIIString}) end @test Compat.repeat(1:2, inner=2) == [1, 1, 2, 2] @test Compat.repeat(1:2, outer=[2]) == [1, 2, 1, 2] @test Compat.repeat([1,2], inner=(2,)) == [1, 1, 2, 2] -if VERSION < v"0.5.0-dev+4267" - if OS_NAME == :Windows - @test is_windows() - elseif OS_NAME == :Darwin - @test is_apple() && is_bsd() && is_unix() - elseif OS_NAME == :FreeBSD - @test is_bsd() && is_unix() - elseif OS_NAME == :Linux - @test is_linux() && is_unix() - end -else - @test Compat.KERNEL == Sys.KERNEL -end - io = IOBuffer() @test @compat(get(io, :limit, false)) == false @test @compat(get(io, :compact, false)) == false @@ -1839,10 +1818,6 @@ using Compat: StringVector @test length(StringVector(5)) == 5 @test String(fill!(StringVector(5), 0x61)) == "aaaaa" -let x = fill!(StringVector(5), 0x61) - @test pointer(x) == pointer(Compat.UTF8String(x)) -end - # collect if VERSION >= v"0.5.0-rc1+46" using OffsetArrays @@ -1893,6 +1868,6 @@ let @test_throws MethodError Dates.Month(1) < Dates.Day(1) end -include("to-be-deprecated.jl") +include("deprecated.jl") nothing