Skip to content

Commit

Permalink
Fix: apply type arguments to method return type
Browse files Browse the repository at this point in the history
  • Loading branch information
OndrejSpanel committed Mar 26, 2024
1 parent 4f7518f commit 4892f2e
Showing 1 changed file with 27 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,13 @@ private[surface] class CompileTimeSurfaceFactory[Q <: Quotes](using quotes: Q):
}
}

// Build a table for resolving type parameters, e.g., class MyClass[A, B] -> Map("A" -> TypeRepr, "B" -> TypeRepr)
private def typeMappingTable(t: TypeRepr, method: Symbol): Map[String, TypeRepr] =
val classTypeParams = t.typeSymbol.typeMembers.filter(_.isTypeParam)
val classTypeArgs: List[TypeRepr] = t match
case a: AppliedType => a.args
case _ => List.empty[TypeRepr]

// Build a table for resolving type parameters, e.g., class MyClass[A, B] -> Map("A" -> TypeRepr, "B" -> TypeRepr)
(classTypeParams zip classTypeArgs).map { (paramType, argType) =>
paramType.name -> argType
}.toMap[String, TypeRepr]
Expand Down Expand Up @@ -491,15 +491,34 @@ private[surface] class CompileTimeSurfaceFactory[Q <: Quotes](using quotes: Q):
isSecret: Boolean
)

private def resolveType(t: TypeRepr, typeArgTable: Map[String, TypeRepr]): TypeRepr =
t match
case a: AppliedType =>
// println(s"=== a.args ${a.args}")
// println(s"=== typeArgTable ${typeArgTable}")
val resolvedTypeArgs = a.args.map {
case p if p.typeSymbol.isTypeParam && typeArgTable.contains(p.typeSymbol.name) =>
typeArgTable(p.typeSymbol.name)
case other =>
resolveType(other, typeArgTable)
}
// println(s"=== resolvedTypeArgs ${resolvedTypeArgs}")
// Need to use the base type of the applied type to replace the type parameters
a.tycon.appliedTo(resolvedTypeArgs)
case TypeRef(_, name) if typeArgTable.contains(name) =>
typeArgTable(name)
case other =>
other


private def methodArgsOf(t: TypeRepr, method: Symbol): List[List[MethodArg]] =
// println(s"==== method args of ${fullTypeNameOf(t)}")

val defaultValueMethods = t.typeSymbol.companionClass.declaredMethods.filter { m =>
m.name.startsWith("apply$default$") || m.name.startsWith("$lessinit$greater$default$")
}

// Build a table for resolving type parameters, e.g., class MyClass[A, B] -> Map("A" -> TypeRepr, "B" -> TypeRepr)
val typeArgTable: Map[String, TypeRepr] = typeMappingTable(t, method)
val typeArgTable = typeMappingTable(t, method)

val paramss: List[List[Symbol]] = method.paramSymss.filter { lst =>
// Empty arg is allowed
Expand All @@ -516,26 +535,7 @@ private[surface] class CompileTimeSurfaceFactory[Q <: Quotes](using quotes: Q):
// println(s"=== ${v.show} ${s.flags.show} ${s.flags.is(Flags.Implicit)}")
// Substitute type param to actual types

def resolveType(t: TypeRepr): TypeRepr =
t match
case a: AppliedType =>
// println(s"=== a.args ${a.args}")
// println(s"=== typeArgTable ${typeArgTable}")
val resolvedTypeArgs = a.args.map {
case p if p.typeSymbol.isTypeParam && typeArgTable.contains(p.typeSymbol.name) =>
typeArgTable(p.typeSymbol.name)
case other =>
resolveType(other)
}
// println(s"=== resolvedTypeArgs ${resolvedTypeArgs}")
// Need to use the base type of the applied type to replace the type parameters
a.tycon.appliedTo(resolvedTypeArgs)
case TypeRef(_, name) if typeArgTable.contains(name) =>
typeArgTable(name)
case other =>
other

val resolved: TypeRepr = resolveType(v)
val resolved = resolveType(v, typeArgTable)

val isSecret = hasSecretAnnotation(s)
val isRequired = hasRequiredAnnotation(s)
Expand Down Expand Up @@ -755,8 +755,10 @@ private[surface] class CompileTimeSurfaceFactory[Q <: Quotes](using quotes: Q):
val mod = Expr(modifierBitMaskOf(m))
val owner = surfaceOf(targetType)
val name = Expr(m.name)
// println(s"======= ${df.returnTpt.show}")
val ret = surfaceOf(df.returnTpt.tpe)
val typeArgTable = typeMappingTable(targetType, m)
val returnType = resolveType(df.returnTpt.tpe, typeArgTable)
// println(s"======= ${returnType.show}")
val ret = surfaceOf(returnType)
// println(s"==== method of: def ${m.name}")
val params = methodParametersOf(targetType, m)
val args = methodArgsOf(targetType, m)
Expand Down

0 comments on commit 4892f2e

Please sign in to comment.