@@ -1966,42 +1966,95 @@ defmodule Macro do
1966
1966
1967
1967
def quoted_literal? ( { :%{} , _ , args } ) , do: quoted_literal? ( args )
1968
1968
def quoted_literal? ( { :{} , _ , args } ) , do: quoted_literal? ( args )
1969
+ def quoted_literal? ( { :__MODULE__ , _ , ctx } ) when is_atom ( ctx ) , do: true
1969
1970
def quoted_literal? ( { left , right } ) , do: quoted_literal? ( left ) and quoted_literal? ( right )
1970
1971
def quoted_literal? ( list ) when is_list ( list ) , do: :lists . all ( & quoted_literal? / 1 , list )
1971
1972
def quoted_literal? ( term ) , do: is_atom ( term ) or is_number ( term ) or is_binary ( term )
1972
1973
1973
- @ doc """
1974
- Expands the `ast` representing a quoted literal within the given `env`.
1974
+ @ doc false
1975
+ @ deprecated "Use Macro.expand_literals/2 instead"
1976
+ def expand_literal ( ast , env ) do
1977
+ expand_literals ( ast , env )
1978
+ end
1975
1979
1976
- This function checks if the given AST represents a quoted literal
1977
- (using `quoted_literal?/1`) and then expands all relevant nodes.
1978
- If a literal node is not given, then it returns the AST as is.
1979
- At the moment, the only expandable literal nodes in an AST are
1980
- aliases, so this function only expands aliases.
1980
+ @ doc """
1981
+ Expands all literals in `ast` with the given `env`.
1981
1982
1982
1983
This function is mostly used to remove compile-time dependencies
1983
1984
from AST nodes. In such cases, the given environment is usually
1984
- manipulate to represent a function:
1985
+ manipulated to represent a function:
1985
1986
1986
- Macro.expand_literal(ast, %{env | function: {:my_code, 1}})
1987
+ Macro.expand_literals(ast, %{env | function: {:my_code, 1}})
1988
+
1989
+ At the moment, the only expandable literal nodes in an AST are
1990
+ aliases, so this function only expands aliases.
1987
1991
1988
1992
However, be careful when removing compile-time dependencies between
1989
1993
modules. If you remove them but you still invoke the module at
1990
- compile-time, you may end-up with broken behaviour.
1994
+ compile-time, Elixir will be unable to properly recompile modules
1995
+ when they change.
1991
1996
"""
1992
- @ doc since: "1.14.0"
1993
- @ spec expand_literal ( t ( ) , Macro.Env . t ( ) ) :: t ( )
1994
- def expand_literal ( ast , env ) do
1995
- if quoted_literal? ( ast ) do
1996
- prewalk ( ast , fn
1997
- { :__aliases__ , _ , _ } = alias -> expand ( alias , env )
1998
- other -> other
1999
- end )
1997
+ @ doc since: "1.14.1"
1998
+ @ spec expand_literals ( t ( ) , Macro.Env . t ( ) ) :: t ( )
1999
+ def expand_literals ( ast , env ) do
2000
+ { ast , :ok } = expand_literals ( ast , :ok , fn node , :ok -> { expand ( node , env ) , :ok } end )
2001
+ ast
2002
+ end
2003
+
2004
+ @ doc """
2005
+ Expands all literals in `ast` with the given `acc` and `fun`.
2006
+
2007
+ `fun` will be invoked with an expandable AST node and `acc` and
2008
+ must return a new node with `acc`. This is a general version of
2009
+ `expand_literals/2` which supports a custom expansion function.
2010
+ Please check `expand_literals/2` for use cases and pitfalls.
2011
+ """
2012
+ @ doc since: "1.14.1"
2013
+ @ spec expand_literals ( t ( ) , acc , ( t ( ) , acc -> { t ( ) , acc } ) ) :: t ( ) when acc: term ( )
2014
+ def expand_literals ( ast , acc , fun )
2015
+
2016
+ def expand_literals ( { :__aliases__ , meta , args } , acc , fun ) do
2017
+ { args , acc } = expand_literals ( args , acc , fun )
2018
+
2019
+ if :lists . all ( & is_atom / 1 , args ) do
2020
+ fun . ( { :__aliases__ , meta , args } , acc )
2000
2021
else
2001
- ast
2022
+ { { :__aliases__ , meta , args } , acc }
2002
2023
end
2003
2024
end
2004
2025
2026
+ def expand_literals ( { :__MODULE__ , _meta , ctx } = node , acc , fun ) when is_atom ( ctx ) do
2027
+ fun . ( node , acc )
2028
+ end
2029
+
2030
+ def expand_literals ( { :% , meta , [ left , right ] } , acc , fun ) do
2031
+ { left , acc } = expand_literals ( left , acc , fun )
2032
+ { right , acc } = expand_literals ( right , acc , fun )
2033
+ { { :% , meta , [ left , right ] } , acc }
2034
+ end
2035
+
2036
+ def expand_literals ( { :%{} , meta , args } , acc , fun ) do
2037
+ { args , acc } = expand_literals ( args , acc , fun )
2038
+ { { :%{} , meta , args } , acc }
2039
+ end
2040
+
2041
+ def expand_literals ( { :{} , meta , args } , acc , fun ) do
2042
+ { args , acc } = expand_literals ( args , acc , fun )
2043
+ { { :{} , meta , args } , acc }
2044
+ end
2045
+
2046
+ def expand_literals ( { left , right } , acc , fun ) do
2047
+ { left , acc } = expand_literals ( left , acc , fun )
2048
+ { right , acc } = expand_literals ( right , acc , fun )
2049
+ { { left , right } , acc }
2050
+ end
2051
+
2052
+ def expand_literals ( list , acc , fun ) when is_list ( list ) do
2053
+ :lists . mapfoldl ( & expand_literals ( & 1 , & 2 , fun ) , acc , list )
2054
+ end
2055
+
2056
+ def expand_literals ( term , acc , _fun ) , do: { term , acc }
2057
+
2005
2058
@ doc """
2006
2059
Receives an AST node and expands it until it can no longer
2007
2060
be expanded.
0 commit comments