summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-09-16 03:06:34 -0700
committerJason Zaugg <jzaugg@gmail.com>2013-09-16 03:06:34 -0700
commit9dbc321504ad5550638d6d7c2b3cd2f98273cf74 (patch)
tree7459704f5c9f0d471e63ec56b4f15c2803f10a59 /src/reflect
parent8c68723acd738d94d049ac996d5e0ea22659c4ba (diff)
parent8a7b5666b6f10728f7c3ae9ca1bc2a8b82f6b965 (diff)
downloadscala-9dbc321504ad5550638d6d7c2b3cd2f98273cf74.tar.gz
scala-9dbc321504ad5550638d6d7c2b3cd2f98273cf74.tar.bz2
scala-9dbc321504ad5550638d6d7c2b3cd2f98273cf74.zip
Merge pull request #2935 from densh/topic/si-7304-6489-6701
SI-6701, SI-7304, SI-6489, variable arity definitions refactoring
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/api/FlagSets.scala3
-rw-r--r--src/reflect/scala/reflect/api/StandardDefinitions.scala18
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala24
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala24
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala46
-rw-r--r--src/reflect/scala/reflect/internal/FlagSets.scala1
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala6
7 files changed, 66 insertions, 56 deletions
diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala
index 8a1d2f7f1d..3d5a213f2f 100644
--- a/src/reflect/scala/reflect/api/FlagSets.scala
+++ b/src/reflect/scala/reflect/api/FlagSets.scala
@@ -166,6 +166,9 @@ trait FlagSets { self: Universe =>
/** Flag indicating that tree represents a variable or a member initialized to the default value */
val DEFAULTINIT: FlagSet
+
+ /** Flag indicating that tree was generated by the compiler */
+ val SYNTHETIC: FlagSet
}
/** The empty set of flags
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/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index 443f34ccae..7a627bc875 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -2210,13 +2210,13 @@ trait Trees { self: Universe =>
* Flattens directly nested blocks.
* @group Factories
*/
- @deprecated("Use the canonical Block constructor, explicitly specifying its expression if necessary. Flatten directly nested blocks manually if needed", "2.10.1")
+ @deprecated("Use q\"{..$stats}\" instead. Flatten directly nested blocks manually if needed", "2.10.1")
def Block(stats: Tree*): Block
/** A factory method for `CaseDef` nodes.
* @group Factories
*/
- @deprecated("Use the canonical CaseDef constructor passing EmptyTree for guard", "2.10.1")
+ @deprecated("Use cq\"$pat => $body\" instead", "2.10.1")
def CaseDef(pat: Tree, body: Tree): CaseDef
/** A factory method for `Bind` nodes.
@@ -2228,50 +2228,50 @@ trait Trees { self: Universe =>
/** A factory method for `Try` nodes.
* @group Factories
*/
- @deprecated("Use canonical CaseDef constructors to to create exception catching expressions and then wrap them in Try", "2.10.1")
+ @deprecated("Convert cases into casedefs and use q\"try $body catch { case ..$newcases }\" instead", "2.10.1")
def Try(body: Tree, cases: (Tree, Tree)*): Try
/** A factory method for `Throw` nodes.
* @group Factories
*/
- @deprecated("Use the canonical New constructor to create an object instantiation expression and then wrap it in Throw", "2.10.1")
+ @deprecated("Use q\"throw new $tpe(..$args)\" instead", "2.10.1")
def Throw(tpe: Type, args: Tree*): Throw
/** Factory method for object creation `new tpt(args_1)...(args_n)`
* A `New(t, as)` is expanded to: `(new t).<init>(as)`
* @group Factories
*/
- @deprecated("Use Apply(...Apply(Select(New(tpt), nme.CONSTRUCTOR), args1)...argsN) instead", "2.10.1")
+ @deprecated("Use q\"new $tpt(...$argss)\" instead", "2.10.1")
def New(tpt: Tree, argss: List[List[Tree]]): Tree
/** 0-1 argument list new, based on a type.
* @group Factories
*/
- @deprecated("Use New(TypeTree(tpe), args.toList) instead", "2.10.1")
+ @deprecated("Use q\"new $tpe(..$args)\" instead", "2.10.1")
def New(tpe: Type, args: Tree*): Tree
/** 0-1 argument list new, based on a symbol.
* @group Factories
*/
- @deprecated("Use New(sym.toType, args) instead", "2.10.1")
+ @deprecated("Use q\"new ${sym.toType}(..$args)\" instead", "2.10.1")
def New(sym: Symbol, args: Tree*): Tree
/** A factory method for `Apply` nodes.
* @group Factories
*/
- @deprecated("Use Apply(Ident(sym), args.toList) instead", "2.10.1")
+ @deprecated("Use q\"$sym(..$args)\" instead", "2.10.1")
def Apply(sym: Symbol, args: Tree*): Tree
/** 0-1 argument list new, based on a type tree.
* @group Factories
*/
- @deprecated("Use Apply(Select(New(tpt), nme.CONSTRUCTOR), args) instead", "2.10.1")
+ @deprecated("Use q\"new $tpt(..$args)\" instead", "2.10.1")
def ApplyConstructor(tpt: Tree, args: List[Tree]): Tree
/** A factory method for `Super` nodes.
* @group Factories
*/
- @deprecated("Use Super(This(sym), mix) instead", "2.10.1")
+ @deprecated("Use q\"$sym.super[$mix].x\".qualifier instead", "2.10.1")
def Super(sym: Symbol, mix: TypeName): Tree
/** A factory method for `This` nodes.
@@ -2283,7 +2283,7 @@ trait Trees { self: Universe =>
* The string `name` argument is assumed to represent a [[scala.reflect.api.Names#TermName `TermName`]].
* @group Factories
*/
- @deprecated("Use Select(tree, newTermName(name)) instead", "2.10.1")
+ @deprecated("Use Select(tree, TermName(name)) instead", "2.10.1")
def Select(qualifier: Tree, name: String): Select
/** A factory method for `Select` nodes.
@@ -2294,7 +2294,7 @@ trait Trees { self: Universe =>
/** A factory method for `Ident` nodes.
* @group Factories
*/
- @deprecated("Use Ident(newTermName(name)) instead", "2.10.1")
+ @deprecated("Use Ident(TermName(name)) instead", "2.10.1")
def Ident(name: String): Ident
/** A factory method for `Ident` nodes.
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 c56637874c..ed1c3f1044 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) {
@@ -1233,7 +1231,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
diff --git a/src/reflect/scala/reflect/internal/FlagSets.scala b/src/reflect/scala/reflect/internal/FlagSets.scala
index 961adb2c57..84825ff2da 100644
--- a/src/reflect/scala/reflect/internal/FlagSets.scala
+++ b/src/reflect/scala/reflect/internal/FlagSets.scala
@@ -42,5 +42,6 @@ trait FlagSets extends api.FlagSets { self: SymbolTable =>
val DEFAULTPARAM : FlagSet = Flags.DEFAULTPARAM
val PRESUPER : FlagSet = Flags.PRESUPER
val DEFAULTINIT : FlagSet = Flags.DEFAULTINIT
+ val SYNTHETIC : FlagSet = Flags.SYNTHETIC
}
}
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index 07fa6fb317..26adf20c52 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -437,4 +437,10 @@ abstract class TreeGen extends macros.TreeBuilder {
else if (!stats.last.isTerm) Block(stats, Literal(Constant(())))
else if (stats.length == 1) stats.head
else Block(stats.init, stats.last)
+
+ def mkTreeOrBlock(stats: List[Tree]) = stats match {
+ case Nil => EmptyTree
+ case head :: Nil => head
+ case _ => gen.mkBlock(stats)
+ }
}