diff options
author | Paul Phillips <paulp@improving.org> | 2011-03-15 04:02:35 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-03-15 04:02:35 +0000 |
commit | 4383277103b8bc78244aff05d5116b07e70f2c2a (patch) | |
tree | cc3c66dd4dd1da779fb624478bce56bc125a6aaf | |
parent | e96dba0c9a2467c6cf396c70a48ef0750503c26e (diff) | |
download | scala-4383277103b8bc78244aff05d5116b07e70f2c2a.tar.gz scala-4383277103b8bc78244aff05d5116b07e70f2c2a.tar.bz2 scala-4383277103b8bc78244aff05d5116b07e70f2c2a.zip |
Addresses the issues swirling around Double.Eps...
Addresses the issues swirling around Double.Epsilon and friends which
were battled out in more than one venue and then aptly summarized by
retronym in #3791. Thanks to Simon Ochsenreither for submitting a patch;
I wasn't able to use too much of it because the source code for these
types is generated, but effort is always appreciated. Closes #3791, and
I'm tired and I'd hate to blow this one at this late date: review by
rytz.
-rw-r--r-- | src/compiler/scala/tools/cmd/gen/AnyVals.scala | 84 | ||||
-rw-r--r-- | src/compiler/scala/tools/cmd/gen/Codegen.scala | 12 | ||||
-rw-r--r-- | src/compiler/scala/tools/cmd/gen/CodegenSpec.scala | 6 | ||||
-rwxr-xr-x | src/library/scala/Boolean.scala | 2 | ||||
-rw-r--r-- | src/library/scala/Byte.scala | 2 | ||||
-rw-r--r-- | src/library/scala/Char.scala | 2 | ||||
-rw-r--r-- | src/library/scala/Double.scala | 17 | ||||
-rw-r--r-- | src/library/scala/Float.scala | 17 | ||||
-rw-r--r-- | src/library/scala/Int.scala | 2 | ||||
-rw-r--r-- | src/library/scala/Long.scala | 2 | ||||
-rw-r--r-- | src/library/scala/Math.scala | 6 | ||||
-rw-r--r-- | src/library/scala/Short.scala | 2 | ||||
-rwxr-xr-x | src/library/scala/Unit.scala | 2 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/Arbitrary.scala | 4 | ||||
-rw-r--r-- | test/files/neg/t3115.check | 4 | ||||
-rwxr-xr-x | tools/codegen | 3 | ||||
-rwxr-xr-x | tools/codegen-anyvals | 5 |
17 files changed, 103 insertions, 69 deletions
diff --git a/src/compiler/scala/tools/cmd/gen/AnyVals.scala b/src/compiler/scala/tools/cmd/gen/AnyVals.scala index 23a31a56b4..f6f48359cd 100644 --- a/src/compiler/scala/tools/cmd/gen/AnyVals.scala +++ b/src/compiler/scala/tools/cmd/gen/AnyVals.scala @@ -7,9 +7,8 @@ package scala.tools.cmd package gen trait AnyValTemplates { - def timestampString = "// generated on " + new java.util.Date + "\n" - - def template = """ + def timestampString = "" + def template = (""" /* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** @@ -22,10 +21,10 @@ trait AnyValTemplates { package scala import java.{ lang => jl } - """.trim.format(timestampString) + "\n\n" + ) - val booleanBody = """ + def booleanBody = """ final class Boolean extends AnyVal { def unary_! : Boolean = sys.error("stub") @@ -48,7 +47,7 @@ object Boolean extends AnyValCompanion { } """.trim - val unitBody = """ + def unitBody = """ import runtime.BoxedUnit final class Unit extends AnyVal { } @@ -59,6 +58,40 @@ object Unit extends AnyValCompanion { def unbox(x: jl.Object): Unit = () } """.trim + + def cardinalCompanion = """ +final val MinValue = @type@.MIN_VALUE +final val MaxValue = @type@.MAX_VALUE + +def box(x: @name@): @type@ = @type@.valueOf(x) +def unbox(x: jl.Object): @name@ = x.asInstanceOf[@type@].@lcname@Value() +override def toString = "object scala.@name@" + """.trim.lines + + def floatingCompanion = """ +/** The smallest positive value greater than @zero@.*/ +final val MinPositiveValue = @type@.MIN_VALUE +final val NaN = @type@.NaN +final val PositiveInfinity = @type@.POSITIVE_INFINITY +final val NegativeInfinity = @type@.NEGATIVE_INFINITY + +@deprecated("use @name@.MinPositiveValue instead") +final val Epsilon = MinPositiveValue + +/** The negative number with the greatest (finite) absolute value which is representable + * by a @name@. Note that it differs from [[java.lang.@name@.MIN_VALUE]], which + * is the smallest positive value representable by a @name@. In Scala that number + * is called @name@.MinPositiveValue. + */ +final val MinValue = -@type@.MAX_VALUE + +/** The largest finite positive number representable as a @name@. */ +final val MaxValue = @type@.MAX_VALUE + +def box(x: @name@): @type@ = @type@.valueOf(x) +def unbox(x: jl.Object): @name@ = x.asInstanceOf[@type@].@lcname@Value() +override def toString = "object scala.@name@" + """.trim.lines } class AnyVals extends AnyValTemplates { @@ -90,11 +123,18 @@ class AnyVals extends AnyValTemplates { val isCardinal = cardinal contains name val restype = if ("LFD" contains name.head) name else I val tpe = javaType(name) + val zero = name.head match { + case 'L' => "0L" + case 'F' => "0.0f" + case 'D' => "0.0d" + case _ => "0" + } val interpolations = Map( "@restype@" -> restype, "@name@" -> name, "@type@" -> tpe, - "@lcname@" -> name.toLowerCase + "@lcname@" -> name.toLowerCase, + "@zero@" -> zero ) def mkCoercions = numeric map (x => "def to%s: %s".format(x, x)) @@ -131,7 +171,7 @@ class AnyVals extends AnyValTemplates { } assemble("final class", "AnyVal", lines) } - def mkObject = assemble("object", "AnyValCompanion", companionLines map interpolate) + def mkObject = assemble("object", "AnyValCompanion", companionBody map interpolate toList) def assemble(what: String, parent: String, lines: List[String]): String = ( List(what, name, "extends", parent, "{").mkString(" ") +: @@ -171,35 +211,9 @@ class AnyVals extends AnyValTemplates { def boolBinops = List("==", "!=", "<", "<=", ">", ">=") def otherBinops = List("+", "-" ,"*", "/", "%") - def floatingCompanion = List( - "final val MinPositiveValue = @type@.MIN_VALUE", - "final val MinNegativeValue = -@type@.MAX_VALUE", - "final val NaN = @type@.NaN", - "final val PositiveInfinity = @type@.POSITIVE_INFINITY", - "final val NegativeInfinity = @type@.NEGATIVE_INFINITY", - "", - """@deprecated("use @name@.MinPositiveValue instead")""", - "final val Epsilon = MinPositiveValue", - """@deprecated("use @name@.MinNegativeValue instead")""", - "final val MinValue = MinNegativeValue" - ) - - def cardinalCompanion = List( - "final val MinValue = @type@.MIN_VALUE" - ) - - def commonCompanion = List( - "final val MaxValue = @type@.MAX_VALUE", - "", - "def box(x: @name@): @type@ = @type@.valueOf(x)", - "def unbox(x: jl.Object): @name@ = x.asInstanceOf[@type@].@lcname@Value()", - "override def toString = \"object scala.@name@\"" - ) - - def companionLines = ( + def companionBody = if (isCardinal) cardinalCompanion else floatingCompanion - ) ++ commonCompanion } } diff --git a/src/compiler/scala/tools/cmd/gen/Codegen.scala b/src/compiler/scala/tools/cmd/gen/Codegen.scala index a96e53d4e2..d7801f2c08 100644 --- a/src/compiler/scala/tools/cmd/gen/Codegen.scala +++ b/src/compiler/scala/tools/cmd/gen/Codegen.scala @@ -27,19 +27,19 @@ object Codegen { if (anyvals || all) { val av = new AnyVals { - override def timestampString = - if (stamp) super.timestampString - else "" + override def timestampString = ( + "// DO NOT EDIT, CHANGES WILL BE LOST.\n" + ( + if (stamp) "// Generated by tools/codegen on " + new java.util.Date + "\n" else "" + ) + ) } + av.make() foreach { case (name, code ) => val file = out / (name + ".scala") toFile; echo("Writing: " + file) file writeAll code } } - if (products || all) { - () - } } } diff --git a/src/compiler/scala/tools/cmd/gen/CodegenSpec.scala b/src/compiler/scala/tools/cmd/gen/CodegenSpec.scala index e99c49721f..7f4b9c1bb0 100644 --- a/src/compiler/scala/tools/cmd/gen/CodegenSpec.scala +++ b/src/compiler/scala/tools/cmd/gen/CodegenSpec.scala @@ -10,15 +10,15 @@ import FromString.ExistingDir trait CodegenSpec extends Spec with Meta.StdOpts with Interpolation { def referenceSpec = CodegenSpec - def programInfo = Spec.Info("codegen", "", "scala.tools.cmd.cmd") + def programInfo = Spec.Info("codegen", "", "scala.tools.cmd.gen.Codegen") import FromString.ExistingDir help("Usage: codegen [<options>]") - val inDir = "in" / "directory containing templates" --^ ExistingDir + // val inDir = "in" / "directory containing templates" --^ ExistingDir val outDir = "out" / "directory for generated files" --^ ExistingDir - val install = "install" / "write source files directly to src/library/scala" + // val install = "install" / "write source files directly to src/library/scala" val anyvals = "anyvals" / "generate sources for AnyVal types" --? val products = "products" / "generate sources for ProductN, FunctionN, etc." --? val genall = "all" / "generate sources for everything" --? diff --git a/src/library/scala/Boolean.scala b/src/library/scala/Boolean.scala index d5e9eb950e..dc2076cb1d 100755 --- a/src/library/scala/Boolean.scala +++ b/src/library/scala/Boolean.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -// generated on Sun Jan 23 21:13:38 PST 2011 +// DO NOT EDIT, CHANGES WILL BE LOST. package scala diff --git a/src/library/scala/Byte.scala b/src/library/scala/Byte.scala index e3f4a82003..69d435b33b 100644 --- a/src/library/scala/Byte.scala +++ b/src/library/scala/Byte.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -// generated on Sun Jan 23 21:13:38 PST 2011 +// DO NOT EDIT, CHANGES WILL BE LOST. package scala diff --git a/src/library/scala/Char.scala b/src/library/scala/Char.scala index 3c3f292fd2..88d7617ea5 100644 --- a/src/library/scala/Char.scala +++ b/src/library/scala/Char.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -// generated on Sun Jan 23 21:13:38 PST 2011 +// DO NOT EDIT, CHANGES WILL BE LOST. package scala diff --git a/src/library/scala/Double.scala b/src/library/scala/Double.scala index cc4f597bda..fe37860c07 100644 --- a/src/library/scala/Double.scala +++ b/src/library/scala/Double.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -// generated on Sun Jan 23 21:13:38 PST 2011 +// DO NOT EDIT, CHANGES WILL BE LOST. package scala @@ -119,16 +119,23 @@ final class Double extends AnyVal { object Double extends AnyValCompanion { + /** The smallest positive value greater than 0.0d.*/ final val MinPositiveValue = jl.Double.MIN_VALUE - final val MinNegativeValue = -jl.Double.MAX_VALUE final val NaN = jl.Double.NaN final val PositiveInfinity = jl.Double.POSITIVE_INFINITY final val NegativeInfinity = jl.Double.NEGATIVE_INFINITY @deprecated("use Double.MinPositiveValue instead") - final val Epsilon = MinPositiveValue - @deprecated("use Double.MinNegativeValue instead") - final val MinValue = MinNegativeValue + final val Epsilon = MinPositiveValue + + /** The negative number with the greatest (finite) absolute value which is representable + * by a Double. Note that it differs from [[java.lang.Double.MIN_VALUE]], which + * is the smallest positive value representable by a Double. In Scala that number + * is called Double.MinPositiveValue. + */ + final val MinValue = -jl.Double.MAX_VALUE + + /** The largest finite positive number representable as a Double. */ final val MaxValue = jl.Double.MAX_VALUE def box(x: Double): jl.Double = jl.Double.valueOf(x) diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala index 81b464078d..39e510e477 100644 --- a/src/library/scala/Float.scala +++ b/src/library/scala/Float.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -// generated on Sun Jan 23 21:13:38 PST 2011 +// DO NOT EDIT, CHANGES WILL BE LOST. package scala @@ -119,16 +119,23 @@ final class Float extends AnyVal { object Float extends AnyValCompanion { + /** The smallest positive value greater than 0.0f.*/ final val MinPositiveValue = jl.Float.MIN_VALUE - final val MinNegativeValue = -jl.Float.MAX_VALUE final val NaN = jl.Float.NaN final val PositiveInfinity = jl.Float.POSITIVE_INFINITY final val NegativeInfinity = jl.Float.NEGATIVE_INFINITY @deprecated("use Float.MinPositiveValue instead") - final val Epsilon = MinPositiveValue - @deprecated("use Float.MinNegativeValue instead") - final val MinValue = MinNegativeValue + final val Epsilon = MinPositiveValue + + /** The negative number with the greatest (finite) absolute value which is representable + * by a Float. Note that it differs from [[java.lang.Float.MIN_VALUE]], which + * is the smallest positive value representable by a Float. In Scala that number + * is called Float.MinPositiveValue. + */ + final val MinValue = -jl.Float.MAX_VALUE + + /** The largest finite positive number representable as a Float. */ final val MaxValue = jl.Float.MAX_VALUE def box(x: Float): jl.Float = jl.Float.valueOf(x) diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala index 416512d43b..69fb0a66b7 100644 --- a/src/library/scala/Int.scala +++ b/src/library/scala/Int.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -// generated on Sun Jan 23 21:13:38 PST 2011 +// DO NOT EDIT, CHANGES WILL BE LOST. package scala diff --git a/src/library/scala/Long.scala b/src/library/scala/Long.scala index 25b6873e72..7fdefebae3 100644 --- a/src/library/scala/Long.scala +++ b/src/library/scala/Long.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -// generated on Sun Jan 23 21:13:38 PST 2011 +// DO NOT EDIT, CHANGES WILL BE LOST. package scala diff --git a/src/library/scala/Math.scala b/src/library/scala/Math.scala index 3d300b8259..a1663a6a02 100644 --- a/src/library/scala/Math.scala +++ b/src/library/scala/Math.scala @@ -13,7 +13,7 @@ package scala * operations such as the elementary exponential, logarithm, square root, and * trigonometric functions. */ -@deprecated("use scala.math package object instead.\n(Example package object usage: scala.math.Pi )") +@deprecated("use the scala.math package object instead.\n(Example package object usage: scala.math.Pi )") object Math extends MathCommon { @deprecated("Use scala.Byte.MinValue instead") val MIN_BYTE = java.lang.Byte.MIN_VALUE @@ -50,7 +50,7 @@ object Math extends MathCommon { val MIN_FLOAT = -java.lang.Float.MAX_VALUE /** The smallest difference between two values of <a href="Float.html" target="_self">scala.Float</a>. */ - @deprecated("Use scala.Float.Epsilon instead") + @deprecated("Use scala.Float.MinPositiveValue instead") val EPS_FLOAT = java.lang.Float.MIN_VALUE /** The greatest possible value for <a href="Float.html" target="_self">scala.Float</a>. */ @@ -74,7 +74,7 @@ object Math extends MathCommon { val MIN_DOUBLE = -java.lang.Double.MAX_VALUE /** The smallest difference between two values of <a href="Double.html" target="_self">scala.Double</a>. */ - @deprecated("Use scala.Double.Epsilon instead") + @deprecated("Use scala.Double.MinPositiveValue instead") val EPS_DOUBLE = java.lang.Double.MIN_VALUE /** The greatest possible value for <a href="Double.html" target="_self">scala.Double</a>. */ diff --git a/src/library/scala/Short.scala b/src/library/scala/Short.scala index abbb939c4c..df3e680575 100644 --- a/src/library/scala/Short.scala +++ b/src/library/scala/Short.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -// generated on Sun Jan 23 21:13:38 PST 2011 +// DO NOT EDIT, CHANGES WILL BE LOST. package scala diff --git a/src/library/scala/Unit.scala b/src/library/scala/Unit.scala index 7ef282a9ad..9e2d4dc616 100755 --- a/src/library/scala/Unit.scala +++ b/src/library/scala/Unit.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -// generated on Sun Jan 23 21:13:38 PST 2011 +// DO NOT EDIT, CHANGES WILL BE LOST. package scala diff --git a/src/scalacheck/org/scalacheck/Arbitrary.scala b/src/scalacheck/org/scalacheck/Arbitrary.scala index 388c3dccff..14d2b9b924 100644 --- a/src/scalacheck/org/scalacheck/Arbitrary.scala +++ b/src/scalacheck/org/scalacheck/Arbitrary.scala @@ -98,7 +98,7 @@ object Arbitrary { /** Arbitrary instance of Float */ implicit lazy val arbFloat: Arbitrary[Float] = Arbitrary( Gen.chooseNum( - Float.MinNegativeValue, Float.MaxValue + Float.MinValue, Float.MaxValue // I find that including these by default is a little TOO testy. // Float.Epsilon, Float.NaN, Float.PositiveInfinity, Float.NegativeInfinity ) @@ -107,7 +107,7 @@ object Arbitrary { /** Arbitrary instance of Double */ implicit lazy val arbDouble: Arbitrary[Double] = Arbitrary( Gen.chooseNum( - Double.MinNegativeValue / 2, Double.MaxValue / 2 + Double.MinValue / 2, Double.MaxValue / 2 // As above. Perhaps behind some option? // Double.Epsilon, Double.NaN, Double.PositiveInfinity, Double.NegativeInfinity ) diff --git a/test/files/neg/t3115.check b/test/files/neg/t3115.check index b9c0ed9829..3da8c8d1c6 100644 --- a/test/files/neg/t3115.check +++ b/test/files/neg/t3115.check @@ -1,11 +1,11 @@ t3115.scala:6: error: object Math in object sc is deprecated: println(sc.Math) ^ -t3115.scala:7: error: object Math in package scala is deprecated: use scala.math package object instead. +t3115.scala:7: error: object Math in package scala is deprecated: use the scala.math package object instead. (Example package object usage: scala.math.Pi ) println(scala.Math) ^ -t3115.scala:8: error: object Math in package scala is deprecated: use scala.math package object instead. +t3115.scala:8: error: object Math in package scala is deprecated: use the scala.math package object instead. (Example package object usage: scala.math.Pi ) scala.Math.Pi ^ diff --git a/tools/codegen b/tools/codegen index eee5a3884e..734235aef8 100755 --- a/tools/codegen +++ b/tools/codegen @@ -3,5 +3,6 @@ THISDIR=`dirname $0` SCALALIB=$THISDIR/../src/library/scala +BINDIR=$THISDIR/../build/pack/bin -scala scala.tools.cmd.gen.Codegen "$@" +$BINDIR/scala scala.tools.cmd.gen.Codegen "$@" diff --git a/tools/codegen-anyvals b/tools/codegen-anyvals new file mode 100755 index 0000000000..27d1c40134 --- /dev/null +++ b/tools/codegen-anyvals @@ -0,0 +1,5 @@ +#!/bin/bash +# + +THISDIR=`dirname $0` +$THISDIR/codegen --anyvals --out $THISDIR/../src/library/scala |