summaryrefslogtreecommitdiff
path: root/src/build/genprod.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-02-20 06:51:57 +0000
committerPaul Phillips <paulp@improving.org>2011-02-20 06:51:57 +0000
commitfd1ca1e63c876046936f681be26730a301da8ff2 (patch)
tree6db9fac72b958af0df8c51eeae8478c0fe5b6a98 /src/build/genprod.scala
parent6a570deed1790889f7036a00c045c15217313587 (diff)
downloadscala-fd1ca1e63c876046936f681be26730a301da8ff2.tar.gz
scala-fd1ca1e63c876046936f681be26730a301da8ff2.tar.bz2
scala-fd1ca1e63c876046936f681be26730a301da8ff2.zip
Moved unlift to the Function companion object, ...
Moved unlift to the Function companion object, which might have been better in the first place. Had to make a minor change to genprod, and then I couldn't escape that unscathed. Finished the not very complete undertaking I found there to update the scaladoc. Lots of little changes to the generated text and code. I changed genprod to only put a unique stamp on Function0 so we can stop having a 100 file diff everytime an i is dotted somewhere. Closes #3825, no review.
Diffstat (limited to 'src/build/genprod.scala')
-rw-r--r--src/build/genprod.scala165
1 files changed, 74 insertions, 91 deletions
diff --git a/src/build/genprod.scala b/src/build/genprod.scala
index c95346ad94..d1c610d046 100644
--- a/src/build/genprod.scala
+++ b/src/build/genprod.scala
@@ -15,7 +15,7 @@
* @author Burak Emir, Stephane Micheloud, Geoffrey Washburn, Paul Phillips
* @version 1.1
*/
-object genprod {
+object genprod extends Application {
val MAX_ARITY = 22
def arities = (1 to MAX_ARITY).toList
@@ -48,16 +48,12 @@ object genprod {
def covariantSpecs = ""
def contravariantSpecs = ""
def contraCoArgs = typeArgsString((targs map (contravariantSpecs + "-" + _)) ::: List(covariantSpecs + "+R"))
- def constructorArgs = (targs).map( _.toLowerCase ) mkString ","
- def fields = (mdefs, targs).zipped.map(_ + ":" + _) mkString ","
- def funArgs = (vdefs, targs).zipped.map(_ + ":" + _) mkString ","
+ def constructorArgs = (targs).map( _.toLowerCase ) mkString ", "
+ def fields = (mdefs, targs).zipped.map(_ + ": " + _) mkString ", "
+ def funArgs = (vdefs, targs).zipped.map(_ + ": " + _) mkString ", "
- def genprodString = "// generated by genprod on %s %s %s".format(now, withFancy, withMoreMethods)
- def now = new java.util.Date().toString()
+ def genprodString = " See scala.Function0 for timestamp."
def moreMethods = ""
- def descriptiveComment = ""
- def withFancy = if (descriptiveComment.isEmpty) "" else "(with fancy comment)"
- def withMoreMethods = if (moreMethods.isEmpty) "" else "(with extra methods)"
def packageDef = "scala"
def imports = ""
@@ -69,29 +65,27 @@ object genprod {
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
-
-%s
+// GENERATED CODE: DO NOT EDIT.%s
package %s
%s
-""".trim.format(genprodString, packageDef, imports) + "\n\n"
+""".trim.format(genprodString, packageDef, imports)
}
- def main(args: Array[String]) {
- if (args.length != 1) {
- println("please give path of output directory")
- exit(-1)
- }
- val out = args(0)
- def writeFile(node: scala.xml.Node) {
- import scala.tools.nsc.io._
- val f = Path(out) / node.attributes("name").toString
- f.parent.createDirectory(force = true)
- f.toFile writeAll node.text
- }
-
- allfiles foreach writeFile
+ def args = arguments
+ if (args.length != 1) {
+ println("please give path of output directory")
+ exit(-1)
+ }
+ val out = args(0)
+ def writeFile(node: scala.xml.Node) {
+ import scala.tools.nsc.io._
+ val f = Path(out) / node.attributes("name").toString
+ f.parent.createDirectory(force = true)
+ f.toFile writeAll node.text
}
+
+ allfiles foreach writeFile
}
import genprod._
@@ -101,17 +95,16 @@ import genprod._
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz */
object FunctionZero extends Function(0) {
+ override def genprodString = "\n// genprod generated these sources at: " + new java.util.Date()
override def covariantSpecs = "@specialized "
- override def descriptiveComment = functionNTemplate.format("currentSeconds", "anonfun0",
+ override def descriptiveComment = functionNTemplate.format("javaVersion", "anonfun0",
"""
- * val currentSeconds = () => System.currentTimeMillis() / 1000L
+ * val javaVersion = () => sys.props("java.version")
*
- * val anonfun0 = new Function0[Long] {
- * def apply(): Long = System.currentTimeMillis() / 1000L
+ * val anonfun0 = new Function0[String] {
+ * def apply(): String = sys.props("java.version")
* }
- *
- * println(currentSeconds())
- * println(anonfun0())
+ * assert(javaVersion() == anonfun0())
* """)
override def moreMethods = ""
}
@@ -123,41 +116,28 @@ object FunctionOne extends Function(1) {
override def descriptiveComment = functionNTemplate.format("succ", "anonfun1",
"""
* val succ = (x: Int) => x + 1
- *
* val anonfun1 = new Function1[Int, Int] {
* def apply(x: Int): Int = x + 1
* }
- *
- * println(succ(0))
- * println(anonfun1(0))
+ * assert(succ(0) == anonfun1(0))
* """)
override def moreMethods = """
- /** Returns a function taking one argument that applies this function to `g` applied to the argument.
- * @return a function `f` such that `f(x) == apply(g(x))`
+ /** Composes two instances of Function1 in a new Function1, with this function applied last.
+ *
+ * @tparam A the type to which function `g` can be applied
+ * @param g a function A => T1
+ * @return a new function `f` such that `f(x) == apply(g(x))`
*/
def compose[A](g: A => T1): A => R = { x => apply(g(x)) }
- /** Returns a function taking one argument that applies `g` to this function applied to the argument.
- * @return a function `f` such that `f(x) == g(apply(x))`
- */
- def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) }
-
- /** Turns a function `A => Option[B]` into a `PartialFunction[A, B]`. Important note:
- * this transformation implies the original function will be called 2 or more
- * times on each logical invocation, because the only way to supply an implementation
- * of isDefinedAt is to call the function and examine the return value.
+ /** Composes two instances of Function1 in a new Function1, with this function applied first.
*
- * @see PartialFunction#lift
- * @return a partial function which is defined for those inputs
- * where this function returns Some(_) and undefined where
- * this function returns None.
+ * @tparam A the result type of function `g`
+ * @param g a function R => A
+ * @return a new function `f` such that `f(x) == g(apply(x))`
*/
- def unlift[R1](implicit ev: R <:< Option[R1]): PartialFunction[T1, R1] = new PartialFunction[T1, R1] {
- def apply(x: T1): R1 = ev(Function1.this.apply(x)).get
- def isDefinedAt(x: T1): Boolean = Function1.this.apply(x).isDefined
- override def lift = Function1.this.asInstanceOf[T1 => Option[R1]]
- }
+ def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) }
"""
}
@@ -172,14 +152,11 @@ object FunctionTwo extends Function(2) {
* val anonfun2 = new Function2[Int, Int, Int] {
* def apply(x: Int, y: Int): Int = if (x < y) y else x
* }
- *
- * println(max(0, 1))
- * println(anonfun2(0, 1))
+ * assert(max(0, 1) == anonfun2(0, 1))
* """)
}
-object Function
-{
+object Function {
def make(i: Int) = apply(i)()
def apply(i: Int) = i match {
case 0 => FunctionZero
@@ -190,10 +167,10 @@ object Function
}
class Function(val i: Int) extends Group("Function") with Arity {
- val functionNTemplate = """
- * In the following example, the definition of
- * %s is a shorthand for the anonymous class
- * definition %s:
+ def descriptiveComment = ""
+ def functionNTemplate = """
+ * In the following example, the definition of %s is a
+ * shorthand for the anonymous class definition %s:
*
* {{{
* object Main extends Application { %s }
@@ -203,17 +180,16 @@ class Function(val i: Int) extends Group("Function") with Arity {
def apply() = {
<file name={fileName}>{header}
-/** Function with {i} parameter{s}.
+/** A function of {i} parameter{s}.
* {descriptiveComment}
*/
trait {className}{contraCoArgs} extends AnyRef {{ self =>
- /**
- * Applies this function to the argument{s}.
- * @return the results of application of this function to the passed-in argument{s}
+ /** Apply the body of this function to the argument{s}.
+ * @return the result of function application.
*/
def apply({funArgs}): R
- override def toString() = {toStr}
{moreMethods}
+ override def toString() = {toStr}
}}
</file>
}
@@ -235,24 +211,24 @@ trait {className}{contraCoArgs} extends AnyRef {{ self =>
// f(x1,x2,x3,x4,x5,x6) == (f.curried)(x1)(x2)(x3)(x4)(x5)(x6)
def curryComment = { """
- /**
- * Returns a curried version of this function.
- * @return a function `f` such that `f%s == apply%s`
+ /** Creates a curried version of this function.
+ *
+ * @return a function `f` such that `f%s == apply%s`
*/
""".format(xdefs map ("(" + _ + ")") mkString, commaXs)
}
def tupleMethod = {
def comment = """
- /**
- * Returns a version of this function that takes a [[scala.Tuple%d]] as its argument
- * instead of %d arguments.
- * @return a function `f` such that `f(%s) == f(Tuple%d%s) == apply%s`
+ /** Creates a tupled version of this function: instead of %d arguments,
+ * it accepts a single [[scala.Tuple%d]] argument.
+ *
+ * @return a function `f` such that `f(%s) == f(Tuple%d%s) == apply%s`
*/
-""".format(i,i,commaXs, i, commaXs, commaXs)
+""".format(i, i, commaXs, i, commaXs, commaXs)
def body = "case Tuple%d%s => apply%s".format(i, commaXs, commaXs)
- comment + " def tupled: Tuple%d%s => R = {\n %s\n }\n".format(i, invariantArgs, body)
+ comment + " def tupled: Tuple%d%s => R = {\n %s\n }".format(i, invariantArgs, body)
}
def curryMethod = {
@@ -528,8 +504,15 @@ object TupleThree extends Tuple(3) {
"""
}
-class Tuple(val i: Int) extends Group("Tuple") with Arity
-{
+class Tuple(val i: Int) extends Group("Tuple") with Arity {
+ private def idiomatic =
+ if (i < 2) ""
+ else " Note that it is more idiomatic to create a %s via `(%s)`".format(className, constructorArgs)
+
+ private def params = (
+ 1 to i map (x => " * @param _%d Element %d of this Tuple%d".format(x, x, i))
+ ) mkString "\n"
+
// prettifies it a little if it's overlong
def mkToString() = {
def str(xs: List[String]) = xs.mkString(""" + "," + """)
@@ -545,10 +528,9 @@ class Tuple(val i: Int) extends Group("Tuple") with Arity
<file name={fileName}>{header}
/** A tuple of {i} elements; the canonical representation of a [[scala.{Product.className(i)}]].
- * {descriptiveComment}
*
- * @constructor Create a new tuple with {i} elements. Note that it is more idiomatic to create a {className} via `({constructorArgs})`.
-{to.map { index => " * @param _" + index + " element " + index + " of this `Tuple`\n" }}
+ * @constructor Create a new tuple with {i} elements.{idiomatic}
+{params}
*/
case class {className}{covariantArgs}({fields})
extends {Product.className(i)}{invariantArgs}
@@ -586,8 +568,7 @@ object ProductTwo extends Product(2)
class Product(val i: Int) extends Group("Product") with Arity {
val productElementComment = """
- /**
- * Returns the n-th projection of this product if 0 < n <= productArity,
+ /** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
@@ -603,7 +584,11 @@ class Product(val i: Int) extends Group("Product") with Arity {
}
def proj = {
(mdefs,targs).zipped.map( (_,_) ).zipWithIndex.map { case ((method,typeName),index) =>
- " /** Returns a projection of element %d of this product.\n * @return a projection of element %d */\n def %s: %s\n\n".format(index+1,index+1,method,typeName)
+ """| /** A projection of element %d of this Product.
+ | * @return A projection of element %d.
+ | */
+ | def %s: %s
+ |""".stripMargin.format(index + 1, index + 1, method, typeName)
} mkString
}
@@ -615,12 +600,10 @@ object {className} {{
}}
/** {className} is a cartesian product of {i} component{s}.
- * {descriptiveComment}
* @since 2.3
*/
trait {className}{covariantArgs} extends Product {{
- /**
- * The arity of this product.
+ /** The arity of this product.
* @return {i}
*/
override def productArity = {i}