From 1b5cc306873f1a4c31722f9c54cde812a6b3dd4e Mon Sep 17 00:00:00 2001 From: IceMimosa Date: Mon, 2 Aug 2021 15:22:46 +0800 Subject: [PATCH] Support generic with bound (#92) --- .../plugin/processor/AbsProcessor.scala | 16 ++++++++++++++++ .../plugin/processor/clazz/ApplyProcessor.scala | 5 +++-- .../processor/clazz/BuilderProcessor.scala | 12 +++++++----- .../scala/io/github/dreamylost/ApplyTest.scala | 4 ++++ .../scala/io/github/dreamylost/BuilderTest.scala | 7 ++++++- 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/AbsProcessor.scala b/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/AbsProcessor.scala index 5249a95..d01d9ef 100644 --- a/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/AbsProcessor.scala +++ b/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/AbsProcessor.scala @@ -52,4 +52,20 @@ abstract class AbsProcessor extends Processor { ) } } + + /** + * get type param string + * + * @param returnType if it is return type + * @return + * if `returnType` is false, just return typeParamString with bound like [T <: Any, U] + * else return typeParamString without bound like [T, U] + */ + protected def getTypeParamString(clazz: ScClass, returnType: Boolean = false): String = { + if (!returnType || clazz.typeParamString.isEmpty) { + clazz.typeParamString + } else { + clazz.typeParameters.map(_.name).mkString("[", ", ", "]") + } + } } diff --git a/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/clazz/ApplyProcessor.scala b/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/clazz/ApplyProcessor.scala index ba51f5f..df43196 100644 --- a/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/clazz/ApplyProcessor.scala +++ b/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/clazz/ApplyProcessor.scala @@ -24,8 +24,9 @@ class ApplyProcessor extends AbsProcessor { val nameAndTypes = getConstructorCurryingParameters(clazz, withSecond = false) .map(_.map(o => s"${o._1}: ${o._2}").mkString("(", ", ", ")")) .mkString - val genericTypes = clazz.typeParamString - Seq(s"def apply$genericTypes$nameAndTypes: ${clazz.getName}$genericTypes = ???") + val genericType = getTypeParamString(clazz) + val returnGenericType = getTypeParamString(clazz, returnType = true) + Seq(s"def apply$genericType$nameAndTypes: ${clazz.getName}$returnGenericType = ???") case _ => Nil } case _ => Nil diff --git a/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/clazz/BuilderProcessor.scala b/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/clazz/BuilderProcessor.scala index 53fb6f7..b025781 100644 --- a/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/clazz/BuilderProcessor.scala +++ b/intellij-plugin/src/main/scala/io/github/dreamylost/plugin/processor/clazz/BuilderProcessor.scala @@ -25,8 +25,9 @@ class BuilderProcessor extends AbsProcessor { case obj: ScObject => obj.fakeCompanionClassOrCompanionClass match { case clazz: ScClass => - val genericTypes = clazz.typeParamString - Seq(s"""def builder$genericTypes(): ${genBuilderName(clazz.getName, returnType = true)}$genericTypes = ???""") + val genericType = getTypeParamString(clazz) + val returnGenericType = getTypeParamString(clazz, returnType = true) + Seq(s"""def builder$genericType(): ${genBuilderName(clazz.getName, returnType = true)}$returnGenericType = ???""") case _ => Nil } case _ => Nil @@ -40,14 +41,15 @@ class BuilderProcessor extends AbsProcessor { val className = clazz.getName // support constructor and second constructor val nameAndTypes = getConstructorParameters(clazz.asInstanceOf[ScClass]) - val genericTypes = clazz.typeParamString + val genericType = getTypeParamString(clazz) + val returnGenericType = getTypeParamString(clazz, returnType = true) val assignMethods = nameAndTypes.map(term => s"def ${term._1}(${term._1}: ${term._2}) = this" ) Seq( s""" - |class ${genBuilderName(className)}$genericTypes { - | def build(): $className$genericTypes = ??? + |class ${genBuilderName(className)}$genericType { + | def build(): $className$returnGenericType = ??? | ${assignMethods.mkString("\n")} |} |""".stripMargin diff --git a/src/test/scala/io/github/dreamylost/ApplyTest.scala b/src/test/scala/io/github/dreamylost/ApplyTest.scala index 987e023..82ff2ad 100644 --- a/src/test/scala/io/github/dreamylost/ApplyTest.scala +++ b/src/test/scala/io/github/dreamylost/ApplyTest.scala @@ -76,6 +76,10 @@ class ApplyTest extends AnyFlatSpec with Matchers { @toString @apply class B4[T, U](int: T, val j: U) println(B4("helloworld", 2)) + + @toString + @apply class B5[T <: Any, U](int: T, val j: U) + println(B5("helloworld", 2)) } "apply5" should "failed when input not invalid" in { """@apply(true) class C2(int: Int, val j: Int, var k: Option[String] = None, t: Option[Long] = Some(1L))(o: Int = 1)""" shouldNot compile diff --git a/src/test/scala/io/github/dreamylost/BuilderTest.scala b/src/test/scala/io/github/dreamylost/BuilderTest.scala index e9e5860..9f1739b 100644 --- a/src/test/scala/io/github/dreamylost/BuilderTest.scala +++ b/src/test/scala/io/github/dreamylost/BuilderTest.scala @@ -119,8 +119,13 @@ class BuilderTest extends AnyFlatSpec with Matchers { println(a) @builder - class TestClass12[T, U](val i: T, var j: U) + case class TestClass12[T, U](val i: T, var j: U) val b = TestClass12.builder().i(new AnyRef).j(List("helloworld", "generic is ok")).build() println(b) + + @builder + case class TestClass13[T <: Any, U](val i: T, var j: U) + val c = TestClass13.builder().i(1).j(List("helloworld", "generic is ok")).build() + println(c) } } -- GitLab