liufengyun / gestalt

gestalt : portable and solid macros for Scala

Home Page:https://github.com/scalacenter/macros

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Deal with attachments of trees

liufengyun opened this issue · comments

The extractor-approach doesn't do conversion of trees, thus attachments are not an issue most of the time.

However, if the macro writer destrcuts object A { ... }, adds a method and construct the tree again, the attachments on the original tree are lost (because the original tree is thrown away).

We should provide something like copy so that attachments on the destructed tree are not affected. Macro writers should be fully-aware of the danger of losing attachments if a tree is destructed into parts and built from parts again.

Any ideas @valdisxp1 ?

I see three reasonable solutions:

  1. create a copy a newly created tree, then adds the same attachments as src has.
// in Tree type
def withAttachmentsFrom(src: Tree): Tree
  1. Tree.attachments: Attachments gives a "sealed box" of Attachments, and Tree.withAttachments(Attachments): Tree
// in Tree type
def attachments: Attachments
def withAttachments(a:Attachments): Tree
  1. For every attachment A that a macro user may want to preserver. Provide an extractor and a with setter. Add attachments as needed.
//example: DocComment
object DocComment{
 def unapply(tree: Tree): Option[String]
}
def WithDocComment(tree: Tree,  comment: String): Tree

Is preserving all the attachments always good? Probably keeping ScalaDocs is ok (i.e. dotty.tools.dotc.ast.Trees#DocComment), but there might be attachments that may become invalid after transformation.
For example, a hypothetical attachment: FunctionallyPure. If the macro writer adds a side effect then some optimization could break the code. If this is done quietly then the macro writer has no clue what did he do wrong.

Also position is similar in some ways and is something that might also be something worth preserving somehow.

@valdisxp1 thanks for the inspiring ideas, all of them look interesting 👍

By attachments, I mean all possible info on trees, might they be positions, docs, types and any other things that a compiler implementation may attach to a tree. As you mentioned, keeping some attachments may not make sense.

Only the specific toolbox implementor has the knowledge of what attachments there are and which should be maintained. The macro writers don't have the knowledge, as different compilers may have different set of copy-overs.

I prefer the first idea, but I'm cautious about assuming a specific method on the trees, and I'm thinking of remove the def tpe: Type assumption on trees. Maybe we can put the method in StructToolbox instead of Tree?

This issue now is addressed by providing a copy method in DefTree representors -- which is the recommended approach to deal with definition trees attributed with attachments.