You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hey, thanks for the library, I was experimenting with zippers and so far experience is great.
I have a question/comment regarding guide about expanding aliases.
From my understanding, the do is represented Sourceror AST in two ways:
# I removed the metadata for nodesaliases={:__aliases__,[],[:A]}defblock(children)do{:__block__,[],children}endsingle_do_block={block([:do]),block([4])}single_literal_module={:defmodule,[],[aliases,single_do_block]}multi_do_block={block([:do]),block([block([4]),block([4])])}multi_literal_module={:defmodule,[],[aliases,multi_do_block]}
That is: when do block has only single child - it doesn't wrap it in the block and just stores it directly in the {do_atom, do_content} tuple representing do block.
In the tutorial we assume that we're in the block: we're adding siblings to the current node and then removing grouped alias node. This produces wrong AST when we're expanding single alias:
# removed comment handling codedefmoduleAliasExpansiondoaliasSourceror.Zipper,as: Zdefexpand_aliases(quoted)doZ.zip(quoted)|>Z.traverse(&expand_alias/1)|>Z.root()enddefpexpand_alias({{:alias,_,[{{:.,_,[left,:{}]},_,right}]},_metadata}=zipper)do{_,_,base_segments}=leftright|>Enum.map(&segments_to_alias(base_segments,&1))# we insert expanded aliases in reverse because insert_right doesn't move the zipper|>Enum.reverse()|>Enum.reduce(zipper,&Z.insert_right(&2,&1))# remove the grouped alias|>Z.remove()enddefpexpand_alias(zipper),do: zipperdefpsegments_to_alias(base_segments,{_,meta,segments})do{:alias,meta,[{:__aliases__,[],base_segments++segments}]}endend~S"""defmodule A do alias A.{B,C}end"""|>Sourceror.parse_string!()|>AliasExpansion.expand_aliases()
I changed the code to replace grouped alias node to block and then inline if necessary:
defmoduleAliasExpansiondoaliasSourceror.Zipperdefexpand_aliases(quoted)doquoted|>Zipper.zip()|>Zipper.traverse(&expand_grouped_alias/1)|>Zipper.root()enddefpexpand_grouped_alias({{:alias,_alias_meta,[{{:.,_,[module_prefix,:{}]},_call_meta,module_suffix}]},_metadata}=zipper)do{:__aliases__,_meta,base_module_part}=module_prefixmodule_suffix|>Enum.map(&expand_alias(base_module_part,&1))|>Enum.reverse()# insert expanded aliases. insert_right doesn't move zipper, so we add them in reverse|>Enum.reduce(replace_with_block(zipper),&Zipper.append_child(&2,&1))|>inline_if_single_child()enddefpexpand_grouped_alias(zipper),do: zipperdefpexpand_alias(base,{:__aliases__,meta,grouped_part})dofull={:__aliases__,[],base++grouped_part}{:alias,meta,[full]}enddefpreplace_with_block(zipper)doZipper.replace(zipper,{:__block__,[trailing_comments: [],leading_comments: []],[]})enddefpinline_if_single_child(zipper)docaseZipper.children(zipper)do[tree]->Zipper.replace(zipper,tree)_children->zipperendendendaliasSourceror.Zipper~S"""defmodule A do alias A.{B, C}end"""|>Sourceror.parse_string!()|>AliasExpansion.expand_aliases()|>Sourceror.to_string()|>IO.puts()
EDIT: I noticed that new code doesn't merge generated blocks. This results in parens between alias groups ¯\(ツ)/¯
My question is:
Should Zipper support this special case (in Zipper.remove, insert_*, etc) or should we handle it ourselves?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hey, thanks for the library, I was experimenting with zippers and so far experience is great.
I have a question/comment regarding guide about expanding aliases.
From my understanding, the
do
is represented Sourceror AST in two ways:That is: when
do
block has only single child - it doesn't wrap it in theblock
and just stores it directly in the{do_atom, do_content}
tuple representingdo
block.In the tutorial we assume that we're in the block: we're adding siblings to the current node and then removing grouped alias node. This produces wrong AST when we're expanding single alias:
Output:
When the correct output is:
I changed the code to replace grouped alias node to block and then inline if necessary:
EDIT: I noticed that new code doesn't merge generated blocks. This results in parens between alias groups ¯\(ツ)/¯
My question is:
Should Zipper support this special case (in
Zipper.remove
,insert_*
, etc) or should we handle it ourselves?Beta Was this translation helpful? Give feedback.
All reactions