diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2014-01-30 10:01:31 +0300 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2014-02-14 23:51:22 +0100 |
commit | 114c99691674873393223a11a9aa9168c3f41d77 (patch) | |
tree | d855c67a565faf4dbe414cc8f1a1aaff68a8df79 /src/compiler/scala/reflect/reify | |
parent | 27805570cbf130260eab04fe1491e58fa95e8108 (diff) | |
download | scala-114c99691674873393223a11a9aa9168c3f41d77.tar.gz scala-114c99691674873393223a11a9aa9168c3f41d77.tar.bz2 scala-114c99691674873393223a11a9aa9168c3f41d77.zip |
establishes scala.reflect.api#internal
Reflection API exhibits a tension inherent to experimental things:
on the one hand we want it to grow into a beautiful and robust API,
but on the other hand we have to deal with immaturity of underlying mechanisms
by providing not very pretty solutions to enable important use cases.
In Scala 2.10, which was our first stab at reflection API, we didn't
have a systematic approach to dealing with this tension, sometimes exposing
too much of internals (e.g. Symbol.deSkolemize) and sometimes exposing
too little (e.g. there's still no facility to change owners, to do typing
transformations, etc). This resulted in certain confusion with some internal
APIs living among public ones, scaring the newcomers, and some internal APIs
only available via casting, which requires intimate knowledge of the
compiler and breaks compatibility guarantees.
This led to creation of the `internal` API module for the reflection API,
which provides advanced APIs necessary for macros that push boundaries
of the state of the art, clearly demarcating them from the more or less
straightforward rest and providing compatibility guarantees on par with
the rest of the reflection API.
This commit does break source compatibility with reflection API in 2.10,
but the next commit is going to introduce a strategy of dealing with that.
Diffstat (limited to 'src/compiler/scala/reflect/reify')
3 files changed, 30 insertions, 30 deletions
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala index a90a3a338b..a6b69e239f 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala @@ -45,21 +45,21 @@ trait GenTypes { case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic => val module = reify(clazz.sourceModule) val moduleClass = Select(Select(module, nme.asModule), nme.moduleClass) - mirrorFactoryCall(nme.ThisType, moduleClass) - case tpe @ ThisType(_) => - reifyProduct(tpe) + mirrorBuildCall(nme.ThisType, moduleClass) + case tpe @ ThisType(sym) => + reifyBuildCall(nme.ThisType, sym) case tpe @ SuperType(thistpe, supertpe) => - reifyProduct(tpe) + reifyBuildCall(nme.SuperType, thistpe, supertpe) case tpe @ SingleType(pre, sym) => - reifyProduct(tpe) + reifyBuildCall(nme.SingleType, pre, sym) case tpe @ ConstantType(value) => - mirrorFactoryCall(nme.ConstantType, reifyProduct(value)) + mirrorBuildCall(nme.ConstantType, reifyProduct(value)) case tpe @ TypeRef(pre, sym, args) => - reifyProduct(tpe) + reifyBuildCall(nme.TypeRef, pre, sym, args) case tpe @ TypeBounds(lo, hi) => - reifyProduct(tpe) + reifyBuildCall(nme.TypeBounds, lo, hi) case tpe @ NullaryMethodType(restpe) => - reifyProduct(tpe) + reifyBuildCall(nme.NullaryMethodType, restpe) case tpe @ AnnotatedType(anns, underlying) => reifyAnnotatedType(tpe) case _ => @@ -119,7 +119,8 @@ trait GenTypes { // todo. write a test for this if (ReflectRuntimeUniverse == NoSymbol) CannotConvertManifestToTagWithoutScalaReflect(tpe, manifestInScope) val cm = typer.typed(Ident(ReflectRuntimeCurrentMirror)) - val tagTree = gen.mkMethodCall(ReflectRuntimeUniverse, nme.manifestToTypeTag, List(tpe), List(cm, manifestInScope)) + val internal = gen.mkAttributedSelect(gen.mkAttributedRef(ReflectRuntimeUniverse), UniverseInternal) + val tagTree = gen.mkMethodCall(Select(internal, nme.manifestToTypeTag), List(tpe), List(cm, manifestInScope)) Select(Apply(Select(tagTree, nme.in), List(Ident(nme.MIRROR_SHORT))), nme.tpe) case _ => EmptyTree @@ -157,13 +158,13 @@ trait GenTypes { */ private def reifySemiConcreteTypeMember(tpe: Type): Tree = tpe match { case tpe @ TypeRef(pre @ SingleType(prepre, presym), sym, args) if sym.isAbstractType && !sym.isExistential => - mirrorFactoryCall(nme.TypeRef, reify(pre), mirrorBuildCall(nme.selectType, reify(sym.owner), reify(sym.name.toString)), reify(args)) + mirrorBuildCall(nme.TypeRef, reify(pre), mirrorBuildCall(nme.selectType, reify(sym.owner), reify(sym.name.toString)), reify(args)) } /** Reify an annotated type, i.e. the one that makes us deal with AnnotationInfos */ private def reifyAnnotatedType(tpe: AnnotatedType): Tree = { val AnnotatedType(anns, underlying) = tpe - mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying)) + mirrorBuildCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying)) } /** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */ @@ -172,25 +173,25 @@ trait GenTypes { def reifyScope(scope: Scope): Tree = { scope foreach reifySymDef - mirrorCall(nme.newScopeWith, scope.toList map reify: _*) + mirrorBuildCall(nme.newScopeWith, scope.toList map reify: _*) } tpe match { case tpe @ RefinedType(parents, decls) => reifySymDef(tpe.typeSymbol) - mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) + mirrorBuildCall(nme.RefinedType, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) case tpe @ ExistentialType(tparams, underlying) => tparams foreach reifySymDef - mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) + reifyBuildCall(nme.ExistentialType, tparams, underlying) case tpe @ ClassInfoType(parents, decls, clazz) => reifySymDef(clazz) - mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) + mirrorBuildCall(nme.ClassInfoType, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) case tpe @ MethodType(params, restpe) => params foreach reifySymDef - mirrorFactoryCall(tpe, reify(params), reify(restpe)) + reifyBuildCall(nme.MethodType, params, restpe) case tpe @ PolyType(tparams, underlying) => tparams foreach reifySymDef - mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) + reifyBuildCall(nme.PolyType, tparams, underlying) case _ => throw new Error("internal error: %s (%s) is not supported".format(tpe, tpe.kind)) } diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala index d052127956..cfc42e31a9 100644 --- a/src/compiler/scala/reflect/reify/utils/Extractors.scala +++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala @@ -183,12 +183,12 @@ trait Extractors { tree match { case ValDef(_, name, _, Apply( - Select(Select(uref1 @ Ident(_), build1), freeTermFactory), + Select(Select(Select(uref1 @ Ident(_), internal1), rs1), freeTermFactory), _ :+ - ApplyCall(Select(Select(uref2 @ Ident(_), build2), flagsRepr), List(Literal(Constant(flags: Long)))) :+ + ApplyCall(Select(Select(Select(uref2 @ Ident(_), internal2), rs2), flagsRepr), List(Literal(Constant(flags: Long)))) :+ Literal(Constant(origin: String)))) - if uref1.name == nme.UNIVERSE_SHORT && build1 == nme.build && acceptFreeTermFactory(freeTermFactory) && - uref2.name == nme.UNIVERSE_SHORT && build2 == nme.build && flagsRepr == nme.FlagsRepr => + if uref1.name == nme.UNIVERSE_SHORT && internal1 == nme.internal && rs1 == nme.reificationSupport && acceptFreeTermFactory(freeTermFactory) && + uref2.name == nme.UNIVERSE_SHORT && internal2 == nme.internal && rs2 == nme.reificationSupport && flagsRepr == nme.FlagsRepr => Some((uref1, name, reifyBinding(tree), flags, origin)) case _ => None @@ -201,8 +201,8 @@ trait Extractors { object FreeRef { def unapply(tree: Tree): Option[(Tree, TermName)] = tree match { - case Apply(Select(Select(uref @ Ident(_), build), ident), List(Ident(name: TermName))) - if build == nme.build && ident == nme.Ident && name.startsWith(nme.REIFY_FREE_PREFIX) => + case Apply(Select(Select(Select(uref @ Ident(_), internal), rs), ident), List(Ident(name: TermName))) + if internal == nme.internal && rs == nme.reificationSupport && ident == nme.Ident && name.startsWith(nme.REIFY_FREE_PREFIX) => Some((uref, name)) case _ => None @@ -213,15 +213,15 @@ trait Extractors { def unapply(tree: Tree): Option[(Tree, TermName, Long, Boolean)] = tree match { case ValDef(_, name, _, Apply( - Select(Select(uref1 @ Ident(_), build1), newNestedSymbol), + Select(Select(Select(uref1 @ Ident(_), internal1), rs1), newNestedSymbol), List( _, _, _, - ApplyCall(Select(Select(uref2 @ Ident(_), build2), flagsRepr), List(Literal(Constant(flags: Long)))), + ApplyCall(Select(Select(Select(uref2 @ Ident(_), internal2), rs2), flagsRepr), List(Literal(Constant(flags: Long)))), Literal(Constant(isClass: Boolean))))) - if uref1.name == nme.UNIVERSE_SHORT && build1 == nme.build && newNestedSymbol == nme.newNestedSymbol && - uref2.name == nme.UNIVERSE_SHORT && build2 == nme.build && flagsRepr == nme.FlagsRepr => + if uref1.name == nme.UNIVERSE_SHORT && internal1 == nme.internal && rs1 == nme.reificationSupport && newNestedSymbol == nme.newNestedSymbol && + uref2.name == nme.UNIVERSE_SHORT && internal2 == nme.internal && rs2 == nme.reificationSupport && flagsRepr == nme.FlagsRepr => Some((uref1, name, flags, isClass)) case _ => None diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala index e37b861461..3b91d28360 100644 --- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala +++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala @@ -32,7 +32,7 @@ trait NodePrinters { s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List") s = "List\\[.*?\\]".r.replaceAllIn(s, "List") s = s.replace("immutable.this.Nil", "List()") - s = """build\.FlagsRepr\((\d+)[lL]\)""".r.replaceAllIn(s, m => { + s = """internal\.reificationSupport\.FlagsRepr\((\d+)[lL]\)""".r.replaceAllIn(s, m => { flagsAreUsed = true show(m.group(1).toLong) }) @@ -76,7 +76,6 @@ trait NodePrinters { if (mirrorIsUsed) printout += mirror.replace("Mirror[", "scala.reflect.api.Mirror[").trim val imports = scala.collection.mutable.ListBuffer[String]() imports += nme.UNIVERSE_SHORT.toString - // if (buildIsUsed) imports += nme.build if (mirrorIsUsed) imports += nme.MIRROR_SHORT.toString if (flagsAreUsed) imports += nme.Flag.toString printout += s"""import ${imports map (_ + "._") mkString ", "}""" |