@@ -16,3 +16,53 @@ _compat(ex) = ex
16
16
macro compat (ex)
17
17
esc (_compat (ex))
18
18
end
19
+
20
+ # Only the import-renaming usage results in multiple arguments.
21
+ # On versions where renaming is supported natively it parses as a
22
+ # single expression and thus takes the single-argument @compat
23
+ # code-path above
24
+ macro compat (ex, exprs... )
25
+ @assert VERSION < v " 1.6.0-DEV.1157"
26
+ if length (exprs) == 2 && Meta. isexpr (ex, :import , 1 ) && Meta. isexpr (ex. args[1 ], :.) &&
27
+ exprs[1 ] === :as && exprs[2 ] isa Symbol
28
+ # Matches "import Module(.Submodule) as a"
29
+ lhs = Symbol[ex. args[1 ]. args... ]
30
+ alias = exprs[2 ]
31
+ return _create_import_expression ([lhs => alias])
32
+ elseif Meta. isexpr (ex, [:import , :using ], 1 ) &&
33
+ Meta. isexpr (ex. args[1 ], :(:)) && length (exprs) % 2 == 0 &&
34
+ all (x -> x === :as , exprs[1 : 2 : end - 1 ]) &&
35
+ all (x -> Meta. isexpr (x, :tuple , 2 ), exprs[2 : 2 : end - 2 ]) &&
36
+ exprs[end ] isa Symbol
37
+ # Matches "(import|using) Module(.Submodule): a as b(, c as d)
38
+ syms = Symbol[ ex. args[1 ]. args[2 ]. args[1 ] ]
39
+ foreach (x -> x isa Symbol ? push! (syms, x) : append! (syms, x. args), exprs[2 : 2 : end ])
40
+
41
+ path_aliases = Pair{Vector{Symbol},Symbol}[]
42
+ init = ex. args[1 ]. args[1 ]. args
43
+ for i in 1 : 2 : length (syms)
44
+ push! (path_aliases, Symbol[init; syms[i]] => syms[i+ 1 ])
45
+ end
46
+ return _create_import_expression (path_aliases)
47
+ else
48
+ throw (ArgumentError (" invalid use of @compat" ))
49
+ end
50
+ end
51
+
52
+ function _create_import_expression (path_aliases:: Vector{Pair{Vector{Symbol}, Symbol}} )
53
+ # Create an gensymd baremodule to hide names in
54
+ s = gensym ()
55
+ # Create all import/const exprs
56
+ import_exprs = Expr[]
57
+ const_exprs = Expr[]
58
+ for (path, alias) in path_aliases
59
+ import_expr = Expr (:import , Expr (:., path... ))
60
+ push! (import_exprs, import_expr)
61
+ rhs_expr = Expr (:escape , Expr (:., s, QuoteNode (last (path))))
62
+ const_expr = Expr (:const , Expr (:global , Expr (:(= ), alias, rhs_expr)))
63
+ push! (const_exprs, const_expr)
64
+ end
65
+ module_expr = Expr (:module , false , Expr (:escape , s), Expr (:block , import_exprs... ))
66
+ return_expr = Expr (:toplevel , module_expr, const_exprs... , nothing )
67
+ return return_expr
68
+ end
0 commit comments