Permalink
Browse files

Fix parsing of primitive generic type information

  • Loading branch information...
1 parent 0388577 commit 7a986eef7d93e83286ceae69c8fe17e2241e69c3 Joni Freeman committed May 28, 2011
@@ -379,7 +379,7 @@ object JsonParser {
}
}
- def near = new String(segment, (cur-20) max 0, (cur+20) min offset)
+ def near = new String(segment, (cur-20) max 0, 40 min (offset - cur + 20))
def release = segments.foreach(Segments.release)
@@ -111,7 +111,7 @@ private[json] object Meta {
val typeArgs = x.getActualTypeArguments.toList.zipWithIndex
.map { case (t, idx) =>
if (t == classOf[java.lang.Object])
- ScalaSigReader.readConstructor(context.argName, context.containingClass, context.allArgs.map(_._1))
+ ScalaSigReader.readConstructor(context.argName, context.containingClass, idx, context.allArgs.map(_._1))
else t
}
Some(mkParameterizedType(x.getRawType, typeArgs))
@@ -231,13 +231,13 @@ private[json] object Meta {
}
try {
val names = nameReader.lookupParameterNames(c).map(clean)
- val types = c.getGenericParameterTypes.toList map {
- case v: TypeVariable[_] =>
+ val types = c.getGenericParameterTypes.toList.zipWithIndex map {
+ case (v: TypeVariable[_], idx) =>
val arg = typeArgs.getOrElse(v, v)
if (arg == classOf[java.lang.Object])
- context.map(ctx => ScalaSigReader.readConstructor(ctx.argName, ctx.containingClass, ctx.allArgs.map(_._1))).getOrElse(arg)
+ context.map(ctx => ScalaSigReader.readConstructor(ctx.argName, ctx.containingClass, idx, ctx.allArgs.map(_._1))).getOrElse(arg)
else arg
- case x => x
+ case (x, _) => x
}
names.toList.zip(types)
} catch {
@@ -266,7 +266,7 @@ private[json] object Meta {
case ptype: ParameterizedType => ptype.getActualTypeArguments()(i) match {
case c: Class[_] =>
if (c == classOf[java.lang.Object])
- ScalaSigReader.readConstructor(context.argName, context.containingClass, context.allArgs.map(_._1))
+ ScalaSigReader.readConstructor(context.argName, context.containingClass, i, context.allArgs.map(_._1))
else c
case p: ParameterizedType => p.getRawType.asInstanceOf[Class[_]]
case x => fail("do not know how to get type parameter from " + x)
@@ -20,10 +20,10 @@ package json
import scala.tools.scalap.scalax.rules.scalasig._
private[json] object ScalaSigReader {
- def readConstructor(argName: String, clazz: Class[_], argNames: List[String]): Class[_] = {
+ def readConstructor(argName: String, clazz: Class[_], typeArgIndex: Int, argNames: List[String]): Class[_] = {
val cl = findClass(clazz)
val cstr = findConstructor(cl, argNames).getOrElse(Meta.fail("Can't find constructor " + clazz))
- findArgType(cstr, argNames.indexOf(argName))
+ findArgType(cstr, argNames.indexOf(argName), typeArgIndex)
}
def readField(name: String, clazz: Class[_], typeArgIndex: Int): Class[_] = {
@@ -60,17 +60,22 @@ private[json] object ScalaSigReader {
private def findField(c: ClassSymbol, name: String): Option[MethodSymbol] =
(c.children collect { case m: MethodSymbol if m.name == name => m }).headOption
- private def findArgType(s: MethodSymbol, argIdx: Int): Class[_] = {
+ private def findArgType(s: MethodSymbol, argIdx: Int, typeArgIndex: Int): Class[_] = {
def findPrimitive(t: Type): Symbol = t match {
+ case TypeRefType(ThisType(_), symbol, _) if isPrimitive(symbol) => symbol
case TypeRefType(_, _, TypeRefType(ThisType(_), symbol, _) :: xs) => symbol
- case TypeRefType(_, _, (ref @ TypeRefType(_, _, _)) :: xs) => findPrimitive(ref)
+ case TypeRefType(_, _, args) =>
+ args(typeArgIndex) match {
+ case ref @ TypeRefType(_, _, _) => findPrimitive(ref)
+ case x => Meta.fail("Unexpected type info " + x)
+ }
case x => Meta.fail("Unexpected type info " + x)
}
toClass(findPrimitive(s.children(argIdx).asInstanceOf[SymbolInfoSymbol].infoType))
}
private def findArgTypeF(s: MethodSymbol, typeArgIdx: Int): Class[_] = {
- // FIXME can be removed when 2.8 no loner needs to supported.
+ // FIXME can be removed when 2.8 no longer needs to be supported.
// 2.8 does not have NullaryMethodType, work around that.
/*
val t = s.infoType match {
@@ -99,6 +104,8 @@ private[json] object ScalaSigReader {
case _ => classOf[AnyRef]
}
+ private def isPrimitive(s: Symbol) = toClass(s) != classOf[AnyRef]
+
private def findScalaSig(clazz: Class[_]): Option[ScalaSig] =
ScalaSigParser.parse(clazz).orElse(findScalaSig(clazz.getDeclaringClass))
}
@@ -117,8 +117,17 @@ object SerializationBugs extends Specification {
val ser = Serialization.write(o)
ser mustEqual """{"x":{"some":"data"}}"""
}
+
+ "Map with Map value" in {
+ val a = Map("a" -> Map("a" -> 5))
+ val b = Map("b" -> 1)
+ val str = Serialization.write(MapWithMap(a, b))
+ read[MapWithMap](str) mustEqual MapWithMap(a, b)
+ }
}
+case class MapWithMap(a: Map[String, Map[String, Int]], b: Map[String, Int])
+
case class LongList(xs: List[Num])
case class Num(x: Int)

0 comments on commit 7a986ee

Please sign in to comment.