Skip to content
This repository was archived by the owner on Nov 28, 2017. It is now read-only.

Commit 628bf1b

Browse files
committed
support both scala 2.10 and 2.11
1 parent e59ee5b commit 628bf1b

File tree

7 files changed

+61
-52
lines changed

7 files changed

+61
-52
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
language: scala
22
scala:
33
- 2.11.1
4+
- 2.10.4
45
branches:
56
only:
67
- master

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ You can find the [documentation on the site](http://muster.json4s.org/docs)
1111

1212
## Getting the library
1313

14-
This only works with scala 2.11.
14+
This works with scala 2.10 and up.
1515
The library is published to maven central so you can get it with:
1616

1717
```scala

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ lazy val argonaut = project in file("codecs/argonaut") dependsOn (core % "compil
1818

1919
lazy val caliperBenchmarks = project in file("benchmarks/caliper") dependsOn (core % "compile->compile;test->test", jackson % "compile->compile;test->test", json4s % "compile->compile;test->test", playJson % "compile->compile;test->test", argonaut % "compile->compile;test->test", jawn % "compile->compile;test->test", strings % "compile->compile;test->test")
2020

21-
scalaVersion in ThisBuild := "2.11.1"
21+
scalaVersion in ThisBuild := "2.10.4"
2222

2323
crossScalaVersions in ThisBuild := Seq("2.10.4", "2.11.1")
2424

core/src/main/scala/muster/helper.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.sql.Timestamp
77
import scala.annotation.tailrec
88

99
/** A utility class for the generator macros */
10-
class Helper[C <: blackbox.Context](val c: C) {
10+
class Helper[C <: Context](val c: C) {
1111
import c.universe._
1212

1313
private val primitiveTypes = Set[Type](c.typeOf[String], c.typeOf[Int], c.typeOf[Long], c.typeOf[Double],
@@ -25,7 +25,7 @@ class Helper[C <: blackbox.Context](val c: C) {
2525
def isEnum(tpe: c.Type) = tpe <:< c.typeOf[Enumeration#Value]
2626

2727
def caseClassFields(tpe: c.universe.Type): Seq[Symbol] = {
28-
tpe.decls.toVector.filter {
28+
tpe.declarations.toVector.filter {
2929
v =>
3030
if (v.isTerm) {
3131
val t = v.asTerm
@@ -80,11 +80,11 @@ class Helper[C <: blackbox.Context](val c: C) {
8080
v.isTerm && v.asTerm.isMethod && v.isPublic &&
8181
(v.asTerm.asMethod.isSetter || v.asTerm.name.decodedName.toString.startsWith("set")) &&
8282
varNames.exists(vn => s"set${vn.capitalize}" == methodName || s"${vn}_=" == methodName) &&
83-
v.asMethod.paramLists.flatten.length == 1
83+
v.asMethod.paramss.flatten.length == 1
8484
}
8585

8686
def getSetters(tpe: Type): List[Symbol] = {
87-
val ctorParams = tpe.member(termNames.CONSTRUCTOR).asTerm.alternatives.map(_.asMethod.paramLists.flatten.map(_.name)).flatten.toSet
87+
val ctorParams = tpe.member(nme.CONSTRUCTOR).asTerm.alternatives.map(_.asMethod.paramss.flatten.map(_.name)).flatten.toSet
8888
val varNames = vars(tpe).filter(sym => sym.asTerm.isProtected || sym.asTerm.isPrivate && !ctorParams(sym.name)).map(_.name.decodedName.toString.trim).toSet
8989
(tpe.members filter (isJavaOrScalaSetter(varNames, _))).toList
9090
}
@@ -94,18 +94,18 @@ class Helper[C <: blackbox.Context](val c: C) {
9494
v.isTerm && v.asTerm.isMethod && v.isPublic &&
9595
(v.asTerm.asMethod.isGetter || v.asTerm.name.decodedName.toString.startsWith("get")) &&
9696
varNames.exists(vn => s"get${vn.capitalize}" == methodName || vn == methodName) &&
97-
v.asMethod.paramLists.flatten.length == 0
97+
v.asMethod.paramss.flatten.length == 0
9898
}
9999

100100
def getGetters(tpe: Type): List[Symbol] = {
101-
val ctorParams = tpe.member(termNames.CONSTRUCTOR).asTerm.alternatives.map(_.asMethod.paramLists.flatten.map(_.name)).flatten.toSet
101+
val ctorParams = tpe.member(nme.CONSTRUCTOR).asTerm.alternatives.map(_.asMethod.paramss.flatten.map(_.name)).flatten.toSet
102102
val valNames = vals(tpe).filterNot(sym => sym.asTerm.isProtected || sym.asTerm.isPrivate ).map(_.name.decodedName.toString.trim).toSet
103103
val varNames = vars(tpe).filter(sym => sym.asTerm.isProtected || sym.asTerm.isPrivate).map(_.name.decodedName.toString.trim).toSet
104104
(tpe.members filter (isJavaOrScalaGetter(varNames ++ valNames ++ ctorParams.map(_.decodedName.toString.trim), _))).toList
105105
}
106106

107107
def enumValues(tpe: Type): List[Symbol] = {
108-
tpe.member(TermName("Value")).asTerm.alternatives.headOption.fold(List.empty[Symbol])({ vt =>
108+
tpe.member(newTermName("Value")).asTerm.alternatives.headOption.fold(List.empty[Symbol])({ vt =>
109109
val valueType = vt.asMethod.returnType
110110
tpe.members.filter(sym => !sym.isMethod && sym.typeSignature.baseType(valueType.typeSymbol) =:= valueType).toList
111111
})

core/src/main/scala/muster/input/Consumer.scala

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ object Consumer {
310310
*/
311311
implicit def consumer[T]: Consumer[T] = macro consumerImpl[T]
312312

313-
def consumerImpl[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[Consumer[T]] = {
313+
def consumerImpl[T: c.WeakTypeTag](c: Context): c.Expr[Consumer[T]] = {
314314
import c.universe._
315315

316316
val primitiveMap =
@@ -333,7 +333,8 @@ object Consumer {
333333
val nullNodeDefault = reify(NullNode).tree
334334

335335
def buildValue(_tpe: Type, reader: c.Expr[Any], methodSuffix: String = "", args: List[Tree] = Nil, default: Tree = nullNodeDefault): (Tree, Tree) = {
336-
val tpe = _tpe.dealias
336+
// TODO: put in separate file for 2.10, 2.11 support, was _tpe.dealias
337+
val tpe = _tpe.normalize
337338
val t = appliedType(weakTypeOf[Consumer[Any]].typeConstructor, tpe :: Nil)
338339
c.inferImplicitValue(t) match {
339340
case EmptyTree => c.abort(c.enclosingPosition, s"Couldn't find a muster.input.Consumer[${t.typeSymbol.name.decodedName.toString}], try bringing an implicit value for ${tpe.typeSymbol.name.decodedName.toString} in scope by importing one or defining one.")
@@ -342,17 +343,17 @@ object Consumer {
342343
val rdrOpt: Tree = {
343344
if (helper.isPrimitive(tpe)) {
344345
val nm = primitiveMap(tpe)
345-
Apply(Select(reader.tree, TermName(s"read${nm}${methodSuffix}Opt")), args)
346+
Apply(Select(reader.tree, newTermName(s"read${nm}${methodSuffix}Opt")), args)
346347
} else if (helper.isOption(tpe)) {
347348
val agType = helper.resolveInnerOptionType(tpe)
348349
val nm = primitiveMap(agType)
349-
Apply(Select(reader.tree, TermName(s"read${nm}${methodSuffix}Opt")), args)
350+
Apply(Select(reader.tree, newTermName(s"read${nm}${methodSuffix}Opt")), args)
350351
} else if (helper.isSeq(tpe) || helper.isSet(tpe))
351-
Apply(Select(reader.tree, TermName(s"readArray${methodSuffix}Opt")), args)
352+
Apply(Select(reader.tree, newTermName(s"readArray${methodSuffix}Opt")), args)
352353
else if (helper.isEnum(tpe)) {
353-
Apply(Select(reader.tree, TermName(s"readString${methodSuffix}Opt")), args)
354+
Apply(Select(reader.tree, newTermName(s"readString${methodSuffix}Opt")), args)
354355
} else
355-
Apply(Select(reader.tree, TermName(s"readObject${methodSuffix}Opt")), args)
356+
Apply(Select(reader.tree, newTermName(s"readObject${methodSuffix}Opt")), args)
356357
}
357358

358359
(rdrOpt, resolved)
@@ -362,24 +363,24 @@ object Consumer {
362363
def setterDef(returnType: Type, reader: c.Expr[Any], fieldName: Tree, defVal: Tree = EmptyTree): Tree = {
363364
val t = appliedType(weakTypeOf[Consumer[Any]].typeConstructor, returnType :: Nil)
364365
val (definition, resolved) = buildValue(returnType, reader, "Field", List(fieldName), defVal)
365-
val fn = c.freshName("consumer$")
366-
val vn = TermName(fn)
366+
val fn = c.fresh("consumer$")
367+
val vn = newTermName(fn)
367368
val v = ValDef(Modifiers(), vn, TypeTree(t), resolved)
368-
val cn = c.freshName("node$")
369+
val cn = c.fresh("node$")
369370

370371
defVal match {
371372
case EmptyTree =>
372-
val noDefault = Apply(Select(definition, TermName("getOrElse")), nullNodeDefault :: Nil)
373-
val ce = c.Expr[AstNode[_]](Ident(TermName(cn)))
374-
val ct: Tree = ValDef(Modifiers(), TermName(cn), TypeTree(weakTypeOf[AstNode[_]]), noDefault)
375-
Block(v :: ct :: Nil, Apply(Select(Ident(vn), TermName("consume")), ce.tree :: Nil))
373+
val noDefault = Apply(Select(definition, newTermName("getOrElse")), nullNodeDefault :: Nil)
374+
val ce = c.Expr[AstNode[_]](Ident(newTermName(cn)))
375+
val ct: Tree = ValDef(Modifiers(), newTermName(cn), TypeTree(weakTypeOf[AstNode[_]]), noDefault)
376+
Block(v :: ct :: Nil, Apply(Select(Ident(vn), newTermName("consume")), ce.tree :: Nil))
376377
case defTree =>
377-
val ce = c.Expr[Option[AstNode[_]]](Ident(TermName(cn)))
378-
val ct: Tree = ValDef(Modifiers(), TermName(cn), TypeTree(weakTypeOf[Option[AstNode[_]]]), definition)
378+
val ce = c.Expr[Option[AstNode[_]]](Ident(newTermName(cn)))
379+
val ct: Tree = ValDef(Modifiers(), newTermName(cn), TypeTree(weakTypeOf[Option[AstNode[_]]]), definition)
379380
// val cons = Apply(Select(Ident(vn), TermName("consume")), ce.tree :: Nil)
380381
val res = reify(
381382
ce.splice match {
382-
case Some(n) => c.Expr(Apply(Select(Ident(vn), TermName("consume")), Ident(TermName("n")) :: Nil)).splice
383+
case Some(n) => c.Expr(Apply(Select(Ident(vn), newTermName("consume")), Ident(newTermName("n")) :: Nil)).splice
383384
case _ => c.Expr(defTree).splice
384385
})
385386
Block(v :: ct :: Nil, res.tree)
@@ -401,7 +402,7 @@ object Consumer {
401402
!(sym.isParamWithDefault || sym.typeSignature <:< typeOf[Option[_]])
402403
}
403404

404-
val expr = c.Expr[Set[String]](Apply(Select(Ident(TermName("Set")), TermName("apply")),
405+
val expr = c.Expr[Set[String]](Apply(Select(Ident(newTermName("Set")), newTermName("apply")),
405406
ctors.flatten.filter(isRequired).map(sym => Literal(Constant(sym.name.decodedName.toString)))
406407
))
407408

@@ -416,11 +417,11 @@ object Consumer {
416417

417418

418419

419-
val ctors: List[MethodSymbol] = tpe.member(termNames.CONSTRUCTOR)
420+
val ctors: List[MethodSymbol] = tpe.member(nme.CONSTRUCTOR)
420421
.asTerm.alternatives // List of constructors
421422
.map(_.asMethod) // method symbols
422-
.sortBy(-_.paramLists.flatten.size)
423-
val ifExprsAndParams = ctors.map(ctor => ctorCheckingExpr(ctor.paramLists)).zip(ctors.map(_.asMethod.paramLists))
423+
.sortBy(-_.paramss.flatten.size)
424+
val ifExprsAndParams = ctors.map(ctor => ctorCheckingExpr(ctor.paramss)).zip(ctors.map(_.asMethod.paramss))
424425

425426
ifElseTreeBuilder(ifExprsAndParams)
426427
}
@@ -433,14 +434,14 @@ object Consumer {
433434
// Change out the types if it has type parameters
434435
val pTpe = pSym.typeSignature.substituteTypes(sym.asClass.typeParams, tpeArgs)
435436
val fieldName = Literal(Constant(pSym.name.decodedName.toString))
436-
val pTnm = TermName(pSym.name.decodedName.toString)
437+
val pTnm = newTermName(pSym.name.decodedName.toString)
437438

438439
// If param has defaults, try to find the val in map, or call
439440
// default evaluation from its companion object
440441
// is the sym.companionSymbol.isTerm the best way to check for NoSymbol?
441442
// is there a way to get teh default values for the overloaded constructors?
442-
val tree = if (pSym.asTerm.isParamWithDefault && sym.companion.isTerm) {
443-
val defVal = Select(Ident(sym.companion), TermName("$lessinit$greater$default$" + (index + 1).toString))
443+
val tree = if (pSym.asTerm.isParamWithDefault && sym.companionSymbol.isTerm) {
444+
val defVal = Select(Ident(sym.companionSymbol), newTermName("$lessinit$greater$default$" + (index + 1).toString))
444445
// val defValG = Apply(Select(New(weakTypeOf[ConstantNode[_]])))
445446
setterDef(pTpe, reader, fieldName, defVal)
446447
} else {
@@ -449,13 +450,13 @@ object Consumer {
449450
(ValDef(Modifiers(), pTnm, TypeTree(pTpe), tree), Ident(pTnm))
450451
})
451452

452-
Block(params.flatMap(_.map(_._1)), params.foldLeft(Select(New(Ident(sym)), termNames.CONSTRUCTOR): Tree) { (ct, args) =>
453+
Block(params.flatMap(_.map(_._1)), params.foldLeft(Select(New(Ident(sym)), nme.CONSTRUCTOR): Tree) { (ct, args) =>
453454
Apply(ct, args.map(_._2))
454455
})
455456
}
456457

457-
val on = c.freshName("consumed$")
458-
val ot = TermName(on)
458+
val on = c.fresh("consumed$")
459+
val ot = newTermName(on)
459460
val otr: Tree = ValDef(Modifiers(), ot, TypeTree(tpe), pickConstructorTree(reify(reader.splice.keySet)))
460461

461462
val setterBlocks: List[Tree] = {
@@ -464,7 +465,7 @@ object Consumer {
464465
val stripped = pSym.name.decodedName.toString.replaceFirst("^set", "").replaceFirst("_=$", "")
465466
val name = if (needsLower) stripped(0).toLower + stripped.substring(1) else stripped
466467
val paramType = {
467-
val tp = pSym.asMethod.paramLists.head.head
468+
val tp = pSym.asMethod.paramss.head.head
468469
tp.typeSignatureIn(tpe)
469470
}
470471
Apply(Select(Ident(ot), pSym.name), setterDef(paramType, reader, Literal(Constant(name))) :: Nil)
@@ -484,7 +485,7 @@ object Consumer {
484485
new Consumer[T] {
485486
def consume(node: AstNode[_]): T = {
486487
node match {
487-
case obj: ObjectNode => c.Expr[T](buildObject(thisType, c.Expr[ObjectNode](Ident(TermName("obj"))))).splice
488+
case obj: ObjectNode => c.Expr[T](buildObject(thisType, c.Expr[ObjectNode](Ident(newTermName("obj"))))).splice
488489
case NullNode | UndefinedNode => null.asInstanceOf[T]
489490
case x => throw new MappingException(s"Got a ${x.getClass.getSimpleName} and expected an ObjectNode")
490491
}

core/src/main/scala/muster/output/Producer.scala

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -178,23 +178,30 @@ object Producer {
178178

179179
implicit def producer[T]: Producer[T] = macro producerImpl[T]
180180

181-
def producerImpl[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[Producer[T]] = {
181+
def producerImpl[T: c.WeakTypeTag](c: Context): c.Expr[Producer[T]] = {
182182
import c.universe._
183183
val helper = new Helper[c.type](c)
184-
val tpe = weakTypeOf[T].dealias
184+
// TODO: put in separate helper for 2.10, 2.11 differences, was weakTypeOf[T].dealias
185+
val tpe = weakTypeOf[T].normalize
185186

186187
def buildObject(target: Tree, formatter: Tree): Tree = {
187188
val TypeRef(_, sym: Symbol, _) = tpe
188189
val fields = helper.getGetters(tpe)
189190
val fieldTrees = fields map { fld =>
190-
val tt = fld.asMethod.typeSignatureIn(tpe).resultType
191+
// TODO: put in separate helper for 2.10, 2.11 differences, was fld.asMethod.typeSignatureIn(tpe).resultType
192+
val tt = fld.asMethod.typeSignatureIn(tpe) match {
193+
case NullaryMethodType(rtpe) => rtpe
194+
case MethodType(_, ret) => ret
195+
case PolyType(_, rtpe) => rtpe
196+
case rtpe => rtpe
197+
}
191198
val on = fld.name.decodedName.toString.trim
192199
val needsLower = on.startsWith("get")
193200
val stripped = on.replaceFirst("^get", "")
194201
val fieldName = if (needsLower) stripped(0).toLower + stripped.substring(1) else stripped
195202
val fieldPath = Select(target, fld.asTerm.name)
196203
// TODO: Add field renaming strategy
197-
val startFieldExpr = Apply(Select(formatter, TermName("startField")), Literal(Constant(fieldName)) :: Nil)
204+
val startFieldExpr = Apply(Select(formatter, newTermName("startField")), Literal(Constant(fieldName)) :: Nil)
198205

199206
val pTpe = appliedType(weakTypeOf[Producer[Any]], tt::Nil)
200207
val fVal: List[Tree] = c.inferImplicitValue(pTpe) match {
@@ -203,23 +210,23 @@ object Producer {
203210
// error returns unit
204211
c.abort(c.enclosingPosition, s"Couldn't find an implicit $pTpe, try defining one or bringing one into scope")
205212
case x =>
206-
val pn = c.freshName("producer$")
207-
val ptn = TermName(pn)
213+
val pn = c.fresh("producer$")
214+
val ptn = newTermName(pn)
208215
val pv: Tree = ValDef(Modifiers(), ptn, TypeTree(pTpe), x)
209-
val fn = c.freshName("value$")
210-
val ftn = TermName(fn)
216+
val fn = c.fresh("value$")
217+
val ftn = newTermName(fn)
211218
val fv: Tree = ValDef(Modifiers(), ftn, TypeTree(tt), fieldPath)
212-
val write: Tree = Apply(Select(Ident(ptn), TermName("produce")), Ident(ftn) :: formatter :: Nil)
219+
val write: Tree = Apply(Select(Ident(ptn), newTermName("produce")), Ident(ftn) :: formatter :: Nil)
213220
fv :: pv :: write :: Nil
214221
}
215222
startFieldExpr :: fVal
216223
}
217224
Block(
218225
Apply(
219-
Select(formatter, TermName("startObject")),
226+
Select(formatter, newTermName("startObject")),
220227
Literal(Constant(sym.name.decodedName.toString))::Nil) ::
221228
fieldTrees.reverse.flatten,
222-
Apply(Select(formatter, TermName("endObject")), Nil))
229+
Apply(Select(formatter, newTermName("endObject")), Nil))
223230

224231
}
225232

@@ -228,7 +235,7 @@ object Producer {
228235
reify {
229236
new Producer[T] {
230237
def produce(value: T, formatter: OutputFormatter[_]): Unit = {
231-
c.Expr(buildObject(Ident(TermName("value")), Ident(TermName("formatter")))).splice
238+
c.Expr(buildObject(Ident(newTermName("value")), Ident(newTermName("formatter")))).splice
232239
}
233240
}
234241
}
@@ -276,7 +283,7 @@ object Producer {
276283
*
277284
* @tparam T the type of value this producer knows about
278285
*/
279-
@implicitNotFound("Couldn't find a producer for ${T}. Try importing muster._ or to implement a muster.Consumable")
286+
@implicitNotFound("Couldn't find a producer for ${T}. Try importing muster._ or to implement a muster.Producer")
280287
trait Producer[T] {
281288
def produce(value: T, formatter: OutputFormatter[_])
282289
}

core/src/main/scala/muster/package.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
* Getting the library
1111
*
12-
* This only works with scala 2.11.
12+
* This works with scala 2.10 and up.
1313
* Check the [[https://github.com/json4s/muster/releases releases page]] for the latest version.
1414
* The library is published to maven central so you can get it with:
1515
*

0 commit comments

Comments
 (0)