diff options
author | Martin Odersky <odersky@gmail.com> | 2017-03-18 11:26:59 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2017-04-06 13:15:28 +0200 |
commit | db4f7a19c9329d59da09a4de6b8476b4b6988cdf (patch) | |
tree | e70a1cf2d4af3a9e3e4b3999d5000b4466627143 /compiler/src/dotty/tools/dotc/core/Types.scala | |
parent | 26497bb3c654e294a48db2098978bc77b11f2889 (diff) | |
download | dotty-db4f7a19c9329d59da09a4de6b8476b4b6988cdf.tar.gz dotty-db4f7a19c9329d59da09a4de6b8476b4b6988cdf.tar.bz2 dotty-db4f7a19c9329d59da09a4de6b8476b4b6988cdf.zip |
Further refactorings
- Use TypeLambda instead of PolyType.
- Further harmonize factory operations
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core/Types.scala')
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/Types.scala | 108 |
1 files changed, 58 insertions, 50 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 6c9046c20..a7401f6f9 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -65,12 +65,12 @@ object Types { * | +- ExprType * | +- AnnotatedType * | +- TypeVar - * | +- PolyType + * | +- HKLambda --------- PolyType * | * +- GroundType -+- AndType * +- OrType - * +- MethodType -----+- ImplicitMethodType - * | +- JavaMethodType + * +- MethodOrPoly ----- MethodType ---+- ImplicitMethodType + * | +- JavaMethodType * +- ClassInfo * | * +- NoType @@ -814,6 +814,12 @@ object Types { */ def stripAnnots(implicit ctx: Context): Type = this + /** Strip PolyType prefix */ + def stripPoly(implicit ctx: Context): Type = this match { + case tp: PolyType => tp.resType.stripPoly + case _ => this + } + /** Widen from singleton type to its underlying non-singleton * base type by applying one or more `underlying` dereferences, * Also go from => T to T. @@ -1088,31 +1094,27 @@ object Types { } /** The parameter types of a PolyType or MethodType, Empty list for others */ - final def paramInfoss(implicit ctx: Context): List[List[Type]] = this match { + final def paramInfoss(implicit ctx: Context): List[List[Type]] = stripPoly match { case mt: MethodType => mt.paramInfos :: mt.resultType.paramInfoss - case pt: TypeLambda => pt.resultType.paramInfoss case _ => Nil } /** The parameter names of a PolyType or MethodType, Empty list for others */ - final def paramNamess(implicit ctx: Context): List[List[TermName]] = this match { + final def paramNamess(implicit ctx: Context): List[List[TermName]] = stripPoly match { case mt: MethodType => mt.paramNames :: mt.resultType.paramNamess - case pt: TypeLambda => pt.resultType.paramNamess case _ => Nil } /** The parameter types in the first parameter section of a generic type or MethodType, Empty list for others */ - final def firstParamTypes(implicit ctx: Context): List[Type] = this match { + final def firstParamTypes(implicit ctx: Context): List[Type] = stripPoly match { case mt: MethodType => mt.paramInfos - case pt: TypeLambda => pt.resultType.firstParamTypes case _ => Nil } /** Is this either not a method at all, or a parameterless method? */ - final def isParameterless(implicit ctx: Context): Boolean = this match { + final def isParameterless(implicit ctx: Context): Boolean = stripPoly match { case mt: MethodType => false - case pt: TypeLambda => pt.resultType.isParameterless case _ => true } @@ -1122,9 +1124,8 @@ object Types { /** The final result type of a PolyType, MethodType, or ExprType, after skipping * all parameter sections, the type itself for all others. */ - def finalResultType(implicit ctx: Context): Type = resultType match { + def finalResultType(implicit ctx: Context): Type = resultType.stripPoly match { case mt: MethodType => mt.resultType.finalResultType - case pt: PolyType => pt.resultType.finalResultType case _ => resultType } @@ -2337,10 +2338,10 @@ object Types { /** The lambda type square: * - * LambdaType | TermLambda | TypeLambda - * ------------+-------------------+------------------ - * HKLambda | HKTermLambda | HKTypeLambda - * StarLambda | MethodType | PolyType + * LambdaType | TermLambda | TypeLambda + * -------------+-------------------+------------------ + * HKLambda | HKTermLambda | HKTypeLambda + * MethodOrPoly | MethodType | PolyType */ trait LambdaType extends BindingType with MethodicType { self => type ThisName <: Name @@ -2370,6 +2371,15 @@ object Types { protected def companion: LambdaTypeCompanion[ThisName, PInfo, This] + /** The type `[tparams := paramRefs] tp`, where `tparams` can be + * either a list of type parameter symbols or a list of lambda parameters + */ + def integrate(tparams: List[ParamInfo], tp: Type)(implicit ctx: Context): Type = + tparams match { + case LambdaParam(lam, _) :: _ => tp.subst(lam, this) + case tparams: List[Symbol @unchecked] => tp.subst(tparams, paramRefs) + } + final def derivedLambdaType(paramNames: List[ThisName] = this.paramNames, paramInfos: List[PInfo] = this.paramInfos, resType: Type = this.resType)(implicit ctx: Context) = @@ -2400,7 +2410,7 @@ object Types { final override def underlying(implicit ctx: Context) = resType } - abstract class StarLambda extends CachedGroundType with LambdaType with TermType { + abstract class MethodOrPoly extends CachedGroundType with LambdaType with TermType { final override def computeHash = doHash(paramNames, resType, paramInfos) } @@ -2504,7 +2514,7 @@ object Types { abstract case class MethodType(paramNames: List[TermName])( paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type) - extends StarLambda with TermLambda with NarrowCached { thisMethodType => + extends MethodOrPoly with TermLambda with NarrowCached { thisMethodType => import MethodType._ type This = MethodType @@ -2544,14 +2554,25 @@ object Types { } abstract class LambdaTypeCompanion[N <: Name, PInfo <: Type, LT <: LambdaType] { - def apply(paramNames: List[N])(paramInfosExp: LT => List[PInfo], resultTypeExp: LT => Type)(implicit ctx: Context): LT def syntheticParamNames(n: Int): List[N] + + def apply(paramNames: List[N])(paramInfosExp: LT => List[PInfo], resultTypeExp: LT => Type)(implicit ctx: Context): LT def apply(paramNames: List[N], paramInfos: List[PInfo], resultType: Type)(implicit ctx: Context): LT = apply(paramNames)(_ => paramInfos, _ => resultType) def apply(paramInfos: List[PInfo])(resultTypeExp: LT => Type)(implicit ctx: Context): LT = apply(syntheticParamNames(paramInfos.length))(_ => paramInfos, resultTypeExp) def apply(paramInfos: List[PInfo], resultType: Type)(implicit ctx: Context): LT = apply(syntheticParamNames(paramInfos.length), paramInfos, resultType) + + protected def paramName(param: ParamInfo.Of[N])(implicit ctx: Context): N = + param.paramName + protected def paramInfo(param: ParamInfo.Of[N])(implicit ctx: Context): Type = + param.paramInfo + + def fromParams[PI <: ParamInfo.Of[N]](params: List[PI], resultType: Type)(implicit ctx: Context): LT = + apply(params.map(paramName))( + tl => params.map(param => tl.integrate(params, paramInfo(param)).asInstanceOf[PInfo]), + tl => tl.integrate(params, resultType)) } abstract class TermLambdaCompanion[LT <: TermLambda] @@ -2567,10 +2588,11 @@ object Types { abstract class MethodTypeCompanion extends TermLambdaCompanion[MethodType] { /** Produce method type from parameter symbols, with special mappings for repeated - * and inline parameters. + * and inline parameters: + * - replace @repeated annotations on Seq or Array types by <repeated> types + * - add @inlineParam to inline call-by-value parameters */ def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = { - /** Replace @repeated annotations on Seq or Array types by <repeated> types */ def translateRepeated(tp: Type): Type = tp match { case tp @ ExprType(tp1) => tp.derivedExprType(translateRepeated(tp1)) case AnnotatedType(tp, annot) if annot matches defn.RepeatedAnnot => @@ -2580,21 +2602,18 @@ object Types { case tp => tp } - /** Add @inlineParam to inline call-by-value parameters */ def translateInline(tp: Type): Type = tp match { case _: ExprType => tp case _ => AnnotatedType(tp, Annotation(defn.InlineParamAnnot)) } - def integrate(tp: Type, mt: MethodType): Type = - tp.subst(params, params.indices.toList.map(mt.newParamRef)) - - def paramInfo(param: Symbol): Type = { + def paramInfo(param: Symbol) = { val paramType = translateRepeated(param.info) if (param.is(Inline)) translateInline(paramType) else paramType } + apply(params.map(_.name.asTermName))( - mt => params.map(param => integrate(paramInfo(param), mt)), - mt => integrate(resultType, mt)) + tl => params.map(p => tl.integrate(params, paramInfo(p))), + tl => tl.integrate(params, resultType)) } def checkValid(mt: MethodType)(implicit ctx: Context): mt.type = { @@ -2670,15 +2689,6 @@ object Types { assert(resType.isInstanceOf[TermType], this) assert(paramNames.nonEmpty) - /** The type `[tparams := paramRefs] tp`, where `tparams` can be - * either a list of type parameter symbols or a list of lambda parameters - */ - def lifted(tparams: List[ParamInfo], tp: Type)(implicit ctx: Context): Type = - tparams match { - case LambdaParam(poly, _) :: _ => tp.subst(poly, this) - case tparams: List[Symbol @unchecked] => tp.subst(tparams, paramRefs) - } - protected def prefixString = "HKTypeLambda" } @@ -2726,15 +2736,6 @@ object Types { case _ => this } - /** The type `[tparams := paramRefs] tp`, where `tparams` can be - * either a list of type parameter symbols or a list of lambda parameters - */ - def lifted(tparams: List[ParamInfo], tp: Type)(implicit ctx: Context): Type = - tparams match { - case LambdaParam(poly, _) :: _ => tp.subst(poly, this) - case tparams: List[Symbol @unchecked] => tp.subst(tparams, paramRefs) - } - protected def prefixString = "PolyType" } @@ -2751,6 +2752,9 @@ object Types { def any(n: Int)(implicit ctx: Context) = apply(syntheticParamNames(n))( pt => List.fill(n)(TypeBounds.empty), pt => defn.AnyType) + + override def paramName(param: ParamInfo.Of[TypeName])(implicit ctx: Context): TypeName = + param.paramName.withVariance(param.paramVariance) } object PolyType extends TypeLambdaCompanion[PolyType] { @@ -2766,6 +2770,9 @@ object Types { def any(n: Int)(implicit ctx: Context) = apply(syntheticParamNames(n))( pt => List.fill(n)(TypeBounds.empty), pt => defn.AnyType) + + override def paramName(param: ParamInfo.Of[TypeName])(implicit ctx: Context): TypeName = + param.paramName.withVariance(param.paramVariance) //### } private object DepStatus { @@ -2782,10 +2789,11 @@ object Types { /** The parameter of a type lambda */ case class LambdaParam(tl: TypeLambda, n: Int) extends ParamInfo { + type ThisName = TypeName def isTypeParam(implicit ctx: Context) = tl.paramNames.head.isTypeName - def paramName(implicit ctx: Context): TypeName = tl.paramNames(n) - def paramInfo(implicit ctx: Context): Type = tl.paramInfos(n) - def paramInfoAsSeenFrom(pre: Type)(implicit ctx: Context): Type = paramInfo + def paramName(implicit ctx: Context) = tl.paramNames(n) + def paramInfo(implicit ctx: Context) = tl.paramInfos(n) + def paramInfoAsSeenFrom(pre: Type)(implicit ctx: Context) = paramInfo def paramInfoOrCompleter(implicit ctx: Context): Type = paramInfo def paramVariance(implicit ctx: Context): Int = tl.paramNames(n).variance def toArg: Type = TypeParamRef(tl, n) |