Skip to content

Commit 53d3434

Browse files
committed
Implement alias type args
1 parent cd003f0 commit 53d3434

File tree

4 files changed

+30
-8
lines changed

4 files changed

+30
-8
lines changed

airframe-surface/src/main/scala-3/org/opengrabeso/airframe/surface/CompileTimeSurfaceFactory.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,21 +224,28 @@ private[surface] class CompileTimeSurfaceFactory[Q <: Quotes](using quotes: Q):
224224
//println(s"Match 2 $symbolInOwner as ${t.simplified.show}")
225225
surfaceOf(t.simplified)
226226

227+
private def extractTypeArgs(t: TypeRepr): Expr[Seq[Surface]] = {
228+
//println(s"extractTypeArgs of ${t.show}: ${typeArgsOf(t).map(_.show).mkString("[", ",", "]")}")
229+
Expr.ofSeq(typeArgsOf(t).map(s => extractSymbol(s)))
230+
}
231+
227232
private def aliasFactory: Factory = {
228233
case t if t.typeSymbol.typeRef.isOpaqueAlias =>
229234
// Treat opaque types in Scala 3 as alias types
230235
val alias = t.typeSymbol
231236
val inner = extractSymbol(t)
232237
val name = Expr(alias.name)
233238
val fullName = Expr(fullTypeNameOf(t))
234-
'{ Alias(${ name }, ${ fullName }, ${ inner }) }
239+
val typeArgs = extractTypeArgs(t)
240+
'{ Alias(${ name }, ${ fullName }, ${ inner }, ${ typeArgs }) }
235241
case t if t.typeSymbol.isType && t.typeSymbol.isAliasType && !belongsToScalaDefault(t) =>
236242
// println(s"=== alias factory: ${t}, ${dealiased}, ${t.simplified}")
237243
val inner = extractSymbol(t)
238244
val s = t.typeSymbol
239245
val name = Expr(s.name)
240246
val fullName = Expr(fullTypeNameOf(t.asType))
241-
'{ Alias(${ name }, ${ fullName }, ${ inner }) }
247+
val typeArgs = extractTypeArgs(t)
248+
'{ Alias(${ name }, ${ fullName }, ${ inner }, ${ typeArgs }) }
242249
}
243250

244251
private def higherKindedTypeFactory: Factory = {
@@ -372,7 +379,7 @@ private[surface] class CompileTimeSurfaceFactory[Q <: Quotes](using quotes: Q):
372379

373380
private def genericTypeFactory: Factory = {
374381
case t if t =:= TypeRepr.of[Any] =>
375-
'{ Alias("Any", "scala.Any", AnyRefSurface) }
382+
'{ Alias("Any", "scala.Any", AnyRefSurface, Seq.empty) }
376383
case a: AppliedType =>
377384
val typeArgs = a.args.map(surfaceOf(_))
378385
'{ new GenericSurface(${ clsOf(a) }, typeArgs = ${ Expr.ofSeq(typeArgs) }.toIndexedSeq, params = Seq.empty, docString = ${Expr(a.typeSymbol.docstring)}) }

airframe-surface/src/main/scala/org/opengrabeso/airframe/surface/Surfaces.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,9 @@ object Primitive {
152152
case object BigInteger extends PrimitiveSurface(classOf[java.math.BigInteger])
153153
}
154154

155-
case class Alias(override val name: String, override val fullName: String, ref: Surface)
156-
extends GenericSurface(ref.rawType, typeArgs = ref.typeArgs, params = ref.params, docString = ref.docString) {
155+
case class Alias(
156+
override val name: String, override val fullName: String, ref: Surface, aliasTypeArgs: Seq[Surface]
157+
) extends GenericSurface(ref.rawType, typeArgs = ref.typeArgs, params = ref.params, docString = ref.docString) {
157158
override def toString: String = s"${name}:=${ref.name}"
158159
override def isAlias: Boolean = true
159160
override def isPrimitive: Boolean = ref.isPrimitive

airframe-surface/src/test/scala-3/org/opengrabeso/airframe/surface/Scala3NewTypeTest.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@ class Scala3NewTypeTest extends AnyFunSuite with should.Matchers:
6262
s.name shouldBe "Function1[MyEnv,String]"
6363
}
6464

65+
opaque type TypedString[T] = String
66+
67+
test("opaque types with type parameters") {
68+
val s = Surface.of[TypedString[Int]]
69+
s.name shouldBe "TypedString"
70+
s.fullName shouldBe "org.opengrabeso.airframe.surface.Scala3NewTypeTest.TypedString[Int]"
71+
s should not be Surface.of[String]
72+
s match {
73+
case a: Alias =>
74+
a.aliasTypeArgs.head.name shouldBe "Int"
75+
}
76+
s.dealias shouldBe Surface.of[String]
77+
}
78+
6579
case class MyString(env: MyEnv)
6680

6781
test("opaque type in constructor args") {

build.sbt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ publish / skip := true
1414

1515
publishLocal / skip := true
1616

17-
val VERSION = "0.5.6"
18-
val SCALA_3 = "3.3.4"
17+
val VERSION = "0.6.0-SNAPSHOT"
18+
val SCALA_3 = "3.3.6"
1919

2020
// Reload build.sbt on changes
2121
Global / onChangedBuildSource := ReloadOnSourceChanges
@@ -69,7 +69,7 @@ lazy val surface =
6969
name := "light-surface",
7070
Compile / packageDoc / publishArtifact := false,
7171
description := "A library for extracting object structure surface",
72-
libraryDependencies += "org.scalatest" %%% "scalatest" % "3.2.18" % Test,
72+
libraryDependencies += "org.scalatest" %%% "scalatest" % "3.2.19" % Test,
7373
)
7474
.jsSettings(jsBuildSettings)
7575

0 commit comments

Comments
 (0)