I use a macro annotation to add a method to a class based on code introspection in another method of this class. I extract the method's syntax tree from the class definition, but within the method the identifiers of the terms and types are not expanded. These identifiers do not yet contain information about imports, other definitions within the class, and implicit conversions.
import geo.model.meta.src.state.IStateCoding
import java.util.{Collection ⇒ JCollection}
import scala.collection.JavaConverters._
@IntrospectionGenerator
class IntrospectionTest(
val a:Int,
val b:String,
map:ConcurrentHashMap[String, JCollection[String]]
){
def inrospectionTarget: IntrospectionTest = {
val map = new ConcurrentHashMap[String, JCollection[String]]()
map.put("some", Seq("bar").asJava)
new IntrospectionTest(a, b, map)
}
}
//Macros definition example
@compileTimeOnly("enable macro paradise to expand macro annotations")
class IntrospectionGenerator extends StaticAnnotation{
def macroTransform(annottees: Any*): Any = macro IntrospectionGenerator.impl
}
object IntrospectionGenerator {
def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
annottees.map(_.tree) match{
case (cls @ ClassDef(modifiers, className, typeDefs, template)) :: Nil⇒
val nonInferedContent = template.body.collectFirst{
case DefDef(_, TermName("copyState"), Nil, Nil, _, content) ⇒
content
}.get
val idents = nonInferedContent.collect{
case iden @ Ident(name) ⇒
idents //HOW TO GET SYMBOL FOR THIS IDENTIFIER?
}.flatten
val generatedMethod = q"override def copyStateSource = $someStructure"
val extTemplate = Template(
template.parents,
template.self,
template.body ::: generatedMethod :: Nil
)
c.Expr(ClassDef(modifiers, className, typeDefs, extTemplate))
case _ ⇒
c.abort(c.enclosingPosition, "incorrect use of StateCodingMacro")
}
}
}
1) How can I manually create a context (BlackBox) for a method in the context of a class so that this context knows all the definitions within the class?
2) How can I get the definition of some identifier (full qualified name of Class or method) inside the AST of method without a common typeCheck call? I want to preserve the original tree structure, but at the same time understand what the identifiers of terms and types in this tree refer to. Examples of identifiers from the above code: JCollection, asJava, a, b, map, IntrospectionTest.