@@ -1425,39 +1425,36 @@ if Version.match?(System.version(), ">= 1.17.0-dev") do
14251425 end
14261426 end
14271427
1428- defp expand_macro ( _meta , Kernel , type , [ { name , _ , params } , [ { _ , block } ] ] , _callback , state , env )
1429- when type in [ :def , :defp ] and is_tuple ( block ) and is_atom ( name ) and is_list ( params ) do
1430- { _ , state , penv } =
1431- for p <- params , reduce: { nil , state , env } do
1432- { _ , state , penv } ->
1433- expand_pattern ( p , state , penv )
1428+ defp expand_macro ( _meta , Kernel , type , args , _callback , state , env )
1429+ when type in [ :def , :defmacro , :defp , :defmacrop ] do
1430+ # extract the name, params, guards, and blocks
1431+ { name , params , guards , blocks } =
1432+ case args do
1433+ [ { :when , _ , [ { name , _ , params } | guards ] } | maybe_blocks ] ->
1434+ { name , params , guards , maybe_blocks }
1435+
1436+ [ { name , _ , params } | maybe_blocks ] ->
1437+ { name , params , [ ] , maybe_blocks }
14341438 end
14351439
1436- { res , state , _env } = expand ( block , state , penv )
1437-
1438- arity = length ( List . wrap ( params ) )
1439- functions = Map . update ( state . functions , env . module , [ { name , arity } ] , & Keyword . put_new ( & 1 , name , arity ) )
1440- { res , put_in ( state . functions , functions ) , env }
1441- end
1442-
1443- defp expand_macro ( _meta , Kernel , type , [ { name , _ , params } , block ] , _callback , state , env )
1444- when type in [ :defmacro , :defmacrop ] do
1445- { _res , state , penv } = expand ( params , state , env )
1446- { res , state , _env } = expand ( block , state , penv )
1440+ blocks = List . first ( blocks , [ ] )
14471441
1448- arity = length ( List . wrap ( params ) )
1449- macros = Map . update ( state . macros , env . module , [ { name , arity } ] , & Keyword . put_new ( & 1 , name , arity ) )
1450- { res , put_in ( state . macros , macros ) , env }
1451- end
1452-
1453- defp expand_macro ( _meta , Kernel , type , [ { name , _ , params } , blocks ] , _callback , state , env )
1454- when type in [ :def , :defp ] and is_atom ( name ) and is_list ( params ) and is_list ( blocks ) do
1442+ # collect the environment from the parameters
1443+ # parameters are always patterns
14551444 { _ , state , penv } =
14561445 for p <- params , reduce: { nil , state , env } do
14571446 { _ , state , penv } ->
14581447 expand_pattern ( p , state , penv )
14591448 end
14601449
1450+ # expand guards, which includes the env from params
1451+ { _ , state , _ } =
1452+ for guard <- guards , reduce: { nil , state , penv } do
1453+ { _ , state , env } ->
1454+ expand ( guard , state , env )
1455+ end
1456+
1457+ # expand the blocks, there could be `:do`, `:after`, `:catch`, etc
14611458 { blocks , state } =
14621459 for { type , block } <- blocks , reduce: { [ ] , state } do
14631460 { acc , state } ->
@@ -1467,26 +1464,21 @@ if Version.match?(System.version(), ">= 1.17.0-dev") do
14671464
14681465 arity = length ( List . wrap ( params ) )
14691466
1470- functions = Map . update ( state . functions , env . module , [ { name , arity } ] , & Keyword . put_new ( & 1 , name , arity ) )
1471- { Enum . reverse ( blocks ) , put_in ( state . functions , functions ) , env }
1472- end
1473-
1474- defp expand_macro ( _meta , Kernel , type , [ { _name , _ , params } , blocks ] , _callback , state , env )
1475- when type in [ :def , :defp ] and is_list ( params ) and is_list ( blocks ) do
1476- { _ , state , penv } =
1477- for p <- params , reduce: { nil , state , env } do
1478- { _ , state , penv } ->
1479- expand_pattern ( p , state , penv )
1467+ # determine which key to save this function in state
1468+ state_key =
1469+ case type do
1470+ type when type in [ :def , :defp ] -> :functions
1471+ type when type in [ :defmacro , :defmacrop ] -> :macros
14801472 end
14811473
1482- { blocks , state } =
1483- for { type , block } <- blocks , reduce: { [ ] , state } do
1484- { acc , state } ->
1485- { res , state , _env } = expand ( block , state , penv )
1486- { [ { type , res } | acc ] , state }
1474+ funcs =
1475+ if is_atom ( name ) do
1476+ Map . update ( state [ state_key ] , env . module , [ { name , arity } ] , & Keyword . put_new ( & 1 , name , arity ) )
1477+ else
1478+ state [ state_key ]
14871479 end
14881480
1489- { Enum . reverse ( blocks ) , state , env }
1481+ { Enum . reverse ( blocks ) , put_in ( state [ state_key ] , funcs ) , env }
14901482 end
14911483
14921484 defp expand_macro ( meta , Kernel , :@ , [ { name , _ , p } ] = args , callback , state , env ) when is_list ( p ) do
0 commit comments