diff options
author | Den Shabalin <den.shabalin@gmail.com> | 2013-09-10 15:32:07 +0200 |
---|---|---|
committer | Den Shabalin <den.shabalin@gmail.com> | 2013-09-12 12:43:28 +0200 |
commit | 8a7b5666b6f10728f7c3ae9ca1bc2a8b82f6b965 (patch) | |
tree | 3e6ad67c8cba6e23047f991e71f1256e652d25bb /src | |
parent | 95fe19545d60ae9aa79d2c8d5665c7f3b0cbdb1a (diff) | |
download | scala-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.
Diffstat (limited to 'src')
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 |