Skip to content

Commit

Permalink
Support import renaming through compat"..." string macro.
Browse files Browse the repository at this point in the history
  • Loading branch information
fredrikekre committed Oct 10, 2020
1 parent 786d0d8 commit 1725126
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "Compat"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.20.0"
version = "3.21.0"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ changes in `julia`.

## Supported features

* Import renaming is available through the `compat"..."` string macro, e.g. `compat"import LinearAlgebra as LA"` and
`compat"import LinearAlgebra: cholesky as c, lu as l"` ([#37396]). (since Compat 3.21).

* `Compat.parseatom(text::AbstractString, pos::Integer; filename="none")` parses a single
atom from `text` starting at index `pos`. Returns a `Tuple` consisting of the
parsed expression and the index to resume parsing from. ([#35243]) (since Compat 3.20)
Expand Down Expand Up @@ -219,3 +222,4 @@ Note that you should specify the correct minimum version for `Compat` in the
[#37559]: https://github.com/JuliaLang/julia/pull/37559
[#29634]: https://github.com/JuliaLang/julia/pull/29634
[#35243]: https://github.com/JuliaLang/julia/pull/35243
[#37396]: https://github.com/JuliaLang/julia/pull/37396
50 changes: 50 additions & 0 deletions src/Compat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,56 @@ else
using .Meta: parseatom, parseall
end

# Import renaming, https://github.com/JuliaLang/julia/pull/37396,
# and https://github.com/JuliaLang/julia/pull/37965
export @compat_str

macro compat_str(str)
return compat_str(str)
end

function compat_str(str)
str = strip(str)
if VERSION >= v"1.6.0-DEV.1157" # TODO: Update this after the macro-bugfix PR
return Meta.parse(str)
end
if (m = match(r"^import\s+([\w\.@]+)\s+as\s+(@?\w+)$", str)) !== nothing
lhs = Symbol.(split(m[1], '.'))
alias = Symbol(m[2])
return _create_expression([lhs => alias])
elseif (m = match(r"^(import|using)\s+([\w\.]+):\s+(.*)$", str)) !== nothing &&
(ms = match.(Ref(r"^(@?\w+)\s+as\s+(@?\w+)$"), strip.(split(m[3], ','))); all(x -> x !== nothing, ms))
path_aliases = Pair{Vector{Symbol},Symbol}[]
for mss in ms
lhs = Symbol.(split(m[2], '.'))
push!(lhs, Symbol(mss[1]))
alias = Symbol(mss[2])
push!(path_aliases, lhs => alias)
end
return _create_expression(path_aliases)
else
throw(ArgumentError("could not parse $(repr(str)) as a valid import statement"))
end
end

function _create_expression(path_aliases::Vector{Pair{Vector{Symbol}, Symbol}})
# Create an gensymd baremodule to hide names in
s = gensym()
# Create all import/const exprs
import_exprs = Expr[]
const_exprs = Expr[]
for (path, alias) in path_aliases
import_expr = Expr(:import, Expr(:., path...))
push!(import_exprs, import_expr)
rhs_expr = Expr(:escape, Expr(:., s, QuoteNode(last(path))))
const_expr = Expr(:const, Expr(:global, Expr(:(=), alias, rhs_expr)))
push!(const_exprs, const_expr)
end
module_expr = Expr(:module, false, Expr(:escape, s), Expr(:block, import_exprs...))
return_expr = Expr(:toplevel, module_expr, const_exprs..., nothing)
return return_expr
end

include("iterators.jl")
include("deprecated.jl")

Expand Down
36 changes: 35 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -753,4 +753,38 @@ end

include("iterators.jl")

nothing
# Import renaming, https://github.com/JuliaLang/julia/pull/37396,
# and https://github.com/JuliaLang/julia/pull/37965
module ImportRename
using Compat
compat"import LinearAlgebra as LA"
compat"import LinearAlgebra.BLAS as BL"
compat"import LinearAlgebra.BLAS: dotc as dc"
compat"import LinearAlgebra: cholesky as chol, lu as lufact"
compat"using LinearAlgebra.BLAS: hemm as hm"
compat"import Base.Cartesian: @nloops as @nl"
compat"import Base.Cartesian.@ntuple as @nt"
compat"using Base.Cartesian: @nexprs as @ne"
end

import .ImportRename
import LinearAlgebra

@testset "import renaming" begin
@test ImportRename.LA === LinearAlgebra
@test !isdefined(ImportRename, :LinearAlgebra)
@test ImportRename.BL === LinearAlgebra.BLAS
@test !isdefined(ImportRename, :BLAS)
@test ImportRename.dc === LinearAlgebra.BLAS.dotc
@test !isdefined(ImportRename, :dotc)
@test ImportRename.chol === LinearAlgebra.cholesky
@test ImportRename.lufact === LinearAlgebra.lu
@test ImportRename.hm === LinearAlgebra.BLAS.hemm
@test !isdefined(ImportRename, :hemm)
@test isdefined(ImportRename, Symbol("@nl"))
@test !isdefined(ImportRename, Symbol("@nloops"))
@test isdefined(ImportRename, Symbol("@nt"))
@test !isdefined(ImportRename, Symbol("@ntuple"))
@test isdefined(ImportRename, Symbol("@ne"))
@test !isdefined(ImportRename, Symbol("@nexprs"))
end

0 comments on commit 1725126

Please sign in to comment.