@@ -221,6 +221,54 @@ def tagKeyImpl[T](using Quotes, Type[T])(thisOuter: Expr[upickle.core.Types with
221221 case None => ' {$ {thisOuter}.tagName}
222222 }
223223
224+ inline def applyConstructor [T ](params : Array [Any ]): T = $ { applyConstructorImpl[T ](' params ) }
225+ def applyConstructorImpl [T ](using quotes : Quotes , t0 : Type [T ])(params : Expr [Array [Any ]]): Expr [T ] =
226+ import quotes .reflect ._
227+ def apply (typeApply : Option [List [TypeRepr ]]) = {
228+ val tpe = TypeRepr .of[T ]
229+ val companion : Symbol = tpe.classSymbol.get.companionModule
230+ val constructorSym = tpe.typeSymbol.primaryConstructor
231+ val constructorParamSymss = constructorSym.paramSymss
232+
233+ val (tparams0, params0) = constructorParamSymss.flatten.partition(_.isType)
234+ val constructorTpe = tpe.memberType(constructorSym).widen
235+
236+ val rhs = params0.zipWithIndex.map {
237+ case (sym0, i) =>
238+ val lhs = ' {$params($ { Expr (i) })}
239+ val tpe0 = constructorTpe.memberType(sym0)
240+
241+ typeApply.map(tps => tpe0.substituteTypes(tparams0, tps)).getOrElse(tpe0) match {
242+ case AnnotatedType (AppliedType (base, Seq (arg)), x)
243+ if x.tpe =:= defn.RepeatedAnnot .typeRef =>
244+ arg.asType match {
245+ case ' [t] =>
246+ Typed (
247+ lhs.asTerm,
248+ TypeTree .of(using AppliedType (defn.RepeatedParamClass .typeRef, List (arg)).asType)
249+ )
250+ }
251+ case tpe =>
252+ tpe.asType match {
253+ case ' [t] => ' { $lhs.asInstanceOf [t] }.asTerm
254+ }
255+ }
256+
257+ }
258+
259+ typeApply match {
260+ case None => Select .overloaded(Ref (companion), " apply" , Nil , rhs).asExprOf[T ]
261+ case Some (args) =>
262+ Select .overloaded(Ref (companion), " apply" , args, rhs).asExprOf[T ]
263+ }
264+ }
265+
266+ TypeRepr .of[T ] match {
267+ case t : AppliedType => apply(Some (t.args))
268+ case t : TypeRef => apply(None )
269+ case t : TermRef => ' {$ {Ref (t.classSymbol.get.companionModule).asExprOf[Any ]}.asInstanceOf [T ]}
270+ }
271+
224272inline def tagName [T ]: String = $ { tagNameImpl[T ] }
225273def tagNameImpl [T ](using Quotes , Type [T ]): Expr [String ] =
226274 tagNameImpl0(identity)
0 commit comments