-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#patch Adding support for SdkBindingData[scala.Option[_]] #308
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ import scala.reflect.api.{Mirror, TypeCreator, Universe} | |
import scala.reflect.runtime.universe | ||
import scala.reflect.{ClassTag, classTag} | ||
import scala.reflect.runtime.universe.{ | ||
ClassSymbol, | ||
NoPrefix, | ||
Symbol, | ||
Type, | ||
|
@@ -72,7 +73,7 @@ object SdkLiteralTypes { | |
blobs(BlobType.DEFAULT).asInstanceOf[SdkLiteralType[T]] | ||
case t if t =:= typeOf[Binary] => | ||
binary().asInstanceOf[SdkLiteralType[T]] | ||
case t if t <:< typeOf[Product] && !(t =:= typeOf[Option[_]]) => | ||
case t if t <:< typeOf[Product] => | ||
generics().asInstanceOf[SdkLiteralType[T]] | ||
|
||
case t if t =:= typeOf[List[Long]] => | ||
|
@@ -391,24 +392,37 @@ object SdkLiteralTypes { | |
) | ||
} | ||
|
||
val clazz = typeOf[S].typeSymbol.asClass | ||
val classMirror = mirror.reflectClass(clazz) | ||
val constructor = typeOf[S].decl(termNames.CONSTRUCTOR).asMethod | ||
val constructorMirror = classMirror.reflectConstructor(constructor) | ||
|
||
val constructorArgs = | ||
constructor.paramLists.flatten.map((param: Symbol) => { | ||
val paramName = param.name.toString | ||
val value = map.getOrElse( | ||
paramName, | ||
throw new IllegalArgumentException( | ||
s"Map is missing required parameter named $paramName" | ||
def instantiateViaConstructor(cls: ClassSymbol): S = { | ||
val classMirror = mirror.reflectClass(cls) | ||
val constructor = typeOf[S].decl(termNames.CONSTRUCTOR).asMethod | ||
val constructorMirror = classMirror.reflectConstructor(constructor) | ||
|
||
val constructorArgs = | ||
constructor.paramLists.flatten.map((param: Symbol) => { | ||
val paramName = param.name.toString | ||
val value = map.getOrElse( | ||
paramName, | ||
throw new IllegalArgumentException( | ||
s"Map is missing required parameter named $paramName" | ||
) | ||
) | ||
) | ||
valueToParamValue(value, param.typeSignature.dealias) | ||
}) | ||
valueToParamValue(value, param.typeSignature.dealias) | ||
}) | ||
|
||
constructorMirror(constructorArgs: _*).asInstanceOf[S] | ||
} | ||
|
||
val clazz = typeOf[S].typeSymbol.asClass | ||
// special handling of scala.Option as it is a Product, but can't be instantiated like common | ||
// case classes | ||
if (clazz.name.toString == "Option") | ||
map | ||
.get("value") | ||
.map(valueToParamValue(_, typeOf[S].typeArgs.head)) | ||
.asInstanceOf[S] | ||
Comment on lines
+419
to
+422
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since |
||
else | ||
instantiateViaConstructor(clazz) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pulled out for readability |
||
|
||
constructorMirror(constructorArgs: _*).asInstanceOf[S] | ||
} | ||
|
||
def structValueToAny(value: Struct.Value): Any = { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -232,11 +232,8 @@ object SdkScalaType { | |
implicit def durationLiteralType: SdkScalaLiteralType[Duration] = | ||
DelegateLiteralType(SdkLiteralTypes.durations()) | ||
|
||
// more specific matching to fail the usage of SdkBindingData[Option[_]] | ||
implicit def optionLiteralType: SdkScalaLiteralType[Option[_]] = ??? | ||
|
||
// fixme: using Product is just an approximation for case class because Product | ||
// is also super class of, for example, Option and Tuple | ||
// is also super class of, for example, Either or Try | ||
Comment on lines
-239
to
+236
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tuple is actually also just a case class and already works with the current implementation. The problem arises when there is an abstract Product type with several specific implementations like |
||
implicit def productLiteralType[T <: Product: TypeTag: ClassTag] | ||
: SdkScalaLiteralType[T] = | ||
DelegateLiteralType(SdkLiteralTypes.generics()) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,11 @@ package object flytekitscala { | |
} catch { | ||
case _: Throwable => | ||
// fall back to java's way, less reliable and with limitations | ||
product.getClass.getDeclaredFields.map(_.getName).toList | ||
val methodNames = product.getClass.getDeclaredMethods.map(_.getName) | ||
product.getClass.getDeclaredFields | ||
.map(_.getName) | ||
.filter(methodNames.contains) | ||
.toList | ||
Comment on lines
-33
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This gave me |
||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check for avoiding Option was not successful before. It would need to use
<:<
instead of=:=
.