Current section
4 Versions
Jump to
Current section
4 Versions
Compare versions
3
files changed
+111
additions
-17
deletions
| @@ -1,5 +1,5 @@ | |
| 1 1 | {<<"name">>,<<"ast_walk">>}. |
| 2 | - {<<"version">>,<<"0.2.0">>}. |
| 2 | + {<<"version">>,<<"0.3.0">>}. |
| 3 3 | {<<"requirements">>,#{}}. |
| 4 4 | {<<"app">>,<<"ast_walk">>}. |
| 5 5 | {<<"maintainers">>,[<<"Mariano Guerra">>]}. |
| @@ -1,6 +1,6 @@ | |
| 1 1 | {application,ast_walk, |
| 2 2 | [{description,"An Erlang library to walk the Erlang AST with the ability to mutate it and keep state during transversal"}, |
| 3 | - {vsn,"0.2.0"}, |
| 3 | + {vsn,"0.3.0"}, |
| 4 4 | {registered,[]}, |
| 5 5 | {applications,[kernel,stdlib]}, |
| 6 6 | {env,[]}, |
| @@ -9,6 +9,14 @@ | |
| 9 9 | %% all the error cases must be handled otherwise this module just crashes! |
| 10 10 | |
| 11 11 | -export([walk/3, expr/3, exprs/3, forms/3, form/3]). |
| 12 | + -export([id_walker/2, print_walker/2]). |
| 13 | + |
| 14 | + id_walker(State, Node) -> |
| 15 | + {Node, State}. |
| 16 | + |
| 17 | + print_walker(State, Node) -> |
| 18 | + io:format("~p~n~n", [Node]), |
| 19 | + {Node, State}. |
| 12 20 | |
| 13 21 | walk(Forms, Fun, State) -> |
| 14 22 | forms(Forms, Fun, State). |
| @@ -82,23 +90,24 @@ record_defs([Node={record_field, _Line, {atom, _La, _A}}|Is], Fun, State) -> | |
| 82 90 | {T, State2} = record_defs(Is, Fun, State1), |
| 83 91 | {[R|T], State2}; |
| 84 92 | |
| 85 | - % added from 19.2 |
| 86 | - record_defs([Node={typed_record_field, |
| 87 | - {record_field, _Line, {atom, _La, _A}, _Val0}, _Type0}|Is], Fun, State) -> |
| 88 | - % TODO: support expr and type |
| 89 | - %{Val1, State1} = expr(Val0, Fun, State), |
| 90 | - %{Type1, State2} = type(Type0, Fun, State1), |
| 91 | - {R, State3} = Fun(State, Node), |
| 93 | + record_defs([{typed_record_field, |
| 94 | + {record_field, Line, {atom, La, A}, Val0}, Type}|Is], |
| 95 | + Fun, State) -> |
| 96 | + {Val1, State1} = expr(Val0, Fun, State), |
| 97 | + {Type1, State2} = type(Type, Fun, State1), |
| 98 | + Node1 = {typed_record_field, {record_field, Line, {atom, La, A}, Val1}, Type1}, |
| 99 | + {Node2, State3} = Fun(State2, Node1), |
| 92 100 | {T, State4} = record_defs(Is, Fun, State3), |
| 93 | - {[R|T], State4}; |
| 101 | + {[Node2|T], State4}; |
| 94 102 | |
| 95 | - record_defs([Node={typed_record_field, |
| 96 | - {record_field, _Line, {atom, _La, _A}}, _Type0}|Is], Fun, State) -> |
| 97 | - % TODO: support expr and type |
| 98 | - %{Type1, State2} = type(Type0, Fun, State), |
| 99 | - {R, State3} = Fun(State, Node), |
| 100 | - {T, State4} = record_defs(Is, Fun, State3), |
| 101 | - {[R|T], State4}; |
| 103 | + record_defs([{typed_record_field, |
| 104 | + {record_field, Line, {atom, La, A}}, Type}|Is], |
| 105 | + Fun, State) -> |
| 106 | + {Type1, State1} = type(Type, Fun, State), |
| 107 | + Node1 = {typed_record_field, {record_field, Line, {atom, La, A}}, Type1}, |
| 108 | + {Node2, State2} = Fun(State1, Node1), |
| 109 | + {T, State3} = record_defs(Is, Fun, State2), |
| 110 | + {[Node2|T], State3}; |
| 102 111 | |
| 103 112 | record_defs([], _Fun, State) -> {[], State}. |
| 104 113 | |
| @@ -610,3 +619,88 @@ fun_clauses([C0|Cs], Fun, State) -> | |
| 610 619 | {T, State2} = fun_clauses(Cs, Fun, State1), |
| 611 620 | {[C1|T], State2}; |
| 612 621 | fun_clauses([], _Fun, State) -> {[], State}. |
| 622 | + |
| 623 | + type({ann_type,Line,[{var,Lv,V},T]}, Fun, State) -> |
| 624 | + {T1, State1} = type(T, Fun, State), |
| 625 | + Fun(State1, {ann_type,Line,[{var,Lv,V},T1]}); |
| 626 | + type({atom,Line,A}, Fun, State) -> |
| 627 | + Fun(State, {atom,Line,A}); |
| 628 | + type({integer,Line,I}, Fun, State) -> |
| 629 | + Fun(State, {integer,Line,I}); |
| 630 | + type({op,Line,Op,T}, Fun, State) -> |
| 631 | + {T1, State1} = type(T, Fun, State), |
| 632 | + Fun(State1, {op,Line,Op,T1}); |
| 633 | + type({op,Line,Op,L,R}, Fun, State) -> |
| 634 | + {L1, State1} = type(L, Fun, State), |
| 635 | + {R1, State2} = type(R, Fun, State1), |
| 636 | + Fun(State2, {op,Line,Op,L1,R1}); |
| 637 | + type({type,Line,binary,[M,N]}, Fun, State) -> |
| 638 | + {M1, State1} = type(M, Fun, State), |
| 639 | + {N1, State2} = type(N, Fun, State1), |
| 640 | + Fun(State2, {type,Line,binary,[M1,N1]}); |
| 641 | + type({type,Line,'fun',[]}, Fun, State) -> |
| 642 | + Fun(State, {type,Line,'fun',[]}); |
| 643 | + type({type,Line,'fun',[{type,Lt,any},B]}, Fun, State) -> |
| 644 | + {B1, State1} = type(B, Fun, State), |
| 645 | + Fun(State1, {type,Line,'fun',[{type,Lt,any},B1]}); |
| 646 | + type({type,Line,range,[L,H]}, Fun, State) -> |
| 647 | + {L1, State1} = type(L, Fun, State), |
| 648 | + {H1, State2} = type(H, Fun, State1), |
| 649 | + Fun(State2, {type,Line,range,[L1,H1]}); |
| 650 | + type({type,Line,map,any}, Fun, State) -> |
| 651 | + Fun(State, {type,Line,map,any}); |
| 652 | + type({type,Line,map,Ps}, Fun, State) -> |
| 653 | + {Ps1, State1} = map_pair_types(Ps, Fun, State), |
| 654 | + Fun(State1, {type,Line,map,Ps1}); |
| 655 | + type({type,Line,record,[{atom,La,N}|Fs]}, Fun, State) -> |
| 656 | + {Fs1, State1} = field_types(Fs, Fun, State), |
| 657 | + Fun(State1, {type,Line,record,[{atom,La,N}|Fs1]}); |
| 658 | + type({remote_type,Line,[{atom,Lm,M},{atom,Ln,N},As]}, Fun, State) -> |
| 659 | + {As1, State1} = type_list(As, Fun, State), |
| 660 | + Fun(State1, {remote_type,Line,[{atom,Lm,M},{atom,Ln,N},As1]}); |
| 661 | + type({type,Line,tuple,any}, Fun, State) -> |
| 662 | + Fun(State, {type,Line,tuple,any}); |
| 663 | + type({type,Line,tuple,Ts}, Fun, State) -> |
| 664 | + {Ts1, State1} = type_list(Ts, Fun, State), |
| 665 | + Fun(State1, {type,Line,tuple,Ts1}); |
| 666 | + type({type,Line,union,Ts}, Fun, State) -> |
| 667 | + {Ts1, State1} = type_list(Ts, Fun, State), |
| 668 | + Fun(State1, {type,Line,union,Ts1}); |
| 669 | + type({var,Line,V}, Fun, State) -> |
| 670 | + Fun(State, {var,Line,V}); |
| 671 | + type({user_type,Line,N,As}, Fun, State) -> |
| 672 | + {As1, State1} = type_list(As, Fun, State), |
| 673 | + Fun(State1, {user_type,Line,N,As1}); |
| 674 | + type({type,Line,N,As}, Fun, State) -> |
| 675 | + {As1, State1} = type_list(As, Fun, State), |
| 676 | + Fun(State1, {type,Line,N,As1}). |
| 677 | + |
| 678 | + map_pair_types([{type,Line,map_field_assoc,[K,V]}|Ps], Fun, State) -> |
| 679 | + {K1, State1} = type(K, Fun, State), |
| 680 | + {V1, State2} = type(V, Fun, State1), |
| 681 | + H = {type,Line,map_field_assoc,[K1,V1]}, |
| 682 | + {T, State3} = map_pair_types(Ps, Fun, State2), |
| 683 | + {[H|T], State3}; |
| 684 | + |
| 685 | + map_pair_types([{type,Line,map_field_exact,[K,V]}|Ps], Fun, State) -> |
| 686 | + {K1, State1} = type(K, Fun, State), |
| 687 | + {V1, State2} = type(V, Fun, State1), |
| 688 | + H = {type,Line,map_field_exact,[K1,V1]}, |
| 689 | + {T, State3} = map_pair_types(Ps, Fun, State2), |
| 690 | + {[H|T], State3}; |
| 691 | + |
| 692 | + map_pair_types([], _Fun, State) -> {[], State}. |
| 693 | + |
| 694 | + field_types([{type,Line,field_type,[{atom,La,A},T]}|Fs], Fun, State) -> |
| 695 | + {T1, State1} = type(T, Fun, State), |
| 696 | + H = {type,Line,field_type,[{atom,La,A},T1]}, |
| 697 | + {Tail, State2} = field_types(Fs, Fun, State1), |
| 698 | + {[H|Tail], State2}; |
| 699 | + |
| 700 | + field_types([], _Fun, State) -> {[], State}. |
| 701 | + |
| 702 | + type_list([T|Ts], Fun, State) -> |
| 703 | + {T1, State1} = type(T, Fun, State), |
| 704 | + {Ts1, State2} = type_list(Ts, Fun, State1), |
| 705 | + {[T1|Ts1], State2}; |
| 706 | + type_list([], _Fun, State) -> {[], State}. |