提交 5d3eb741 编写于 作者: 梦境迷离's avatar 梦境迷离

add csv

上级 1798ed03
......@@ -106,6 +106,25 @@ lazy val `cacheable-benchmark` = (project in file("cacheable-benchmark"))
.settings(paradise())
.enablePlugins(HeaderPlugin, JmhPlugin)
lazy val `csv-core` = (project in file("csv-core"))
.settings(commonSettings)
.settings(
name := "smt-csv-core",
crossScalaVersions := List(scala213, scala212, scala211),
).settings(Publishing.publishSettings)
.settings(paradise())
.enablePlugins(HeaderPlugin)
lazy val `csv-derive` = (project in file("csv-derive"))
.settings(commonSettings)
.settings(
name := "smt-csv-derive",
crossScalaVersions := List(scala213, scala212, scala211),
).settings(Publishing.publishSettings)
.settings(paradise())
.enablePlugins(HeaderPlugin)
.dependsOn(`csv-core`)
lazy val tools = (project in file("tools"))
.settings(commonSettings)
.settings(
......
/*
* Copyright (c) 2022 bitlap
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.bitlap.csv.core
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import scala.reflect.macros.blackbox
/**
*
* @author 梦境迷离
* @since 2021/7/24
* @version 1.0
*/
abstract class AbstractMacroProcessor(val c: blackbox.Context) {
def printTree[T: c.WeakTypeTag](c: blackbox.Context)(force: Boolean, resTree: c.Tree): c.Expr[T] = {
c.info(
c.enclosingPosition,
s"\n###### Time: ${
ZonedDateTime.now().format(DateTimeFormatter.ISO_ZONED_DATE_TIME)
} " +
s"Expanded macro start ######\n" + resTree.toString() + "\n###### Expanded macro end ######\n",
force = force
)
c.Expr[T](resTree)
}
}
package org.bitlap.csv.core
import scala.collection.immutable.{ :: => Cons }
/**
* Csv encoder and decoder api.
*
* @author 梦境迷离
* @since 2022/04/27
* @version 1.0
*/
trait CsvConverter[T] {
def from(s: String): Option[T]
def to(t: T): String
}
object CsvConverter {
lazy val LINE_SEPARATOR: String = "\n"
def apply[T](implicit st: => CsvConverter[T]): CsvConverter[T] = st
// Primitives
implicit def stringCSVConverter: CsvConverter[String] = new CsvConverter[String] {
def from(s: String): Option[String] = if (s.isEmpty) None else Some(s)
def to(s: String): String = s
}
implicit def intCsvConverter: CsvConverter[Int] = new CsvConverter[Int] {
def from(s: String): Option[Int] = Option(s.toInt)
def to(i: Int): String = i.toString
}
implicit def charCsvConverter: CsvConverter[Char] = new CsvConverter[Char] {
def from(s: String): Option[Char] = if (s.isEmpty) None else Some(s.charAt(0))
override def to(t: Char): String = t.toString
}
implicit def longCsvConverter: CsvConverter[Long] = new CsvConverter[Long] {
def from(s: String): Option[Long] = Option(s.toLong)
def to(i: Long): String = i.toString
}
implicit def shortCsvConverter: CsvConverter[Short] = new CsvConverter[Short] {
def from(s: String): Option[Short] = Option(s.toShort)
def to(i: Short): String = i.toString
}
implicit def doubleCsvConverter: CsvConverter[Double] = new CsvConverter[Double] {
def from(s: String): Option[Double] = Option(s.toDouble)
def to(i: Double): String = i.toString
}
implicit def floatCsvConverter: CsvConverter[Float] = new CsvConverter[Float] {
def from(s: String): Option[Float] = Option(s.toFloat)
def to(i: Float): String = i.toString
}
implicit def booleanCsvConverter: CsvConverter[Boolean] = new CsvConverter[Boolean] {
def from(s: String): Option[Boolean] = Option(s.toBoolean)
def to(i: Boolean): String = i.toString
}
@inline private[this] def listCsvLinesConverter[A](l: List[String])(implicit ec: CsvConverter[A]): Option[List[A]] = l match {
case Nil => Some(Nil)
case Cons(s, ss) =>
for {
x <- ec.from(s)
xs <- listCsvLinesConverter(ss)(ec)
} yield Cons(x, xs)
}
implicit def listCsvConverter[A](implicit ec: CsvConverter[A]): CsvConverter[List[A]] = new CsvConverter[List[A]] {
def from(s: String): Option[List[A]] = listCsvLinesConverter(s.split(LINE_SEPARATOR).toList)(ec)
def to(l: List[A]): String = l.map(ec.to).mkString(LINE_SEPARATOR)
}
}
package org.bitlap.csv.core
import scala.reflect.macros.blackbox
/**
* @author 梦境迷离
* @version 1.0,2022/4/29
*/
object DeriveToCaseClass {
def apply[T <: Product](line: String, columnSeparator: String): Option[T] = macro Macro.macroImpl[T]
class Macro(override val c: blackbox.Context) extends AbstractMacroProcessor(c) {
def macroImpl[T <: Product : c.WeakTypeTag](line: c.Expr[String], columnSeparator: c.Expr[String]): c.Expr[Option[T]] = {
import c.universe._
val parameters = c.weakTypeOf[T].resultType.member(TermName("<init>")).typeSignature.paramLists
if (parameters.size > 1) {
c.abort(c.enclosingPosition, "The parameters list in constructor of case cass have currying!")
}
lazy val columns = q"$line.split($columnSeparator)"
val params = parameters.flatten
val paramsSize = params.size
val clazzName = c.weakTypeOf[T].typeSymbol.name
val types = params.zip(0 until paramsSize).map(f => c.typecheck(tq"${f._1}", c.TYPEmode).tpe)
val index = (0 until paramsSize).toList.map(i => q"$columns($i)")
val fields = (index zip types).map { f =>
if (f._2 <:< typeOf[Option[_]]) {
val genericType = c.typecheck(q"${f._2}", c.TYPEmode).tpe.typeArgs.head
q"CsvConverter[${genericType.typeSymbol.name.toTypeName}].from(${f._1})"
} else {
f._2 match {
case t if t <:< typeOf[Int] =>
q"CsvConverter[${TypeName(f._2.typeSymbol.name.decodedName.toString)}].from(${f._1}).getOrElse(0)"
case t if t <:< typeOf[String] =>
q"""CsvConverter[${TypeName(f._2.typeSymbol.name.decodedName.toString)}].from(${f._1}).getOrElse("")"""
case t if t <:< typeOf[Double] =>
q"CsvConverter[${TypeName(f._2.typeSymbol.name.decodedName.toString)}].from(${f._1}).getOrElse(0D)"
case t if t <:< typeOf[Float] =>
q"CsvConverter[${TypeName(f._2.typeSymbol.name.decodedName.toString)}].from(${f._1}).getOrElse(0F)"
case t if t <:< typeOf[Char] =>
q"CsvConverter[${TypeName(f._2.typeSymbol.name.decodedName.toString)}].from(${f._1}).getOrElse('0')"
case t if t <:< typeOf[Byte] =>
q"CsvConverter[${TypeName(f._2.typeSymbol.name.decodedName.toString)}].from(${f._1}).getOrElse(0)"
case t if t <:< typeOf[Short] =>
q"CsvConverter[${TypeName(f._2.typeSymbol.name.decodedName.toString)}].from(${f._1}).getOrElse(0)"
case t if t <:< typeOf[Boolean] =>
q"CsvConverter[${TypeName(f._2.typeSymbol.name.decodedName.toString)}].from(${f._1}).getOrElse(false)"
case t if t <:< typeOf[Long] =>
q"CsvConverter[${TypeName(f._2.typeSymbol.name.decodedName.toString)}].from(${f._1}).getOrElse(0L)"
}
}
}
val tree =
q"""
Option(${TermName(clazzName.decodedName.toString)}(..$fields))
"""
printTree[T](c)(force = true, tree)
}.asInstanceOf[c.Expr[Option[T]]]
}
}
package org.bitlap.csv.core
import scala.reflect.macros.blackbox
/**
* @author 梦境迷离
* @version 1.0,2022/4/29
*/
object DeriveToString {
def apply[T <: Product](t: T): String = macro Macro.macroImpl[T]
class Macro(override val c: blackbox.Context) extends AbstractMacroProcessor(c) {
def macroImpl[T <: Product: c.WeakTypeTag](t: c.Expr[T]): c.Expr[String] = {
val clazzName = c.weakTypeOf[T].typeSymbol.name
import c.universe._
val tree =
q"""
val fields = ${TermName(clazzName.decodedName.toString)}.unapply($t).orNull
val fieldsStr = if (null == fields) fields.toString() else ""
fieldsStr.replace("(", "").replace(")", "")
"""
printTree[String](c)(force = true, tree)
}.asInstanceOf[c.Expr[String]]
}
}
package org.bitlap.csv.core
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
/**
*
* @author 梦境迷离
* @version 1.0,2022/4/29
*/
class CsvConverterTest extends AnyFlatSpec with Matchers {
"CsvConverter1" should "ok" in {
val line = "abc,cdf,d,12,2,false,0.1,0.23333"
val dimension = CsvConverter[Dimension].from(line)
assert(dimension.toString == "Some(Dimension(abc,Some(cdf),d,12,2,false,0.1,0.23333))")
}
"CsvConverter2" should "ok when csv column empty" in {
val line =
"abc,,d,12,2,false,0.1,0.23333"
val dimension = CsvConverter[Dimension].from(line)
println(dimension.toString)
assert(dimension.toString == "Some(Dimension(abc,None,d,12,2,false,0.1,0.23333))")
}
"CsvConverter3" should "failed when case class currying" in {
"""
| case class Dimension(key: String, value: Option[String], d: Char, c: Long, e: Short, f: Boolean, g: Float)( h: Double)
| object Dimension {
| implicit def dimensionCsvConverter: CsvConverter[Dimension] = new CsvConverter[Dimension] {
| override def from(line: String): Option[Dimension] = Option(DeriveCaseClassBuilder[Dimension](line, ","))
| override def to(t: Dimension): String = DeriveStringBuilder[Dimension](t)
| }
|
| }
|""".stripMargin shouldNot compile
}
"CsvConverter4" should "ok when using list" in {
val line =
"""1,cdf,d,12,2,false,0.1,0.2
|2,cdf,d,12,2,false,0.1,0.1""".stripMargin
val dimension = CsvConverter[List[Dimension]].from(line)
assert(dimension.toString == "Some(List(Dimension(1,Some(cdf),d,12,2,false,0.1,0.2), Dimension(2,Some(cdf),d,12,2,false,0.1,0.1)))")
}
}
package org.bitlap.csv.core
/**
*
* @author 梦境迷离
* @version 1.0,2022/4/29
*/
case class Dimension(key: String, value: Option[String], d: Char, c: Long, e: Short, f: Boolean, g: Float, h: Double)
object Dimension {
implicit def dimensionCsvConverter: CsvConverter[Dimension] = new CsvConverter[Dimension] {
override def from(line: String): Option[Dimension] = DeriveToCaseClass[Dimension](line, ",")
override def to(t: Dimension): String = DeriveToString[Dimension](t)
}
}
package org.bitlap.csv.derive
import org.bitlap.csv.core.CsvConverter
import scala.reflect.macros.blackbox
import org.bitlap.csv.core.AbstractMacroProcessor
/**
*
* @author 梦境迷离
* @version 1.0,2022/4/29
*/
object DeriveCsvConverter {
def gen[CC]: CsvConverter[CC] = macro Macro.macroImpl[CC]
class Macro(override val c: blackbox.Context) extends AbstractMacroProcessor(c) {
def macroImpl[CC: c.WeakTypeTag]: c.Expr[CC] = {
import c.universe._
val clazzName = c.weakTypeOf[CC].typeSymbol.name
val typeName = TypeName(clazzName.decodedName.toString)
val tree =
q"""
new CsvConverter[$typeName] {
override def from(line: String): Option[$typeName] = _root_.org.bitlap.csv.core.DeriveToCaseClass[$typeName](line, ",")
override def to(t: $typeName): String = _root_.org.bitlap.csv.core.DeriveToString[$typeName](t)
}
"""
printTree[CC](c)(force = true, tree).asInstanceOf[c.Expr[CC]]
}
}
}
package org.bitlap.csv.core
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
/**
*
* @author 梦境迷离
* @version 1.0,2022/4/29
*/
class DeriveCsvConverterTest extends AnyFlatSpec with Matchers {
"DeriveCsvConverter1" should "ok" in {
val line = "abc,cdf,d,12,2,false,0.1,0.23333"
val dimension = CsvConverter[Dimension].from(line)
assert(dimension.toString == "Some(Dimension(abc,Some(cdf),d,12,2,false,0.1,0.23333))")
}
"DeriveCsvConverter2" should "ok when csv column empty" in {
val line =
"abc,,d,12,2,false,0.1,0.23333"
val dimension = CsvConverter[Dimension].from(line)
println(dimension.toString)
assert(dimension.toString == "Some(Dimension(abc,None,d,12,2,false,0.1,0.23333))")
}
"DeriveCsvConverter3" should "ok when using list" in {
val line =
"""1,cdf,d,12,2,false,0.1,0.2
|2,cdf,d,12,2,false,0.1,0.1""".stripMargin
val dimension = CsvConverter[List[Dimension]].from(line)
assert(dimension.toString == "Some(List(Dimension(1,Some(cdf),d,12,2,false,0.1,0.2), Dimension(2,Some(cdf),d,12,2,false,0.1,0.1)))")
}
}
package org.bitlap.csv.core
import org.bitlap.csv.derive.DeriveCsvConverter
/**
*
* @author 梦境迷离
* @version 1.0,2022/4/29
*/
case class Dimension(key: String, value: Option[String], d: Char, c: Long, e: Short, f: Boolean, g: Float, h: Double)
object Dimension {
implicit val dimensionCsvConverter: CsvConverter[Dimension] = DeriveCsvConverter.gen[Dimension]
}
{"{\"organization\":\"org.scala-lang\",\"name\":\"scala-library\",\"revision\":\"2.13.8\",\"isChanging\":false,\"isTransitive\":true,\"isForce\":false,\"explicitArtifacts\":[],\"inclusions\":[],\"exclusions\":[],\"extraAttributes\":{},\"crossVersion\":{\"type\":\"Disabled\"}}":{"value":{"$fields":["path","startLine"],"path":"/Users/liguobin/Projects/scala-macro-tools/build.sbt","startLine":204},"type":"LinePosition"},"{\"organization\":\"org.scala-lang\",\"name\":\"scala-compiler\",\"revision\":\"2.13.8\",\"isChanging\":false,\"isTransitive\":true,\"isForce\":false,\"explicitArtifacts\":[],\"inclusions\":[],\"exclusions\":[],\"extraAttributes\":{},\"crossVersion\":{\"type\":\"Disabled\"}}":{"value":{"$fields":["path","startLine"],"path":"/Users/liguobin/Projects/scala-macro-tools/build.sbt","startLine":204},"type":"LinePosition"},"{\"organization\":\"org.scala-lang\",\"name\":\"scala-reflect\",\"revision\":\"2.13.8\",\"isChanging\":false,\"isTransitive\":true,\"isForce\":false,\"explicitArtifacts\":[],\"inclusions\":[],\"exclusions\":[],\"extraAttributes\":{},\"crossVersion\":{\"type\":\"Disabled\"}}":{"value":{"$fields":["path","startLine"],"path":"/Users/liguobin/Projects/scala-macro-tools/build.sbt","startLine":204},"type":"LinePosition"},"{\"organization\":\"org.scalatest\",\"name\":\"scalatest\",\"revision\":\"3.2.11\",\"configurations\":\"test\",\"isChanging\":false,\"isTransitive\":true,\"isForce\":false,\"explicitArtifacts\":[],\"inclusions\":[],\"exclusions\":[],\"extraAttributes\":{},\"crossVersion\":{\"type\":\"Binary\",\"prefix\":\"\",\"suffix\":\"\"}}":{"value":{"$fields":["path","startLine"],"path":"/Users/liguobin/Projects/scala-macro-tools/build.sbt","startLine":204},"type":"LinePosition"}}
\ No newline at end of file
[debug] not up to date. inChanged = true, force = false
[debug] Updating csv-derive...
[debug] Done updating csv-derive
[debug] not up to date. inChanged = true, force = false
[debug] Updating ProjectRef(uri("file:/Users/liguobin/Projects/scala-macro-tools/"), "csv-derive")...
[debug] Done updating ProjectRef(uri("file:/Users/liguobin/Projects/scala-macro-tools/"), "csv-derive")
/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-library/2.13.8/scala-library-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-compiler/2.13.8/scala-compiler-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-reflect/2.13.8/scala-reflect-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/jline/jline/3.21.0/jline-3.21.0.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/net/java/dev/jna/jna/5.9.0/jna-5.9.0.jar
/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-library/2.13.8/scala-library-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-compiler/2.13.8/scala-compiler-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-reflect/2.13.8/scala-reflect-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/jline/jline/3.21.0/jline-3.21.0.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/net/java/dev/jna/jna/5.9.0/jna-5.9.0.jar
/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-library/2.13.8/scala-library-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-compiler/2.13.8/scala-compiler-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-reflect/2.13.8/scala-reflect-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/jline/jline/3.21.0/jline-3.21.0.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/net/java/dev/jna/jna/5.9.0/jna-5.9.0.jar
/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-library/2.13.8/scala-library-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-compiler/2.13.8/scala-compiler-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-reflect/2.13.8/scala-reflect-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/jline/jline/3.21.0/jline-3.21.0.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/net/java/dev/jna/jna/5.9.0/jna-5.9.0.jar
/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-library/2.13.8/scala-library-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-compiler/2.13.8/scala-compiler-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-reflect/2.13.8/scala-reflect-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest_2.13/3.2.11/scalatest_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/jline/jline/3.21.0/jline-3.21.0.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/net/java/dev/jna/jna/5.9.0/jna-5.9.0.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-core_2.13/3.2.11/scalatest-core_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-featurespec_2.13/3.2.11/scalatest-featurespec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-flatspec_2.13/3.2.11/scalatest-flatspec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-freespec_2.13/3.2.11/scalatest-freespec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-funsuite_2.13/3.2.11/scalatest-funsuite_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-funspec_2.13/3.2.11/scalatest-funspec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-propspec_2.13/3.2.11/scalatest-propspec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-refspec_2.13/3.2.11/scalatest-refspec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-wordspec_2.13/3.2.11/scalatest-wordspec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-diagrams_2.13/3.2.11/scalatest-diagrams_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-matchers-core_2.13/3.2.11/scalatest-matchers-core_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-shouldmatchers_2.13/3.2.11/scalatest-shouldmatchers_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-mustmatchers_2.13/3.2.11/scalatest-mustmatchers_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-compatible/3.2.11/scalatest-compatible-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalactic/scalactic_2.13/3.2.11/scalactic_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/modules/scala-xml_2.13/2.0.1/scala-xml_2.13-2.0.1.jar
/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-library/2.13.8/scala-library-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-compiler/2.13.8/scala-compiler-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/scala-reflect/2.13.8/scala-reflect-2.13.8.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest_2.13/3.2.11/scalatest_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/jline/jline/3.21.0/jline-3.21.0.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/net/java/dev/jna/jna/5.9.0/jna-5.9.0.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-core_2.13/3.2.11/scalatest-core_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-featurespec_2.13/3.2.11/scalatest-featurespec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-flatspec_2.13/3.2.11/scalatest-flatspec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-freespec_2.13/3.2.11/scalatest-freespec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-funsuite_2.13/3.2.11/scalatest-funsuite_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-funspec_2.13/3.2.11/scalatest-funspec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-propspec_2.13/3.2.11/scalatest-propspec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-refspec_2.13/3.2.11/scalatest-refspec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-wordspec_2.13/3.2.11/scalatest-wordspec_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-diagrams_2.13/3.2.11/scalatest-diagrams_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-matchers-core_2.13/3.2.11/scalatest-matchers-core_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-shouldmatchers_2.13/3.2.11/scalatest-shouldmatchers_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-mustmatchers_2.13/3.2.11/scalatest-mustmatchers_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalatest/scalatest-compatible/3.2.11/scalatest-compatible-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/jcenter.bintray.com/org/scalactic/scalactic_2.13/3.2.11/scalactic_2.13-3.2.11.jar:/Users/liguobin/Library/Caches/Coursier/v1/https/maven.aliyun.com/nexus/content/groups/public/org/scala-lang/modules/scala-xml_2.13/2.0.1/scala-xml_2.13-2.0.1.jar
......@@ -31,6 +31,7 @@ import java.util.concurrent.Executor
* @author 梦境迷离
* @version 1.0,2021/12/6
*/
@deprecated
object ProcessorCreator {
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册