如何注入准引号数组

时间:2015-08-20 16:49:57

标签: scala abstract-syntax-tree scala-quasiquotes

我有一个名为definitions的准引号数组,我想将它引入准引号tree。我该怎么做呢?

private def generateDaoComponent(files: Array[File]) = {
    val file = createNewFile(compDirectory)

    val definitions = files.map(f => {
      val daoName = f.getName.replace(".java", "")
      val daoType = TypeName(daoName)
      val daoTerm = TermName(daoName)

      q"""def $daoTerm = getValueOrInstantiate($daoName, () => new $daoType(configuration))


       """
    })

    val tree = q"""
        package database.dao {
          import org.jooq.SQLDialect
          import org.jooq.impl.DefaultConfiguration
          import utility.StrongHashMap

          trait $componentType extends StrongHashMap[String, Dao] {
            this: DaoManager =>

            private lazy val configuration = new DefaultConfiguration().set(connection).set(SQLDialect.POSTGRES_9_4)

            ${definitions.foreach(f => q"${f}")}
          }
        }"""

    writeToFile(file, tree)
  }

1 个答案:

答案 0 :(得分:1)

这是一些疯狂的深夜编码,但我发现它归功于这个网站

3 approaches to Scala code generation

我注意到它将$params数组传递给准引号时,它在类构造函数前面使用了两个..,如下所示:

    val params = schema.fields.map { field =>
      val fieldName = newTermName(field.name)
      val fieldType = newTypeName(field.valueType.fullName)
      q"val $fieldName: $fieldType"
    }

    val json = TypeSchema.toJson(schema)

    // rewrite the class definition
    c.Expr(
      q"""
        case class $className(..$params) {

          def schema = ${json}

        }
      """
    )

我在问题中发布的代码有两个步骤可以使其正常工作。

1)将$definitions.toList转换为列表

2)在前面添加两个..

所以最终的代码如下:

    val definitions = files.map(f => {
      val daoName = f.getName.replace(".java", "")
      val daoType = TypeName(daoName)
      val daoTerm = TermName(new StringBuilder("get").append(daoName).toString())

      q"""def $daoTerm = getValueOrInstantiate($daoName, () => new $daoType(configuration))"""
    }).toList <--- HERE!

    val tree = q"""
        package database.dao {
          import org.jooq.SQLDialect
          import org.jooq.impl.DefaultConfiguration
          import utility.StrongHashMap

          trait $componentType extends StrongHashMap[String, Dao] {
            this: DaoManager =>

            private lazy val configuration = new DefaultConfiguration().set(connection).set(SQLDialect.POSTGRES_9_4)

            ..$definitions <-- AND HERE!

          }
        }"""