aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/core/Definitions.scala
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2017-02-16 10:56:46 +0100
committerGitHub <noreply@github.com>2017-02-16 10:56:46 +0100
commit6df672c7e7be65d7be1cd6524c610aed4f35178c (patch)
treea1b709dc631f0891b6a2c7c628439443c75f14e2 /compiler/src/dotty/tools/dotc/core/Definitions.scala
parent39af2f595979c6bbeb3cfa52d401cf59be68126b (diff)
parent93a2d0653e6b74a0f88825ac8a522da87e474f2a (diff)
downloaddotty-6df672c7e7be65d7be1cd6524c610aed4f35178c.tar.gz
dotty-6df672c7e7be65d7be1cd6524c610aed4f35178c.tar.bz2
dotty-6df672c7e7be65d7be1cd6524c610aed4f35178c.zip
Merge pull request #1962 from dotty-staging/centralize-function-logic
Factor out logic for scala functions.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core/Definitions.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala90
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 01a164a81..9e9e39a84 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -637,13 +637,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
}
@@ -696,20 +692,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
@@ -733,14 +726,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)
@@ -811,16 +851,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 ------------------------------------------
@@ -894,9 +931,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.
*/
@@ -906,7 +940,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
}