summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/internal/transform/UnCurry.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-07-19 13:57:37 +0000
committerMartin Odersky <odersky@gmail.com>2011-07-19 13:57:37 +0000
commit970d4132b66eb77fa0c3d1d2626a1e377bea6ad4 (patch)
tree1ca314de18a1436b1d62f1814fa5f3f70a0ec357 /src/compiler/scala/reflect/internal/transform/UnCurry.scala
parent44b9cf0ca9606f531218deefe7792b4476552291 (diff)
downloadscala-970d4132b66eb77fa0c3d1d2626a1e377bea6ad4.tar.gz
scala-970d4132b66eb77fa0c3d1d2626a1e377bea6ad4.tar.bz2
scala-970d4132b66eb77fa0c3d1d2626a1e377bea6ad4.zip
Refactored infoTransformer functionality from n...
Refactored infoTransformer functionality from nsc.transform to reflect.internal.transform. Needed so that we can find Java methods that correspond to Scala methods. Review by extempore.
Diffstat (limited to 'src/compiler/scala/reflect/internal/transform/UnCurry.scala')
-rw-r--r--src/compiler/scala/reflect/internal/transform/UnCurry.scala70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/compiler/scala/reflect/internal/transform/UnCurry.scala b/src/compiler/scala/reflect/internal/transform/UnCurry.scala
new file mode 100644
index 0000000000..1d63aa4582
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/transform/UnCurry.scala
@@ -0,0 +1,70 @@
+package scala.reflect
+package internal
+package transform
+
+import Flags._
+
+trait UnCurry {
+
+ val global: SymbolTable
+ import global._
+ import definitions._
+
+ private def expandAlias(tp: Type): Type = if (!tp.isHigherKinded) tp.normalize else tp
+
+ private def isUnboundedGeneric(tp: Type) = tp match {
+ case t @ TypeRef(_, sym, _) => sym.isAbstractType && !(t <:< AnyRefClass.tpe)
+ case _ => false
+ }
+
+ protected val uncurry: TypeMap = new TypeMap {
+ def apply(tp0: Type): Type = {
+ // tp0.typeSymbolDirect.initialize
+ val tp = expandAlias(tp0)
+ tp match {
+ case MethodType(params, MethodType(params1, restpe)) =>
+ apply(MethodType(params ::: params1, restpe))
+ case MethodType(params, ExistentialType(tparams, restpe @ MethodType(_, _))) =>
+ assert(false, "unexpected curried method types with intervening existential")
+ tp0
+ case MethodType(h :: t, restpe) if h.isImplicit =>
+ apply(MethodType(h.cloneSymbol.resetFlag(IMPLICIT) :: t, restpe))
+ case NullaryMethodType(restpe) =>
+ apply(MethodType(List(), restpe))
+ case TypeRef(pre, ByNameParamClass, List(arg)) =>
+ apply(functionType(List(), arg))
+ case TypeRef(pre, RepeatedParamClass, args) =>
+ apply(appliedType(SeqClass.typeConstructor, args))
+ case TypeRef(pre, JavaRepeatedParamClass, args) =>
+ apply(arrayType(
+ if (isUnboundedGeneric(args.head)) ObjectClass.tpe else args.head))
+ case _ =>
+ expandAlias(mapOver(tp))
+ }
+ }
+ }
+
+ private val uncurryType = new TypeMap {
+ def apply(tp0: Type): Type = {
+ val tp = expandAlias(tp0)
+ tp match {
+ case ClassInfoType(parents, decls, clazz) =>
+ val parents1 = parents mapConserve uncurry
+ if (parents1 eq parents) tp
+ else ClassInfoType(parents1, decls, clazz) // @MAT normalize in decls??
+ case PolyType(_, _) =>
+ mapOver(tp)
+ case _ =>
+ tp
+ }
+ }
+ }
+
+ /** - return symbol's transformed type,
+ * - if symbol is a def parameter with transformed type T, return () => T
+ *
+ * @MAT: starting with this phase, the info of every symbol will be normalized
+ */
+ def transformInfo(sym: Symbol, tp: Type): Type =
+ if (sym.isType) uncurryType(tp) else uncurry(tp)
+} \ No newline at end of file