Packages

An Erlang library to walk the Erlang AST with the ability to mutate it and keep state during transversal

Current section

4 Versions

Jump to

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}.