@@ -10,6 +10,7 @@ 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 ._
13
14
14
15
object Definitions {
15
16
@@ -90,7 +91,7 @@ class Definitions {
90
91
}
91
92
92
93
/** The trait FunctionN or ImplicitFunctionN, for some N
93
- * @param name The name of the trait to be created
94
+ * @param function The function name description of the trait to be created
94
95
*
95
96
* FunctionN traits follow this template:
96
97
*
@@ -108,32 +109,28 @@ class Definitions {
108
109
* def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
109
110
* }
110
111
*/
111
- private def newFunctionNTrait (name : TypeName ) = {
112
+ private def newFunctionNTrait (function : ScalaFunction ) = {
112
113
val completer = new LazyType {
113
114
def complete (denot : SymDenotation )(implicit ctx : Context ): Unit = {
114
115
val cls = denot.asClass.classSymbol
115
116
val decls = newScope
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)
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
+ }
121
122
val (methodType, parentTraits) =
122
- if (name.startsWith(tpnme.ImplicitFunction )) {
123
- val superTrait =
124
- FunctionType (arity).appliedTo(argParams.map(_.typeRef) ::: resParam.typeRef :: Nil )
123
+ if (function.isImplicit) {
124
+ val superTrait = function.withoutImplicit.typeRef.appliedTo(tParamTpes)
125
125
(ImplicitMethodType , ctx.normalizeToClassRefs(superTrait :: Nil , cls, decls))
126
126
}
127
127
else (MethodType , Nil )
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)
128
+
129
+ decls.enter(newMethod(cls, nme.apply, methodType(tParamTpes.init, tParamTpes.last), Deferred ))
130
+ denot.info = ClassInfo (ScalaPackageClass .thisType, cls, ObjectType :: parentTraits, decls)
134
131
}
135
132
}
136
- newClassSymbol(ScalaPackageClass , name, Trait | NoInits , completer)
133
+ newClassSymbol(ScalaPackageClass , function. name, NoInitsTrait , completer)
137
134
}
138
135
139
136
private def newMethod (cls : ClassSymbol , name : TermName , info : Type , flags : FlagSet = EmptyFlags ): TermSymbol =
@@ -631,19 +628,18 @@ class Definitions {
631
628
sym.owner.linkedClass.typeRef
632
629
633
630
object FunctionOf {
634
- def apply (args : List [Type ], resultType : Type , isImplicit : Boolean = false )(implicit ctx : Context ) =
635
- FunctionType (args.length, isImplicit).appliedTo(args ::: resultType :: Nil )
631
+ def apply (args : List [Type ], resultType : Type , isImplicit : Boolean = false )(implicit ctx : Context ) = {
632
+ ScalaFunction (args, isImplicit).typeRef.appliedTo(args ::: resultType :: Nil )
633
+ }
636
634
def unapply (ft : Type )(implicit ctx : Context ) = {
637
635
val tsym = ft.typeSymbol
638
- val isImplicitFun = isImplicitFunctionClass(tsym)
639
- if (isImplicitFun || isFunctionClass(tsym)) {
640
- val targs = ft.argInfos
641
- val numArgs = targs.length - 1
642
- if (numArgs >= 0 && FunctionType (numArgs, isImplicitFun).symbol == tsym)
643
- Some (targs.init, targs.last, isImplicitFun)
644
- else None
636
+ val function = ScalaFunction (tsym)
637
+ if (function.exists) {
638
+ val targs = ft.dealias.argInfos
639
+ Some (targs.init, targs.last, function.isImplicit)
640
+ } else {
641
+ None
645
642
}
646
- else None
647
643
}
648
644
}
649
645
@@ -688,26 +684,14 @@ class Definitions {
688
684
lazy val AbstractFunctionType = mkArityArray(" scala.runtime.AbstractFunction" , MaxImplementedFunctionArity , 0 )
689
685
val AbstractFunctionClassPerRun = new PerRun [Array [Symbol ]](implicit ctx => AbstractFunctionType .map(_.symbol.asClass))
690
686
def AbstractFunctionClass (n : Int )(implicit ctx : Context ) = AbstractFunctionClassPerRun ()(ctx)(n)
691
- private lazy val ImplementedFunctionType = mkArityArray(" scala.Function" , MaxImplementedFunctionArity , 0 )
687
+ lazy val ImplementedFunctionType = mkArityArray(" scala.Function" , MaxImplementedFunctionArity , 0 )
692
688
def FunctionClassPerRun = new PerRun [Array [Symbol ]](implicit ctx => ImplementedFunctionType .map(_.symbol.asClass))
693
689
694
690
lazy val TupleType = mkArityArray(" scala.Tuple" , MaxTupleArity , 2 )
695
691
lazy val ProductNType = mkArityArray(" scala.Product" , MaxTupleArity , 0 )
696
692
697
- def FunctionClass (n : Int )(implicit ctx : Context ) =
698
- if (n < MaxImplementedFunctionArity ) FunctionClassPerRun ()(ctx)(n)
699
- else ctx.requiredClass(" scala.Function" + n.toString)
700
-
701
- lazy val Function0_applyR = ImplementedFunctionType (0 ).symbol.requiredMethodRef(nme.apply)
702
- def Function0_apply (implicit ctx : Context ) = Function0_applyR .symbol
703
-
704
- def ImplicitFunctionClass (n : Int )(implicit ctx : Context ) =
705
- ctx.requiredClass(" scala.ImplicitFunction" + n.toString)
706
-
707
- def FunctionType (n : Int , isImplicit : Boolean = false )(implicit ctx : Context ): TypeRef =
708
- if (isImplicit && ! ctx.erasedTypes) ImplicitFunctionClass (n).typeRef
709
- else if (n < MaxImplementedFunctionArity ) ImplementedFunctionType (n)
710
- else FunctionClass (n).typeRef
693
+ lazy val Function0_applyR = ImplementedFunctionType (0 ).symbol.requiredMethodRef(nme.apply)
694
+ def Function0_apply (implicit ctx : Context ) = Function0_applyR .symbol
711
695
712
696
private lazy val TupleTypes : Set [TypeRef ] = TupleType .toSet
713
697
private lazy val ProductTypes : Set [TypeRef ] = ProductNType .toSet
@@ -731,10 +715,6 @@ class Definitions {
731
715
def isBottomType (tp : Type ) =
732
716
tp.derivesFrom(NothingClass ) || tp.derivesFrom(NullClass )
733
717
734
- def isFunctionClass (cls : Symbol ) = isVarArityClass(cls, tpnme.Function )
735
- def isImplicitFunctionClass (cls : Symbol ) = isVarArityClass(cls, tpnme.ImplicitFunction )
736
- /** Is a class that will be erased to FunctionXXL */
737
- def isXXLFunctionClass (cls : Symbol ) = cls.name.functionArity > MaxImplementedFunctionArity
738
718
def isAbstractFunctionClass (cls : Symbol ) = isVarArityClass(cls, tpnme.AbstractFunction )
739
719
def isTupleClass (cls : Symbol ) = isVarArityClass(cls, tpnme.Tuple )
740
720
def isProductClass (cls : Symbol ) = isVarArityClass(cls, tpnme.Product )
@@ -780,7 +760,8 @@ class Definitions {
780
760
* trait gets screwed up. Therefore, it is mandatory that FunctionXXL
781
761
* is treated as a NoInit trait.
782
762
*/
783
- lazy val NoInitClasses = PhantomClasses + FunctionXXLClass
763
+ def isNoInitClass (cls : Symbol ) =
764
+ cls.is(NoInitsTrait ) || PhantomClasses (cls) || ScalaFunction (cls).exists
784
765
785
766
def isPolymorphicAfterErasure (sym : Symbol ) =
786
767
(sym eq Any_isInstanceOf ) || (sym eq Any_asInstanceOf )
@@ -807,18 +788,17 @@ class Definitions {
807
788
808
789
/** Is `tp` (an alias) of either a scala.FunctionN or a scala.ImplicitFunctionN ? */
809
790
def isFunctionType (tp : Type )(implicit ctx : Context ) = {
810
- val arity = functionArity(tp)
811
- val sym = tp.dealias.typeSymbol
812
- arity >= 0 && (
813
- isFunctionClass(sym) && tp.isRef(FunctionType (arity, isImplicit = false ).typeSymbol) ||
814
- isImplicitFunctionClass(sym) && tp.isRef(FunctionType (arity, isImplicit = true ).typeSymbol)
815
- )
791
+ val function = ScalaFunction (tp.dealias.typeSymbol)
792
+ function.exists && tp.isRef(function.symbol)
816
793
}
817
794
818
- def functionArity (tp : Type )(implicit ctx : Context ) = tp.dealias.argInfos.length - 1
795
+ def functionArity (tp : Type )(implicit ctx : Context ) =
796
+ ScalaFunction (tp.dealias.typeSymbol).arity
819
797
820
- def isImplicitFunctionType (tp : Type )(implicit ctx : Context ) =
821
- isFunctionType(tp) && tp.dealias.typeSymbol.name.startsWith(tpnme.ImplicitFunction )
798
+ def isImplicitFunctionType (tp : Type )(implicit ctx : Context ) = {
799
+ val function = ScalaFunction (tp.dealias.typeSymbol)
800
+ function.isImplicit && tp.isRef(function.symbol)
801
+ }
822
802
823
803
// ----- primitive value class machinery ------------------------------------------
824
804
@@ -892,9 +872,6 @@ class Definitions {
892
872
893
873
// ----- Initialization ---------------------------------------------------
894
874
895
- private def maxImplemented (name : Name ) =
896
- if (name `startsWith` tpnme.Function ) MaxImplementedFunctionArity else 0
897
-
898
875
/** Give the scala package a scope where a FunctionN trait is automatically
899
876
* added when someone looks for it.
900
877
*/
@@ -904,8 +881,9 @@ class Definitions {
904
881
val newDecls = new MutableScope (oldDecls) {
905
882
override def lookupEntry (name : Name )(implicit ctx : Context ): ScopeEntry = {
906
883
val res = super .lookupEntry(name)
907
- if (res == null && name.isTypeName && name.functionArity > maxImplemented(name))
908
- newScopeEntry(newFunctionNTrait(name.asTypeName))
884
+ lazy val function = ScalaFunction (name.asTypeName)
885
+ if (res == null && name.isTypeName && function.isSynthetic)
886
+ newScopeEntry(newFunctionNTrait(function))
909
887
else res
910
888
}
911
889
}
@@ -928,6 +906,9 @@ class Definitions {
928
906
EmptyPackageVal ,
929
907
OpsPackageClass )
930
908
909
+ def isSyntheticScalaClass (sym : Symbol ): Boolean =
910
+ syntheticScalaClasses.contains(sym) || ScalaFunction (sym).isSynthetic
911
+
931
912
/** Lists core methods that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
932
913
lazy val syntheticCoreMethods = AnyMethods ++ ObjectMethods ++ List (String_+ , throwMethod)
933
914
0 commit comments