diff options
author | Nicolas Stucki <nicolas.stucki@gmail.com> | 2017-02-09 14:45:42 +0100 |
---|---|---|
committer | Nicolas Stucki <nicolas.stucki@gmail.com> | 2017-02-13 18:29:02 +0100 |
commit | 93a2d0653e6b74a0f88825ac8a522da87e474f2a (patch) | |
tree | 7a97d30544f09083ec0561478bf49b78fb44f2ab /compiler/src/dotty/tools/dotc/core/Definitions.scala | |
parent | b29783237c03ade1dd19cc564170c7a87d7b8b84 (diff) | |
download | dotty-93a2d0653e6b74a0f88825ac8a522da87e474f2a.tar.gz dotty-93a2d0653e6b74a0f88825ac8a522da87e474f2a.tar.bz2 dotty-93a2d0653e6b74a0f88825ac8a522da87e474f2a.zip |
Add checks for synthetic functions and erased functions.
* Add `isSyntheticFunction` checks for synthetic functions such as FuntionN
for N > 22 and ImplicitFunctionN for N >= 0.
* Add `erasedFunctionClass` to get the erased verion of synthetic functions.
* Change the semantics of `isFunctionClass` to return true if it is any kind of
FunctionN or ImplicitFunctionN.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core/Definitions.scala')
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/Definitions.scala | 90 |
1 files changed, 62 insertions, 28 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 2797bb8a6..69ab6c21a 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -635,13 +635,9 @@ class Definitions { FunctionType(args.length, isImplicit).appliedTo(args ::: resultType :: Nil) def unapply(ft: Type)(implicit ctx: Context) = { val tsym = ft.typeSymbol - val isImplicitFun = isImplicitFunctionClass(tsym) - if (isImplicitFun || isFunctionClass(tsym)) { - val targs = ft.argInfos - val numArgs = targs.length - 1 - if (numArgs >= 0 && FunctionType(numArgs, isImplicitFun).symbol == tsym) - Some(targs.init, targs.last, isImplicitFun) - else None + if (isFunctionClass(tsym)) { + val targs = ft.dealias.argInfos + Some(targs.init, targs.last, tsym.name.isImplicitFunction) } else None } @@ -694,20 +690,17 @@ class Definitions { lazy val TupleType = mkArityArray("scala.Tuple", MaxTupleArity, 2) lazy val ProductNType = mkArityArray("scala.Product", MaxTupleArity, 0) - def FunctionClass(n: Int)(implicit ctx: Context) = - if (n < MaxImplementedFunctionArity) FunctionClassPerRun()(ctx)(n) + def FunctionClass(n: Int, isImplicit: Boolean = false)(implicit ctx: Context) = + if (isImplicit) ctx.requiredClass("scala.ImplicitFunction" + n.toString) + else if (n <= MaxImplementedFunctionArity) FunctionClassPerRun()(ctx)(n) else ctx.requiredClass("scala.Function" + n.toString) lazy val Function0_applyR = ImplementedFunctionType(0).symbol.requiredMethodRef(nme.apply) def Function0_apply(implicit ctx: Context) = Function0_applyR.symbol - def ImplicitFunctionClass(n: Int)(implicit ctx: Context) = - ctx.requiredClass("scala.ImplicitFunction" + n.toString) - def FunctionType(n: Int, isImplicit: Boolean = false)(implicit ctx: Context): TypeRef = - if (isImplicit && !ctx.erasedTypes) ImplicitFunctionClass(n).typeRef - else if (n < MaxImplementedFunctionArity) ImplementedFunctionType(n) - else FunctionClass(n).typeRef + if (n <= MaxImplementedFunctionArity && (!isImplicit || ctx.erasedTypes)) ImplementedFunctionType(n) + else FunctionClass(n, isImplicit).typeRef private lazy val TupleTypes: Set[TypeRef] = TupleType.toSet private lazy val ProductTypes: Set[TypeRef] = ProductNType.toSet @@ -731,14 +724,61 @@ class Definitions { def isBottomType(tp: Type) = tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass) - def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function) - def isImplicitFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.ImplicitFunction) - /** Is a class that will be erased to FunctionXXL */ - def isXXLFunctionClass(cls: Symbol) = cls.name.functionArity > MaxImplementedFunctionArity + /** Is a function class. + * - FunctionN for N >= 0 + * - ImplicitFunctionN for N >= 0 + */ + def isFunctionClass(cls: Symbol) = scalaClassName(cls).isFunction + + /** Is an implicit function class. + * - ImplicitFunctionN for N >= 0 + */ + def isImplicitFunctionClass(cls: Symbol) = scalaClassName(cls).isImplicitFunction + + /** Is a class that will be erased to FunctionXXL + * - FunctionN for N >= 22 + * - ImplicitFunctionN for N >= 22 + */ + def isXXLFunctionClass(cls: Symbol) = scalaClassName(cls).functionArity > MaxImplementedFunctionArity + + /** Is a synthetic function class + * - FunctionN for N > 22 + * - ImplicitFunctionN for N >= 0 + */ + def isSyntheticFunctionClass(cls: Symbol) = scalaClassName(cls).isSyntheticFunction + def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction) def isTupleClass(cls: Symbol) = isVarArityClass(cls, tpnme.Tuple) def isProductClass(cls: Symbol) = isVarArityClass(cls, tpnme.Product) + /** Returns the erased class of the function class `cls` + * - FunctionN for N > 22 becomes FunctionXXL + * - FunctionN for 22 > N >= 0 remains as FunctionN + * - ImplicitFunctionN for N > 22 becomes FunctionXXL + * - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN + * - anything else becomes a NoSymbol + */ + def erasedFunctionClass(cls: Symbol): Symbol = { + val arity = scalaClassName(cls).functionArity + if (arity > 22) defn.FunctionXXLClass + else if (arity >= 0) defn.FunctionClass(arity) + else NoSymbol + } + + /** Returns the erased type of the function class `cls` + * - FunctionN for N > 22 becomes FunctionXXL + * - FunctionN for 22 > N >= 0 remains as FunctionN + * - ImplicitFunctionN for N > 22 becomes FunctionXXL + * - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN + * - anything else becomes a NoType + */ + def erasedFunctionType(cls: Symbol): Type = { + val arity = scalaClassName(cls).functionArity + if (arity > 22) defn.FunctionXXLType + else if (arity >= 0) defn.FunctionType(arity) + else NoType + } + val predefClassNames: Set[Name] = Set("Predef$", "DeprecatedPredef", "LowPriorityImplicits").map(_.toTypeName) @@ -809,16 +849,13 @@ class Definitions { def isFunctionType(tp: Type)(implicit ctx: Context) = { val arity = functionArity(tp) val sym = tp.dealias.typeSymbol - arity >= 0 && ( - isFunctionClass(sym) && tp.isRef(FunctionType(arity, isImplicit = false).typeSymbol) || - isImplicitFunctionClass(sym) && tp.isRef(FunctionType(arity, isImplicit = true).typeSymbol) - ) + arity >= 0 && isFunctionClass(sym) && tp.isRef(FunctionType(arity, sym.name.isImplicitFunction).typeSymbol) } def functionArity(tp: Type)(implicit ctx: Context) = tp.dealias.argInfos.length - 1 def isImplicitFunctionType(tp: Type)(implicit ctx: Context) = - isFunctionType(tp) && tp.dealias.typeSymbol.name.startsWith(tpnme.ImplicitFunction) + isFunctionType(tp) && tp.dealias.typeSymbol.name.isImplicitFunction // ----- primitive value class machinery ------------------------------------------ @@ -892,9 +929,6 @@ class Definitions { // ----- Initialization --------------------------------------------------- - private def maxImplemented(name: Name) = - if (name `startsWith` tpnme.Function) MaxImplementedFunctionArity else 0 - /** Give the scala package a scope where a FunctionN trait is automatically * added when someone looks for it. */ @@ -904,7 +938,7 @@ class Definitions { val newDecls = new MutableScope(oldDecls) { override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = { val res = super.lookupEntry(name) - if (res == null && name.isTypeName && name.functionArity > maxImplemented(name)) + if (res == null && name.isTypeName && name.isSyntheticFunction) newScopeEntry(newFunctionNTrait(name.asTypeName)) else res } |