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 val uncurry: TypeMap = new TypeMap { def apply(tp0: Type): Type = { 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, arg :: Nil) => apply(functionType(List(), arg)) case TypeRef(pre, RepeatedParamClass, arg :: Nil) => apply(seqType(arg)) case TypeRef(pre, JavaRepeatedParamClass, arg :: Nil) => apply(arrayType( if (isUnboundedGeneric(arg)) ObjectClass.tpe else arg)) 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) }