提交 99aeed69 编写于 作者: 梦境迷离's avatar 梦境迷离

add doc, rename directory

上级 5ee616b6
......@@ -42,7 +42,7 @@
- 零依赖,类型安全
```scala
"org.bitlap" %% "smt-csv-core" % "<VERSION>" // 从0.5.1开始
"org.bitlap" %% "smt-csv-core" % "<VERSION>" // 从0.5.2开始
```
## csv-derive
......@@ -50,7 +50,7 @@
- `DeriveCsvConverter` 为Scala`case class`自动派生`Converter`实例
```scala
"org.bitlap" %% "smt-csv-derive" % "<VERSION>" // 从0.5.1开始
"org.bitlap" %% "smt-csv-derive" % "<VERSION>" // 从0.5.2开始
```
## tools
......
......@@ -53,7 +53,7 @@ lazy val commonSettings =
publishLocalConfiguration := publishLocalConfiguration.value.withOverwrite(true)
)
lazy val `cacheable-core` = (project in file("cacheable-core"))
lazy val `smt-cacheable-core` = (project in file("smt-cacheable-core"))
.settings(commonSettings)
.settings(Publishing.publishSettings)
.settings(
......@@ -68,7 +68,7 @@ lazy val `cacheable-core` = (project in file("cacheable-core"))
.settings(paradise())
.enablePlugins(HeaderPlugin)
lazy val `cacheable-caffeine` = (project in file("cacheable-caffeine"))
lazy val `smt-cacheable-caffeine` = (project in file("smt-cacheable-caffeine"))
.settings(commonSettings)
.settings(Publishing.publishSettings)
.settings(
......@@ -79,11 +79,11 @@ lazy val `cacheable-caffeine` = (project in file("cacheable-caffeine"))
"com.github.ben-manes.caffeine" % "caffeine" % caffeineVersion
)
)
.dependsOn(`cacheable-core` % "compile->compile;test->test")
.dependsOn(`smt-cacheable-core` % "compile->compile;test->test")
.settings(paradise())
.enablePlugins(HeaderPlugin)
lazy val `cacheable-redis` = (project in file("cacheable-redis"))
lazy val `smt-cacheable-redis` = (project in file("smt-cacheable-redis"))
.settings(commonSettings)
.settings(Publishing.publishSettings)
.settings(
......@@ -97,21 +97,21 @@ lazy val `cacheable-redis` = (project in file("cacheable-redis"))
"dev.zio" %% "zio-schema-derivation" % zioSchemaVersion % Test
)
)
.dependsOn(`cacheable-core` % "compile->compile;test->test")
.dependsOn(`smt-cacheable-core` % "compile->compile;test->test")
.settings(paradise())
.enablePlugins(HeaderPlugin)
lazy val `cacheable-benchmark` = (project in file("cacheable-benchmark"))
lazy val `smt-cacheable-benchmark` = (project in file("smt-cacheable-benchmark"))
.settings(commonSettings)
.settings(
name := "smt-cacheable-benchmark",
publish / skip := true
)
.dependsOn(`cacheable-core`, `cacheable-redis`, `cacheable-caffeine`)
.dependsOn(`smt-cacheable-core`, `smt-cacheable-redis`, `smt-cacheable-caffeine`)
.settings(paradise())
.enablePlugins(HeaderPlugin, JmhPlugin)
lazy val `csv-core` = (project in file("csv-core"))
lazy val `smt-csv-core` = (project in file("smt-csv-core"))
.settings(commonSettings)
.settings(
name := "smt-csv-core",
......@@ -121,7 +121,7 @@ lazy val `csv-core` = (project in file("csv-core"))
.settings(paradise())
.enablePlugins(HeaderPlugin)
lazy val `csv-derive` = (project in file("csv-derive"))
lazy val `smt-csv-derive` = (project in file("smt-csv-derive"))
.settings(commonSettings)
.settings(
name := "smt-csv-derive",
......@@ -130,9 +130,9 @@ lazy val `csv-derive` = (project in file("csv-derive"))
.settings(Publishing.publishSettings)
.settings(paradise())
.enablePlugins(HeaderPlugin)
.dependsOn(`csv-core` % "compile->compile;test->test")
.dependsOn(`smt-csv-core` % "compile->compile;test->test")
lazy val tools = (project in file("tools"))
lazy val `smt-tools` = (project in file("smt-tools"))
.settings(commonSettings)
.settings(
name := "smt-tools",
......@@ -154,13 +154,13 @@ lazy val tools = (project in file("tools"))
lazy val root = (project in file("."))
.aggregate(
tools,
`cacheable-core`,
`cacheable-redis`,
`cacheable-caffeine`,
`cacheable-benchmark`,
`csv-core`,
`csv-derive`
`smt-tools`,
`smt-cacheable-core`,
`smt-cacheable-redis`,
`smt-cacheable-caffeine`,
`smt-cacheable-benchmark`,
`smt-csv-core`,
`smt-csv-derive`
)
.settings(
commands ++= Commands.value,
......
......@@ -26,6 +26,8 @@ import scala.collection.mutable.ListBuffer
import scala.util.Using
/**
* Tool class for parsing CSV files.
*
* @author 梦境迷离
* @version 1.0,2022/5/2
*/
......
......@@ -30,9 +30,20 @@ package org.bitlap.csv.core
*/
trait Csvable[T] {
/**
* Internal API for processing a specific field of case class object.
*
* @param t case class object
* @return
*/
@InternalApi
def _toCsvString(t: T): String = ""
/**
* Public API, finally get CSV line string.
*
* @return
*/
def toCsvString: String = ""
}
......
......@@ -30,9 +30,20 @@ package org.bitlap.csv.core
*/
trait Scalable[T] {
/**
* Internal API for processing a specific column value of CSV line data.
*
* @param column The column value of CSV line data.
* @return
*/
@InternalApi
def _toScala(column: String): Option[T] = None
/**
* Public API, finally get scala case class object.
*
* @return
*/
def toScala: Option[T] = None
}
......
......@@ -26,6 +26,8 @@ import java.time.format.DateTimeFormatter
import scala.reflect.macros.blackbox
/**
* This is a generic implementation of macro handling, and subclasses need to inherit it to reduce redundant code.
*
* @author 梦境迷离
* @since 2021/7/24
* @version 1.0
......@@ -34,10 +36,17 @@ abstract class AbstractMacroProcessor(val c: blackbox.Context) {
import c.universe._
private[macros] def checkCaseClassZipParams[T: c.WeakTypeTag](
/**
* Get the list of case class constructor parameters and return the column index, column name, and parameter type that zip as a `List[((Int, Tree), Type)]`.
*
* @param columns CSV row data temporary identifier, also known as a line.
* @tparam T Type of the case class.
* @return
*/
private[macros] def checkCaseClassZipAll[T: c.WeakTypeTag](
columns: TermName
): List[((Int, Tree), Type)] = {
val idxColumn = (i: Int) => q"${columns}(${i})"
val idxColumn = (i: Int) => q"$columns($i)"
val params = getCaseClassParams[T]()
val paramsSize = params.size
val types = params.map(f => c.typecheck(tq"$f", c.TYPEmode).tpe)
......@@ -49,6 +58,12 @@ abstract class AbstractMacroProcessor(val c: blackbox.Context) {
indexColumns zip types
}
/**
* Get only the symbol of the case class constructor parameters.
*
* @tparam T Type of the case class.
* @return
*/
private[macros] def getCaseClassParams[T: c.WeakTypeTag](): List[Symbol] = {
val parameters = resolveParameters[T]
if (parameters.size > 1) {
......@@ -57,6 +72,14 @@ abstract class AbstractMacroProcessor(val c: blackbox.Context) {
parameters.flatten
}
/**
* Print the expanded code of macro.
*
* @param force
* @param resTree
* @tparam T
* @return
*/
def printTree[T: c.WeakTypeTag](force: Boolean, resTree: c.Tree): c.Expr[T] = {
c.info(
c.enclosingPosition,
......@@ -67,23 +90,43 @@ abstract class AbstractMacroProcessor(val c: blackbox.Context) {
c.Expr[T](resTree)
}
/**
* Get the constructor symbol of the case class.
*
* @tparam T Type of the case class.
* @return The parameters may be currying, so it's a two-level list.
*/
private[macros] def resolveParameters[T: c.WeakTypeTag]: List[List[Symbol]] =
c.weakTypeOf[T].resultType.member(TermName("<init>")).typeSignature.paramLists
/**
* Get the `TypeName` of the class.
*
* @tparam T Type of the case class.
* @return
*/
private[macros] def resolveClazzTypeName[T: c.WeakTypeTag]: c.universe.TypeName =
TypeName(c.weakTypeOf[T].typeSymbol.name.decodedName.toString)
private[macros] def zipAllCaseClassParams[T: c.WeakTypeTag]: (List[String], List[(Int, Type)]) = {
val parameters = resolveParameters[T]
if (parameters.size > 1) {
c.abort(c.enclosingPosition, "The constructor of case class has currying!")
}
val params = parameters.flatten
/**
* Get the list of case class constructor parameters and return the column index and parameter type that zip as a `List[(Int, Type)])`.
*
* @tparam T Type of the case class.
* @return
*/
private[macros] def checkCaseClassZip[T: c.WeakTypeTag]: (List[String], List[(Int, Type)]) = {
val params = getCaseClassParams[T]()
val paramsSize = params.size
val names = params.map(p => p.name.decodedName.toString)
names -> params.zip(0 until paramsSize).map(f => f._2 -> c.typecheck(tq"${f._1}", c.TYPEmode).tpe)
}
/**
* Get the builderId of the current class which generated by *Builder,apply macro.
*
* @param annoBuilderPrefix
* @return
*/
private[macros] def getBuilderId(annoBuilderPrefix: String): Int =
c.prefix.actualType.toString.replace(annoBuilderPrefix, "").toInt
}
......@@ -99,7 +99,7 @@ class DeriveCsvableBuilder(override val c: whitebox.Context) extends AbstractMac
customTrees: mutable.Map[String, Any]
): c.Expr[Csvable[T]] = {
val clazzName = resolveClazzTypeName[T]
val (fieldNames, indexTypes) = zipAllCaseClassParams
val (fieldNames, indexTypes) = checkCaseClassZip
val indexByName = (i: Int) => TermName(fieldNames(i))
val fieldsToString = indexTypes.map { idxType =>
val customFunction = () =>
......
......@@ -104,7 +104,7 @@ class DeriveScalableBuilder(override val c: whitebox.Context) extends AbstractMa
val customTrees = MacroCache.builderFunctionTrees.getOrElse(getBuilderId(annoBuilderPrefix), mutable.Map.empty)
val params = getCaseClassParams[T]()
val fieldNames = params.map(_.name.decodedName.toString)
val fields = checkCaseClassZipParams[T](innerVarTermName).map { idxType =>
val fields = checkCaseClassZipAll[T](innerVarTermName).map { idxType =>
val idx = idxType._1._1
val columnValues = idxType._1._2
val fieldTypeName = TypeName(idxType._2.typeSymbol.name.decodedName.toString)
......
......@@ -43,7 +43,7 @@ object DeriveToCaseClass {
val clazzName = c.weakTypeOf[T].typeSymbol.name
val innerVarTermName = TermName("_columns")
val fields = (columns: TermName) =>
checkCaseClassZipParams[T](columns).map { idxType =>
checkCaseClassZipAll[T](columns).map { idxType =>
val columnValues = idxType._1._2
if (idxType._2 <:< typeOf[Option[_]]) {
val genericType = c.typecheck(q"${idxType._2}", c.TYPEmode).tpe.typeArgs.head
......
......@@ -38,7 +38,7 @@ object DeriveToString {
private val packageName = q"_root_.org.bitlap.csv.core"
def macroImpl[T: c.WeakTypeTag](t: c.Expr[T], columnSeparator: c.Expr[Char]): c.Expr[String] = {
val (names, indexTypes) = super.zipAllCaseClassParams[T]
val (names, indexTypes) = super.checkCaseClassZip[T]
val clazzName = c.weakTypeOf[T].typeSymbol.name
val innerVarTermName = TermName("_t")
val indexByName = (i: Int) => TermName(names(i))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册