From f799d1a56dbaf45c4084775c80147a10d75ccefd Mon Sep 17 00:00:00 2001 From: "Simeon H.K. Fitch" Date: Sat, 10 Mar 2018 18:35:14 -0500 Subject: [PATCH 1/5] Use originating mirror for types instantiated from TypeTag. Fix for #26 --- .../src/main/scala/ai/deepsense/deeplang/TypeUtils.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala index 8d629864c..3f7becb6b 100644 --- a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala +++ b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala @@ -20,10 +20,11 @@ import java.lang.reflect.Constructor import scala.reflect.runtime.universe.Type import scala.reflect.runtime.{universe => ru} - import ai.deepsense.deeplang.params.exceptions.NoArgumentConstructorRequiredException import ai.deepsense.sparkutils +import scala.util.Try + /** * Holds methods used for manipulating objects representing types. */ @@ -57,10 +58,10 @@ object TypeUtils { } def instanceOfType[T](typeTag: ru.TypeTag[T]): T = { - val constructorT = constructorForType(typeTag.tpe).getOrElse { + val clazz = typeTag.mirror.runtimeClass(typeTag.tpe) + Try(clazz.newInstance.asInstanceOf[T]).getOrElse { throw NoArgumentConstructorRequiredException(typeTag.tpe.typeSymbol.asClass.name.decodedName.toString) } - createInstance(constructorT).asInstanceOf[T] } private val TypeSeparator = " with " From 5e179720c49385821db62159d850c25833f6a591 Mon Sep 17 00:00:00 2001 From: "Simeon H.K. Fitch" Date: Tue, 13 Mar 2018 09:26:32 -0400 Subject: [PATCH 2/5] Propagated TypeTag/mirror provenance further through APIs. Tried to minimize changes more than a single type away from TypeUtils. Signed-off-by: Simeon H.K. Fitch --- .../ai/deepsense/deeplang/TypeUtils.scala | 25 ++++++++++++------- .../doperable/ConcreteClassNode.scala | 2 +- .../catalogs/doperable/TraitNode.scala | 2 +- .../deeplang/params/ParamsSequence.scala | 2 +- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala index 3f7becb6b..abe482769 100644 --- a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala +++ b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala @@ -29,11 +29,14 @@ import scala.util.Try * Holds methods used for manipulating objects representing types. */ object TypeUtils { - private val mirror = ru.runtimeMirror(getClass.getClassLoader) + private def classMirror(c: Class[_]) = ru.runtimeMirror(c.getClassLoader) - def classToType(c: Class[_]): ru.Type = mirror.classSymbol(c).toType + def classToType[T](c: Class[T]): ru.Type = classMirror(c).classSymbol(c).toType - def typeToClass(t: ru.Type): Class[_] = mirror.runtimeClass(t.typeSymbol.asClass) + def typeToClass(t: ru.Type): Class[_] = classMirror(t.getClass).runtimeClass(t.typeSymbol.asClass) + + def typeTagToClass[T](t: ru.TypeTag[T]): Class[T] = + t.mirror.runtimeClass(t.tpe.typeSymbol.asClass).asInstanceOf[Class[T]] def symbolToType(s: ru.Symbol): ru.Type = s.asClass.toType @@ -42,26 +45,30 @@ object TypeUtils { def isAbstract(c: Class[_]): Boolean = sparkutils.TypeUtils.isAbstract(classToType(c).typeSymbol.asClass) - def constructorForClass(c: Class[_]): Option[Constructor[_]] = { + def constructorForClass[T](c: Class[T]): Option[Constructor[T]] = { val constructors = c.getConstructors val isParameterLess: (Constructor[_] => Boolean) = constructor => constructor.getParameterTypes.isEmpty - constructors.find(isParameterLess) + constructors.find(isParameterLess).map(_.asInstanceOf[Constructor[T]]) + } + + def constructorForTypeTag[T](t: ru.TypeTag[T]): Option[Constructor[T]] = { + constructorForClass(typeTagToClass(t)) } def constructorForType(t: ru.Type): Option[Constructor[_]] = { constructorForClass(typeToClass(t)) } - def createInstance[T](constructor: Constructor[_]): T = { - constructor.newInstance().asInstanceOf[T] + def createInstance[T](constructor: Constructor[T]): T = { + constructor.newInstance() } def instanceOfType[T](typeTag: ru.TypeTag[T]): T = { - val clazz = typeTag.mirror.runtimeClass(typeTag.tpe) - Try(clazz.newInstance.asInstanceOf[T]).getOrElse { + val constructorT = constructorForTypeTag(typeTag).getOrElse { throw NoArgumentConstructorRequiredException(typeTag.tpe.typeSymbol.asClass.name.decodedName.toString) } + createInstance(constructorT) } private val TypeSeparator = " with " diff --git a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/ConcreteClassNode.scala b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/ConcreteClassNode.scala index fae6507f4..2401a3ff6 100644 --- a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/ConcreteClassNode.scala +++ b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/ConcreteClassNode.scala @@ -32,7 +32,7 @@ private[doperable] class ConcreteClassNode(javaType: Class[_]) extends ClassNode * Invokes first constructor and assumes that it takes no parameters. */ private[doperable] def createInstance[T <: DOperable]: T = { - TypeUtils.createInstance[T](constructor) + TypeUtils.createInstance[T](constructor.asInstanceOf[Constructor[T]]) } override private[doperable] def subclassesInstances: Set[ConcreteClassNode] = { diff --git a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/TraitNode.scala b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/TraitNode.scala index 3053bc817..626338849 100644 --- a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/TraitNode.scala +++ b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/TraitNode.scala @@ -17,7 +17,7 @@ package ai.deepsense.deeplang.catalogs.doperable import scala.reflect.runtime.{universe => ru} - +import ru.{TypeTag, typeTag} import ai.deepsense.deeplang.TypeUtils /** diff --git a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/params/ParamsSequence.scala b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/params/ParamsSequence.scala index c50e31829..0748ff07e 100644 --- a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/params/ParamsSequence.scala +++ b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/params/ParamsSequence.scala @@ -40,7 +40,7 @@ case class ParamsSequence[T <: Params]( JsArray(cells: _*) } - private val constructor: Constructor[_] = TypeUtils.constructorForType(tag.tpe).getOrElse { + private val constructor: Constructor[_] = TypeUtils.constructorForTypeTag(tag).getOrElse { throw NoArgumentConstructorRequiredException(tag.tpe.typeSymbol.asClass.name.decodedName.toString) } From 38ff34da4f30bb79ba3bf80f2c12dbb5b98769f3 Mon Sep 17 00:00:00 2001 From: "Simeon H.K. Fitch" Date: Tue, 13 Mar 2018 10:56:14 -0400 Subject: [PATCH 3/5] Removed unused imports. Signed-off-by: Simeon H.K. Fitch --- .../src/main/scala/ai/deepsense/deeplang/TypeUtils.scala | 2 -- .../ai/deepsense/deeplang/catalogs/doperable/TraitNode.scala | 1 - 2 files changed, 3 deletions(-) diff --git a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala index abe482769..6a8f1483d 100644 --- a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala +++ b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala @@ -23,8 +23,6 @@ import scala.reflect.runtime.{universe => ru} import ai.deepsense.deeplang.params.exceptions.NoArgumentConstructorRequiredException import ai.deepsense.sparkutils -import scala.util.Try - /** * Holds methods used for manipulating objects representing types. */ diff --git a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/TraitNode.scala b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/TraitNode.scala index 626338849..6b1b7167d 100644 --- a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/TraitNode.scala +++ b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/TraitNode.scala @@ -17,7 +17,6 @@ package ai.deepsense.deeplang.catalogs.doperable import scala.reflect.runtime.{universe => ru} -import ru.{TypeTag, typeTag} import ai.deepsense.deeplang.TypeUtils /** From 7e4a7dce52479d6bf22bccf9adda0cf2ef939600 Mon Sep 17 00:00:00 2001 From: Jaroslaw Osmanski Date: Fri, 16 Mar 2018 11:04:12 +0100 Subject: [PATCH 4/5] Change version to 1.4.3-SNAPSHOT --- seahorse-workflow-executor/version.sbt | 2 +- version.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/seahorse-workflow-executor/version.sbt b/seahorse-workflow-executor/version.sbt index ae4b1ac50..a491cc4a4 100644 --- a/seahorse-workflow-executor/version.sbt +++ b/seahorse-workflow-executor/version.sbt @@ -1,2 +1,2 @@ -version in ThisBuild := "1.4.2" +version in ThisBuild := "1.4.3-SNAPSHOT" // TODO add postfix to version diff --git a/version.sbt b/version.sbt index d6584afd5..86a12748e 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "1.4.2" +version in ThisBuild := "1.4.3-SNAPSHOT" From 87d58fa15891f571c8735b015ef4309fa768dbf0 Mon Sep 17 00:00:00 2001 From: "Simeon H.K. Fitch" Date: Sun, 18 Mar 2018 11:39:09 -0400 Subject: [PATCH 5/5] Fixed incorrect selection of "boot" ClassLoader instead of application ClassLoader. Signed-off-by: Simeon H.K. Fitch --- .../src/main/scala/ai/deepsense/deeplang/TypeUtils.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala index 6a8f1483d..bca362377 100644 --- a/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala +++ b/seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala @@ -31,7 +31,7 @@ object TypeUtils { def classToType[T](c: Class[T]): ru.Type = classMirror(c).classSymbol(c).toType - def typeToClass(t: ru.Type): Class[_] = classMirror(t.getClass).runtimeClass(t.typeSymbol.asClass) + def typeToClass(t: ru.Type): Class[_] = classMirror(TypeUtils.getClass).runtimeClass(t.typeSymbol.asClass) def typeTagToClass[T](t: ru.TypeTag[T]): Class[T] = t.mirror.runtimeClass(t.tpe.typeSymbol.asClass).asInstanceOf[Class[T]]