summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDen Shabalin <den.shabalin@gmail.com>2013-09-10 15:32:07 +0200
committerDen Shabalin <den.shabalin@gmail.com>2013-09-12 12:43:28 +0200
commit8a7b5666b6f10728f7c3ae9ca1bc2a8b82f6b965 (patch)
tree3e6ad67c8cba6e23047f991e71f1256e652d25bb
parent95fe19545d60ae9aa79d2c8d5665c7f3b0cbdb1a (diff)
downloadscala-8a7b5666b6f10728f7c3ae9ca1bc2a8b82f6b965.tar.gz
scala-8a7b5666b6f10728f7c3ae9ca1bc2a8b82f6b965.tar.bz2
scala-8a7b5666b6f10728f7c3ae9ca1bc2a8b82f6b965.zip
refactor variable arity definitions
Transform current arrays of symbols into function-like objects that return NoSymbol at all places where corresponding arity isn't available.
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala2
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala3
-rw-r--r--src/reflect/scala/reflect/api/StandardDefinitions.scala18
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala24
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala46
5 files changed, 47 insertions, 46 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index edb1c55224..8d025b5451 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -1479,7 +1479,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
sym.owner.isSynthetic &&
sym.owner.tpe.parents.exists { t =>
val TypeRef(_, sym, _) = t
- FunctionClass contains sym
+ FunctionClass.seq contains sym
}
}
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index ffbca7014a..b77a536caf 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -349,7 +349,8 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
}
def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree = {
- val viewTpe = u.appliedType(u.definitions.FunctionClass(1).toTypeConstructor, List(from, to))
+ val functionTypeCtor = u.definitions.FunctionClass(1).asClass.toTypeConstructor
+ val viewTpe = u.appliedType(functionTypeCtor, List(from, to))
inferImplicit(tree, viewTpe, isView = true, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos)
}
diff --git a/src/reflect/scala/reflect/api/StandardDefinitions.scala b/src/reflect/scala/reflect/api/StandardDefinitions.scala
index bbfebcb434..e255d305f7 100644
--- a/src/reflect/scala/reflect/api/StandardDefinitions.scala
+++ b/src/reflect/scala/reflect/api/StandardDefinitions.scala
@@ -214,29 +214,35 @@ trait StandardDefinitions {
/** The module symbol of module `scala.Some`. */
def SomeModule: ModuleSymbol
- /** The array of class symbols for classes `scala.ProductX`.
+ /** Function-like object that maps arity to symbols for classes `scala.ProductX`.
* - 0th element is `Unit`
* - 1st element is `Product1`
* - ...
* - 22nd element is `Product22`
+ * - 23nd element is `NoSymbol`
+ * - ...
*/
- def ProductClass : Array[ClassSymbol]
+ def ProductClass: Int => Symbol
- /** The array of class symbols for classes `scala.FunctionX`.
+ /** Function-like object that maps arity to symbols for classes `scala.FunctionX`.
* - 0th element is `Function0`
* - 1st element is `Function1`
* - ...
* - 22nd element is `Function22`
+ * - 23nd element is `NoSymbol`
+ * - ...
*/
- def FunctionClass : Array[ClassSymbol]
+ def FunctionClass: Int => Symbol
- /** The array of class symbols for classes `scala.TupleX`.
+ /** Function-like object that maps arity to symbols for classes `scala.TupleX`.
* - 0th element is `NoSymbol`
* - 1st element is `Product1`
* - ...
* - 22nd element is `Product22`
+ * - 23nd element is `NoSymbol`
+ * - ...
*/
- def TupleClass: Array[Symbol] // cannot make it Array[ClassSymbol], because TupleClass(0) is supposed to be NoSymbol. weird
+ def TupleClass: Int => Symbol
/** Contains Scala primitive value classes:
* - Byte
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index 06a6e10c30..2584dcb117 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -5,7 +5,7 @@ package internal
import Flags._
trait BuildUtils { self: SymbolTable =>
- import definitions.{TupleClass, FunctionClass, MaxTupleArity, MaxFunctionArity, ScalaPackage, UnitClass}
+ import definitions.{TupleClass, FunctionClass, ScalaPackage, UnitClass}
class BuildImpl extends BuildApi {
@@ -271,32 +271,30 @@ trait BuildUtils { self: SymbolTable =>
}
}
private object TupleClassRef extends ScalaMemberRef {
- val symbols = TupleClass.filter { _ != null }.toSeq
+ val symbols = TupleClass.seq
}
private object TupleCompanionRef extends ScalaMemberRef {
- val symbols = TupleClassRef.symbols.map { _.companionModule }
+ val symbols = TupleClass.seq.map { _.companionModule }
}
private object UnitClassRef extends ScalaMemberRef {
val symbols = Seq(UnitClass)
}
private object FunctionClassRef extends ScalaMemberRef {
- val symbols = FunctionClass.toSeq
+ val symbols = FunctionClass.seq
}
object SyntacticTuple extends SyntacticTupleExtractor {
def apply(args: List[Tree]): Tree = args match {
case Nil => Literal(Constant(()))
case _ =>
- require(args.length <= MaxTupleArity, s"Tuples with arity bigger than $MaxTupleArity aren't supported")
+ require(TupleClass(args.length).exists, s"Tuples with ${args.length} arity aren't supported")
self.Apply(TupleClass(args.length).companionModule, args: _*)
}
def unapply(tree: Tree): Option[List[Tree]] = tree match {
case Literal(Constant(())) =>
Some(Nil)
- case Apply(TupleCompanionRef(sym), args)
- if args.length <= MaxTupleArity
- && sym == TupleClass(args.length).companionModule =>
+ case Apply(TupleCompanionRef(sym), args) if sym == TupleClass(args.length).companionModule =>
Some(args)
case _ =>
None
@@ -307,15 +305,14 @@ trait BuildUtils { self: SymbolTable =>
def apply(args: List[Tree]): Tree = args match {
case Nil => self.Select(self.Ident(nme.scala_), tpnme.Unit)
case _ =>
- require(args.length <= MaxTupleArity, s"Tuples with arity bigger than $MaxTupleArity aren't supported")
+ require(TupleClass(args.length).exists, s"Tuples with ${args.length} arity aren't supported")
AppliedTypeTree(Ident(TupleClass(args.length)), args)
}
def unapply(tree: Tree): Option[List[Tree]] = tree match {
case UnitClassRef(_) =>
Some(Nil)
- case AppliedTypeTree(TupleClassRef(sym), args)
- if args.length <= MaxTupleArity && sym == TupleClass(args.length) =>
+ case AppliedTypeTree(TupleClassRef(sym), args) if sym == TupleClass(args.length) =>
Some(args)
case _ =>
None
@@ -324,13 +321,12 @@ trait BuildUtils { self: SymbolTable =>
object SyntacticFunctionType extends SyntacticFunctionTypeExtractor {
def apply(argtpes: List[Tree], restpe: Tree): Tree = {
- require(argtpes.length <= MaxFunctionArity + 1, s"Function types with arity bigger than $MaxFunctionArity aren't supported")
+ require(FunctionClass(argtpes.length).exists, s"Function types with ${argtpes.length} arity aren't supported")
gen.mkFunctionTypeTree(argtpes, restpe)
}
def unapply(tree: Tree): Option[(List[Tree], Tree)] = tree match {
- case AppliedTypeTree(FunctionClassRef(sym), args @ (argtpes :+ restpe))
- if args.length - 1 <= MaxFunctionArity && sym == FunctionClass(args.length - 1) =>
+ case AppliedTypeTree(FunctionClassRef(sym), args @ (argtpes :+ restpe)) if sym == FunctionClass(args.length - 1) =>
Some((argtpes, restpe))
case _ => None
}
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 90a1ab39d5..bc4b8433f5 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -585,30 +585,29 @@ trait Definitions extends api.StandardDefinitions {
def hasJavaMainMethod(sym: Symbol): Boolean =
(sym.tpe member nme.main).alternatives exists isJavaMainMethod
- // Product, Tuple, Function, AbstractFunction
- private def mkArityArray(name: String, arity: Int, countFrom: Int): Array[ClassSymbol] = {
- val list = countFrom to arity map (i => getRequiredClass("scala." + name + i))
- list.toArray
- }
- def prepend[S >: ClassSymbol : ClassTag](elem0: S, elems: Array[ClassSymbol]): Array[S] = elem0 +: elems
-
- private def aritySpecificType[S <: Symbol](symbolArray: Array[S], args: List[Type], others: Type*): Type = {
- val arity = args.length
- if (arity >= symbolArray.length) NoType
- else appliedType(symbolArray(arity), args ++ others: _*)
+ class VarArityClass(name: String, maxArity: Int, countFrom: Int = 0, init: Option[ClassSymbol] = None) extends (Int => Symbol) {
+ private val offset = countFrom - init.size
+ private def isDefinedAt(i: Int) = i < seq.length + offset && i >= offset
+ val seq: IndexedSeq[ClassSymbol] = (init ++: countFrom.to(maxArity).map { i => getRequiredClass("scala." + name + i) }).toVector
+ def apply(i: Int) = if (isDefinedAt(i)) seq(i - offset) else NoSymbol
+ def specificType(args: List[Type], others: Type*): Type = {
+ val arity = args.length
+ if (!isDefinedAt(arity)) NoType
+ else appliedType(apply(arity), args ++ others: _*)
+ }
}
val MaxTupleArity, MaxProductArity, MaxFunctionArity = 22
- lazy val ProductClass: Array[ClassSymbol] = prepend(UnitClass, mkArityArray("Product", MaxProductArity, 1))
- lazy val TupleClass: Array[Symbol] = prepend(null, mkArityArray("Tuple", MaxTupleArity, 1))
- lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0)
- lazy val AbstractFunctionClass = mkArityArray("runtime.AbstractFunction", MaxFunctionArity, 0)
+ lazy val ProductClass = new VarArityClass("Product", MaxProductArity, countFrom = 1, init = Some(UnitClass))
+ lazy val TupleClass = new VarArityClass("Tuple", MaxTupleArity, countFrom = 1)
+ lazy val FunctionClass = new VarArityClass("Function", MaxFunctionArity)
+ lazy val AbstractFunctionClass = new VarArityClass("runtime.AbstractFunction", MaxFunctionArity)
/** Creators for TupleN, ProductN, FunctionN. */
- def tupleType(elems: List[Type]) = aritySpecificType(TupleClass, elems)
- def functionType(formals: List[Type], restpe: Type) = aritySpecificType(FunctionClass, formals, restpe)
- def abstractFunctionType(formals: List[Type], restpe: Type) = aritySpecificType(AbstractFunctionClass, formals, restpe)
+ def tupleType(elems: List[Type]) = TupleClass.specificType(elems)
+ def functionType(formals: List[Type], restpe: Type) = FunctionClass.specificType(formals, restpe)
+ def abstractFunctionType(formals: List[Type], restpe: Type) = AbstractFunctionClass.specificType(formals, restpe)
def wrapArrayMethodName(elemtp: Type): TermName = elemtp.typeSymbol match {
case ByteClass => nme.wrapByteArray
@@ -625,12 +624,11 @@ trait Definitions extends api.StandardDefinitions {
else nme.genericWrapArray
}
- // NOTE: returns true for NoSymbol since it's included in the TupleClass array -- is this intensional?
- def isTupleSymbol(sym: Symbol) = TupleClass contains unspecializedSymbol(sym)
- def isProductNClass(sym: Symbol) = ProductClass contains sym
+ def isTupleSymbol(sym: Symbol) = TupleClass.seq contains unspecializedSymbol(sym)
+ def isProductNClass(sym: Symbol) = ProductClass.seq contains sym
def tupleField(n: Int, j: Int) = getMemberValue(TupleClass(n), nme.productAccessorName(j))
- def isFunctionSymbol(sym: Symbol) = FunctionClass contains unspecializedSymbol(sym)
- def isProductNSymbol(sym: Symbol) = ProductClass contains unspecializedSymbol(sym)
+ def isFunctionSymbol(sym: Symbol) = FunctionClass.seq contains unspecializedSymbol(sym)
+ def isProductNSymbol(sym: Symbol) = ProductClass.seq contains unspecializedSymbol(sym)
def unspecializedSymbol(sym: Symbol): Symbol = {
if (sym hasFlag SPECIALIZED) {
@@ -1220,7 +1218,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val symbolsNotPresentInBytecode = syntheticCoreClasses ++ syntheticCoreMethods ++ hijackedCoreClasses
/** Is the symbol that of a parent which is added during parsing? */
- lazy val isPossibleSyntheticParent = ProductClass.toSet[Symbol] + ProductRootClass + SerializableClass
+ lazy val isPossibleSyntheticParent = ProductClass.seq.toSet[Symbol] + ProductRootClass + SerializableClass
private lazy val boxedValueClassesSet = boxedClass.values.toSet[Symbol] + BoxedUnitClass