forked from benlings/scala-guice
-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
major rewrite to typeTags instead of the deprecated manifest. So wild…
…card types are converted correctly
- Loading branch information
Showing
7 changed files
with
210 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 110 additions & 0 deletions
110
src/main/scala/net/codingwell/scalaguice/TypeConversions.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package net.codingwell.scalaguice | ||
|
||
import java.lang.reflect.{Type => JavaType} | ||
|
||
import com.google.inject.internal.MoreTypes.WildcardTypeImpl | ||
import com.google.inject.util.Types._ | ||
|
||
import scala.reflect.runtime.universe | ||
import scala.reflect.runtime.universe._ | ||
import scala.reflect.runtime.universe.{Type => ScalaType, WildcardType => ScalaWildCardType} | ||
|
||
/** | ||
* Copyright (C) 22/04/2018 - REstore NV | ||
*/ | ||
private [scalaguice] object TypeConversions { | ||
private val mirror = runtimeMirror(getClass.getClassLoader) | ||
private val anyType = typeOf[Any] | ||
|
||
object ArrayType { | ||
private val arraySymbol = symbolOf[Array[_]] | ||
|
||
def unapply(tpe: ScalaType): Option[ScalaType] = { | ||
tpe match { | ||
case TypeRef(pre, sym, args) if sym == arraySymbol => args.headOption | ||
case _ => None | ||
} | ||
|
||
} | ||
} | ||
|
||
object ClassType { | ||
|
||
def unapply(tpe: ScalaType): Option[(ClassSymbol, Seq[ScalaType])] = { | ||
tpe match { | ||
case TypeRef(pre, sym, args) if sym.isClass => Some((sym.asClass, args)) | ||
case _ => None | ||
} | ||
|
||
} | ||
} | ||
|
||
object WildcardType { | ||
private val bottomType = typeOf[Nothing] | ||
private val topType = typeOf[Any] | ||
def unapply(tpe: ScalaType): Option[(List[ScalaType], List[ScalaType])] = { | ||
tpe match { | ||
case BoundedWildcardType(bounds) => unapply(bounds) | ||
case TypeRef(pre, sym, args) if sym.isType && !sym.isSpecialized => | ||
unapply(sym.asType.info) | ||
case TypeBounds(lo, hi) => | ||
val lowerBounds = if(lo =:= bottomType) Nil else List(lo) | ||
Some((lowerBounds, List(hi))) | ||
case _ => None | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
def scalaTypeToJavaType(scalaType: ScalaType): JavaType = { | ||
scalaType.dealias match { | ||
case `anyType` => classOf[java.lang.Object] | ||
case ExistentialType(symbols, underlying) => scalaTypeToJavaType(underlying) | ||
case ArrayType(argType) => arrayOf(scalaTypeToJavaType(argType)) | ||
case ClassType(symbol, args) => { | ||
val rawType = mirror.runtimeClass(symbol) | ||
val ownerType = findOwnerOf(symbol) | ||
args.map(scalaTypeToJavaType) match { | ||
case Nil => toWrapper(rawType) | ||
case mappedArgs if ownerType.nonEmpty => newParameterizedTypeWithOwner(ownerType.get, rawType, mappedArgs:_*) | ||
case mappedArgs => newParameterizedType(rawType, mappedArgs:_*) | ||
} | ||
} | ||
case WildcardType(lowerBounds, upperBounds) => { | ||
val mappedUpperBounds = upperBounds.map(scalaTypeToJavaType).toArray | ||
val mappedLowerBounds = lowerBounds.map(scalaTypeToJavaType).toArray | ||
new WildcardTypeImpl(mappedUpperBounds, mappedLowerBounds) | ||
} | ||
case _ => throw new UnsupportedOperationException(s"Could not convert scalaType $scalaType to a javaType") | ||
} | ||
} | ||
|
||
private def findOwnerOf(symbol: universe.ClassSymbol): Option[JavaType] = { | ||
val owner = symbol.owner | ||
|
||
if (!owner.isPackage && (owner.isModuleClass && owner.owner.isPackage)) { //workaround for when owner is a top level object | ||
// here we need to resolve class without the $ suffix for some reason | ||
val clazz = mirror.staticClass(owner.asClass.fullName) | ||
Some(mirror.runtimeClass(clazz)) | ||
} else if (!owner.isPackage && owner.isClass) { | ||
Some(mirror.runtimeClass(owner.asClass)) | ||
} else { | ||
None | ||
} | ||
} | ||
|
||
private def toWrapper(c: JavaType) = c match { | ||
case java.lang.Byte.TYPE => classOf[java.lang.Byte] | ||
case java.lang.Short.TYPE => classOf[java.lang.Short] | ||
case java.lang.Character.TYPE => classOf[java.lang.Character] | ||
case java.lang.Integer.TYPE => classOf[java.lang.Integer] | ||
case java.lang.Long.TYPE => classOf[java.lang.Long] | ||
case java.lang.Float.TYPE => classOf[java.lang.Float] | ||
case java.lang.Double.TYPE => classOf[java.lang.Double] | ||
case java.lang.Boolean.TYPE => classOf[java.lang.Boolean] | ||
case java.lang.Void.TYPE => classOf[java.lang.Void] | ||
case cls => cls | ||
} | ||
|
||
} |
Oops, something went wrong.