@@ -10,7 +10,6 @@ import scala.collection.{ mutable, immutable }
10
10
import PartialFunction ._
11
11
import collection .mutable
12
12
import scala .reflect .api .{ Universe => ApiUniverse }
13
- import functions ._
14
13
15
14
object Definitions {
16
15
@@ -91,7 +90,7 @@ class Definitions {
91
90
}
92
91
93
92
/** The trait FunctionN or ImplicitFunctionN, for some N
94
- * @param function The function name description of the trait to be created
93
+ * @param name The name of the trait to be created
95
94
*
96
95
* FunctionN traits follow this template:
97
96
*
@@ -109,28 +108,32 @@ class Definitions {
109
108
* def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
110
109
* }
111
110
*/
112
- private def newFunctionNTrait (function : ScalaFunction ) = {
111
+ private def newFunctionNTrait (name : TypeName ) = {
113
112
val completer = new LazyType {
114
113
def complete (denot : SymDenotation )(implicit ctx : Context ): Unit = {
115
114
val cls = denot.asClass.classSymbol
116
115
val decls = newScope
117
- val tParamTpes = List .tabulate(function.arity + 1 ) { i =>
118
- val variance = if (i < function.arity) Contravariant else Covariant
119
- val paramName = tpnme.scala_ ++ " $ " ++ function.name ++ " $$ " ++ ( if (i != function.arity) " T " + (i + 1 ) else " R " )
120
- enterTypeParam(cls, paramName, variance , decls).typeRef
121
- }
116
+ val arity = name.functionArity
117
+ val argParams =
118
+ for (i <- List .range( 0 , arity)) yield
119
+ enterTypeParam(cls, name ++ " $T " ++ i.toString, Contravariant , decls)
120
+ val resParam = enterTypeParam(cls, name ++ " $R " , Covariant , decls)
122
121
val (methodType, parentTraits) =
123
- if (function.isImplicit) {
124
- val superTrait = function.withoutImplicit.typeRef.appliedTo(tParamTpes)
122
+ if (name.startsWith(tpnme.ImplicitFunction )) {
123
+ val superTrait =
124
+ FunctionType (arity).appliedTo(argParams.map(_.typeRef) ::: resParam.typeRef :: Nil )
125
125
(ImplicitMethodType , ctx.normalizeToClassRefs(superTrait :: Nil , cls, decls))
126
126
}
127
127
else (MethodType , Nil )
128
-
129
- decls.enter(newMethod(cls, nme.apply, methodType(tParamTpes.init, tParamTpes.last), Deferred ))
130
- denot.info = ClassInfo (ScalaPackageClass .thisType, cls, ObjectType :: parentTraits, decls)
128
+ val applyMeth =
129
+ decls.enter(
130
+ newMethod(cls, nme.apply,
131
+ methodType(argParams.map(_.typeRef), resParam.typeRef), Deferred ))
132
+ denot.info =
133
+ ClassInfo (ScalaPackageClass .thisType, cls, ObjectType :: parentTraits, decls)
131
134
}
132
135
}
133
- newClassSymbol(ScalaPackageClass , function. name, NoInitsTrait , completer)
136
+ newClassSymbol(ScalaPackageClass , name, Trait | NoInits , completer)
134
137
}
135
138
136
139
private def newMethod (cls : ClassSymbol , name : TermName , info : Type , flags : FlagSet = EmptyFlags ): TermSymbol =
@@ -628,18 +631,16 @@ class Definitions {
628
631
sym.owner.linkedClass.typeRef
629
632
630
633
object FunctionOf {
631
- def apply (args : List [Type ], resultType : Type , isImplicit : Boolean = false )(implicit ctx : Context ) = {
632
- ScalaFunction (args, isImplicit).typeRef.appliedTo(args ::: resultType :: Nil )
633
- }
634
+ def apply (args : List [Type ], resultType : Type , isImplicit : Boolean = false )(implicit ctx : Context ) =
635
+ FunctionType (args.length, isImplicit).appliedTo(args ::: resultType :: Nil )
634
636
def unapply (ft : Type )(implicit ctx : Context ) = {
635
637
val tsym = ft.typeSymbol
636
- val function = ScalaFunction (tsym)
637
- if (function.exists ) {
638
+ val isImplicitFun = isImplicitFunctionClass (tsym)
639
+ if (isImplicitFun || isFunctionClass(tsym) ) {
638
640
val targs = ft.dealias.argInfos
639
- Some (targs.init, targs.last, function.isImplicit)
640
- } else {
641
- None
641
+ Some (targs.init, targs.last, isImplicitFun)
642
642
}
643
+ else None
643
644
}
644
645
}
645
646
@@ -684,14 +685,23 @@ class Definitions {
684
685
lazy val AbstractFunctionType = mkArityArray(" scala.runtime.AbstractFunction" , MaxImplementedFunctionArity , 0 )
685
686
val AbstractFunctionClassPerRun = new PerRun [Array [Symbol ]](implicit ctx => AbstractFunctionType .map(_.symbol.asClass))
686
687
def AbstractFunctionClass (n : Int )(implicit ctx : Context ) = AbstractFunctionClassPerRun ()(ctx)(n)
687
- lazy val ImplementedFunctionType = mkArityArray(" scala.Function" , MaxImplementedFunctionArity , 0 )
688
+ private lazy val ImplementedFunctionType = mkArityArray(" scala.Function" , MaxImplementedFunctionArity , 0 )
688
689
def FunctionClassPerRun = new PerRun [Array [Symbol ]](implicit ctx => ImplementedFunctionType .map(_.symbol.asClass))
689
690
690
691
lazy val TupleType = mkArityArray(" scala.Tuple" , MaxTupleArity , 2 )
691
692
lazy val ProductNType = mkArityArray(" scala.Product" , MaxTupleArity , 0 )
692
693
693
- lazy val Function0_applyR = ImplementedFunctionType (0 ).symbol.requiredMethodRef(nme.apply)
694
- def Function0_apply (implicit ctx : Context ) = Function0_applyR .symbol
694
+ def FunctionClass (n : Int , isImplicit : Boolean = false )(implicit ctx : Context ) =
695
+ if (isImplicit) ctx.requiredClass(" scala.ImplicitFunction" + n.toString)
696
+ else if (n < MaxImplementedFunctionArity ) FunctionClassPerRun ()(ctx)(n)
697
+ else ctx.requiredClass(" scala.Function" + n.toString)
698
+
699
+ lazy val Function0_applyR = ImplementedFunctionType (0 ).symbol.requiredMethodRef(nme.apply)
700
+ def Function0_apply (implicit ctx : Context ) = Function0_applyR .symbol
701
+
702
+ def FunctionType (n : Int , isImplicit : Boolean = false )(implicit ctx : Context ): TypeRef =
703
+ if (n < MaxImplementedFunctionArity && (! isImplicit || ctx.erasedTypes)) ImplementedFunctionType (n)
704
+ else FunctionClass (n, isImplicit).typeRef
695
705
696
706
private lazy val TupleTypes : Set [TypeRef ] = TupleType .toSet
697
707
private lazy val ProductTypes : Set [TypeRef ] = ProductNType .toSet
@@ -715,10 +725,65 @@ class Definitions {
715
725
def isBottomType (tp : Type ) =
716
726
tp.derivesFrom(NothingClass ) || tp.derivesFrom(NullClass )
717
727
728
+ /** Is a function class.
729
+ * - FunctionN for N >= 0
730
+ * - ImplicitFunctionN for N >= 0
731
+ */
732
+ def isFunctionClass (cls : Symbol ) =
733
+ scalaClassName(cls).isFunction
734
+
735
+ /** Is an implicit function class.
736
+ * - ImplicitFunctionN for N >= 0
737
+ */
738
+ def isImplicitFunctionClass (cls : Symbol ) =
739
+ scalaClassName(cls).isImplicitFunction
740
+
741
+ /** Is a class that will be erased to FunctionXXL
742
+ * - FunctionN for N >= 22
743
+ * - ImplicitFunctionN for N >= 22
744
+ */
745
+ def isXXLFunctionClass (cls : Symbol ) =
746
+ scalaClassName(cls).functionArity > MaxImplementedFunctionArity
747
+
748
+ /** Is a synthetic function class
749
+ * - FunctionN for N > 22
750
+ * - ImplicitFunctionN for N >= 0
751
+ */
752
+ def isSyntheticFunctionClass (cls : Symbol ) =
753
+ scalaClassName(cls).isSyntheticFunction
754
+
718
755
def isAbstractFunctionClass (cls : Symbol ) = isVarArityClass(cls, tpnme.AbstractFunction )
719
756
def isTupleClass (cls : Symbol ) = isVarArityClass(cls, tpnme.Tuple )
720
757
def isProductClass (cls : Symbol ) = isVarArityClass(cls, tpnme.Product )
721
758
759
+ /** Returns the erased class of the function class `cls`
760
+ * - FunctionN for N > 22 becomes FunctionXXL
761
+ * - FunctionN for 22 > N >= 0 remains as FunctionN
762
+ * - ImplicitFunctionN for N > 22 becomes FunctionXXL
763
+ * - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN
764
+ * - anything else becomes a NoSymbol
765
+ */
766
+ def erasedFunctionClass (cls : Symbol ): Symbol = {
767
+ val arity = scalaClassName(cls).functionArity
768
+ if (arity > 22 ) defn.FunctionXXLClass
769
+ else if (arity >= 0 ) defn.FunctionClass (arity)
770
+ else NoSymbol
771
+ }
772
+
773
+ /** Returns the erased type of the function class `cls`
774
+ * - FunctionN for N > 22 becomes FunctionXXL
775
+ * - FunctionN for 22 > N >= 0 remains as FunctionN
776
+ * - ImplicitFunctionN for N > 22 becomes FunctionXXL
777
+ * - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN
778
+ * - anything else becomes a NoType
779
+ */
780
+ def erasedFunctionType (cls : Symbol ): Type = {
781
+ val arity = scalaClassName(cls).functionArity
782
+ if (arity > 22 ) defn.FunctionXXLType
783
+ else if (arity >= 0 ) defn.FunctionType (arity)
784
+ else NoType
785
+ }
786
+
722
787
val predefClassNames : Set [Name ] =
723
788
Set (" Predef$" , " DeprecatedPredef" , " LowPriorityImplicits" ).map(_.toTypeName)
724
789
@@ -760,8 +825,7 @@ class Definitions {
760
825
* trait gets screwed up. Therefore, it is mandatory that FunctionXXL
761
826
* is treated as a NoInit trait.
762
827
*/
763
- def isNoInitClass (cls : Symbol ) =
764
- cls.is(NoInitsTrait ) || PhantomClasses (cls) || ScalaFunction (cls).exists
828
+ lazy val NoInitClasses = PhantomClasses + FunctionXXLClass
765
829
766
830
def isPolymorphicAfterErasure (sym : Symbol ) =
767
831
(sym eq Any_isInstanceOf ) || (sym eq Any_asInstanceOf )
@@ -788,17 +852,15 @@ class Definitions {
788
852
789
853
/** Is `tp` (an alias) of either a scala.FunctionN or a scala.ImplicitFunctionN ? */
790
854
def isFunctionType (tp : Type )(implicit ctx : Context ) = {
791
- val function = ScalaFunction (tp.dealias.typeSymbol)
792
- function.exists && tp.isRef(function.symbol)
855
+ val arity = functionArity(tp)
856
+ val sym = tp.dealias.typeSymbol
857
+ arity >= 0 && isFunctionClass(sym) && tp.isRef(FunctionType (arity, sym.name.isImplicitFunction).typeSymbol)
793
858
}
794
859
795
- def functionArity (tp : Type )(implicit ctx : Context ) =
796
- ScalaFunction (tp.dealias.typeSymbol).arity
860
+ def functionArity (tp : Type )(implicit ctx : Context ) = tp.dealias.argInfos.length - 1
797
861
798
- def isImplicitFunctionType (tp : Type )(implicit ctx : Context ) = {
799
- val function = ScalaFunction (tp.dealias.typeSymbol)
800
- function.isImplicit && tp.isRef(function.symbol)
801
- }
862
+ def isImplicitFunctionType (tp : Type )(implicit ctx : Context ) =
863
+ isFunctionType(tp) && tp.dealias.typeSymbol.name.isImplicitFunction
802
864
803
865
// ----- primitive value class machinery ------------------------------------------
804
866
@@ -881,9 +943,8 @@ class Definitions {
881
943
val newDecls = new MutableScope (oldDecls) {
882
944
override def lookupEntry (name : Name )(implicit ctx : Context ): ScopeEntry = {
883
945
val res = super .lookupEntry(name)
884
- lazy val function = ScalaFunction (name.asTypeName)
885
- if (res == null && name.isTypeName && function.isSynthetic)
886
- newScopeEntry(newFunctionNTrait(function))
946
+ if (res == null && name.isTypeName && name.isSyntheticFunction)
947
+ newScopeEntry(newFunctionNTrait(name.asTypeName))
887
948
else res
888
949
}
889
950
}
@@ -906,9 +967,6 @@ class Definitions {
906
967
EmptyPackageVal ,
907
968
OpsPackageClass )
908
969
909
- def isSyntheticScalaClass (sym : Symbol ): Boolean =
910
- syntheticScalaClasses.contains(sym) || ScalaFunction (sym).isSynthetic
911
-
912
970
/** Lists core methods that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
913
971
lazy val syntheticCoreMethods = AnyMethods ++ ObjectMethods ++ List (String_+ , throwMethod)
914
972
0 commit comments