Skip to content

Commit 96d7902

Browse files
metasimjaroslaw-osmanski
authored and
jaroslaw-osmanski
committed
Use originating mirror for types instantiated from TypeTag. (#27)
* Use originating mirror for types instantiated from TypeTag. Fix for #26 * 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 <fitch@astraea.io> * Removed unused imports. Signed-off-by: Simeon H.K. Fitch <fitch@astraea.io> * Change version to 1.4.3-SNAPSHOT * Fixed incorrect selection of "boot" ClassLoader instead of application ClassLoader. Signed-off-by: Simeon H.K. Fitch <fitch@astraea.io>
1 parent a303596 commit 96d7902

File tree

4 files changed

+18
-13
lines changed

4 files changed

+18
-13
lines changed

seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/TypeUtils.scala

+16-10
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,21 @@ import java.lang.reflect.Constructor
2020

2121
import scala.reflect.runtime.universe.Type
2222
import scala.reflect.runtime.{universe => ru}
23-
2423
import ai.deepsense.deeplang.params.exceptions.NoArgumentConstructorRequiredException
2524
import ai.deepsense.sparkutils
2625

2726
/**
2827
* Holds methods used for manipulating objects representing types.
2928
*/
3029
object TypeUtils {
31-
private val mirror = ru.runtimeMirror(getClass.getClassLoader)
30+
private def classMirror(c: Class[_]) = ru.runtimeMirror(c.getClassLoader)
31+
32+
def classToType[T](c: Class[T]): ru.Type = classMirror(c).classSymbol(c).toType
3233

33-
def classToType(c: Class[_]): ru.Type = mirror.classSymbol(c).toType
34+
def typeToClass(t: ru.Type): Class[_] = classMirror(TypeUtils.getClass).runtimeClass(t.typeSymbol.asClass)
3435

35-
def typeToClass(t: ru.Type): Class[_] = mirror.runtimeClass(t.typeSymbol.asClass)
36+
def typeTagToClass[T](t: ru.TypeTag[T]): Class[T] =
37+
t.mirror.runtimeClass(t.tpe.typeSymbol.asClass).asInstanceOf[Class[T]]
3638

3739
def symbolToType(s: ru.Symbol): ru.Type = s.asClass.toType
3840

@@ -41,26 +43,30 @@ object TypeUtils {
4143
def isAbstract(c: Class[_]): Boolean =
4244
sparkutils.TypeUtils.isAbstract(classToType(c).typeSymbol.asClass)
4345

44-
def constructorForClass(c: Class[_]): Option[Constructor[_]] = {
46+
def constructorForClass[T](c: Class[T]): Option[Constructor[T]] = {
4547
val constructors = c.getConstructors
4648
val isParameterLess: (Constructor[_] => Boolean) = constructor =>
4749
constructor.getParameterTypes.isEmpty
48-
constructors.find(isParameterLess)
50+
constructors.find(isParameterLess).map(_.asInstanceOf[Constructor[T]])
51+
}
52+
53+
def constructorForTypeTag[T](t: ru.TypeTag[T]): Option[Constructor[T]] = {
54+
constructorForClass(typeTagToClass(t))
4955
}
5056

5157
def constructorForType(t: ru.Type): Option[Constructor[_]] = {
5258
constructorForClass(typeToClass(t))
5359
}
5460

55-
def createInstance[T](constructor: Constructor[_]): T = {
56-
constructor.newInstance().asInstanceOf[T]
61+
def createInstance[T](constructor: Constructor[T]): T = {
62+
constructor.newInstance()
5763
}
5864

5965
def instanceOfType[T](typeTag: ru.TypeTag[T]): T = {
60-
val constructorT = constructorForType(typeTag.tpe).getOrElse {
66+
val constructorT = constructorForTypeTag(typeTag).getOrElse {
6167
throw NoArgumentConstructorRequiredException(typeTag.tpe.typeSymbol.asClass.name.decodedName.toString)
6268
}
63-
createInstance(constructorT).asInstanceOf[T]
69+
createInstance(constructorT)
6470
}
6571

6672
private val TypeSeparator = " with "

seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/ConcreteClassNode.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ private[doperable] class ConcreteClassNode(javaType: Class[_]) extends ClassNode
3232
* Invokes first constructor and assumes that it takes no parameters.
3333
*/
3434
private[doperable] def createInstance[T <: DOperable]: T = {
35-
TypeUtils.createInstance[T](constructor)
35+
TypeUtils.createInstance[T](constructor.asInstanceOf[Constructor[T]])
3636
}
3737

3838
override private[doperable] def subclassesInstances: Set[ConcreteClassNode] = {

seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/catalogs/doperable/TraitNode.scala

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package ai.deepsense.deeplang.catalogs.doperable
1818

1919
import scala.reflect.runtime.{universe => ru}
20-
2120
import ai.deepsense.deeplang.TypeUtils
2221

2322
/**

seahorse-workflow-executor/deeplang/src/main/scala/ai/deepsense/deeplang/params/ParamsSequence.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ case class ParamsSequence[T <: Params](
4040
JsArray(cells: _*)
4141
}
4242

43-
private val constructor: Constructor[_] = TypeUtils.constructorForType(tag.tpe).getOrElse {
43+
private val constructor: Constructor[_] = TypeUtils.constructorForTypeTag(tag).getOrElse {
4444
throw NoArgumentConstructorRequiredException(tag.tpe.typeSymbol.asClass.name.decodedName.toString)
4545
}
4646

0 commit comments

Comments
 (0)