diff --git a/docs/_docs/reference/enums/adts.md b/docs/_docs/reference/enums/adts.md index 5219e062a633..a1b356e7a813 100644 --- a/docs/_docs/reference/enums/adts.md +++ b/docs/_docs/reference/enums/adts.md @@ -23,7 +23,7 @@ is treated as a normal enum value. The `extends` clauses that were omitted in the example above can also be given explicitly: -```scala +```scala sc-name:option enum Option[+T]: case Some(x: T) extends Option[T] case None extends Option[Nothing] @@ -39,21 +39,21 @@ As for normal enum values, the cases of an `enum` are all defined in the `enum`s companion object. So it's `Option.Some` and `Option.None` unless the definitions are "pulled out" with an import: -```scala -scala> Option.Some("hello") -val res1: t2.Option[String] = Some(hello) +```scala sc-compile-with:option +val option = Option.Some("hello") +// some: Option[String] = Some(hello) -scala> Option.None -val res2: t2.Option[Nothing] = None +val none = Option.None +// none: Option[Nothing] = None ``` Note that the type of the expressions above is always `Option`. Generally, the type of a enum case constructor application will be widened to the underlying enum type, unless a more specific type is expected. This is a subtle difference with respect to normal case classes. The classes making up the cases do exist, and can be unveiled, either by constructing them directly with a `new`, or by explicitly providing an expected type. -```scala -scala> new Option.Some(2) -val res3: Option.Some[Int] = Some(2) -scala> val x: Option.Some[Int] = Option.Some(3) -val res4: Option.Some[Int] = Some(3) +```scala sc-compile-with:option +val some0 = new Option.Some(2) +// some: Option.Some[Int] = Some(2) +val some1: Option.Some[Int] = Option.Some(3) +// opt: Option.Some[Int] = Some(3) ``` As all other enums, ADTs can define methods. For instance, here is `Option` again, with an @@ -100,7 +100,7 @@ below: The following `View` enum has a contravariant type parameter `T` and a single case `Refl`, representing a function mapping a type `T` to itself: -```scala +```scala sc:nocompile enum View[-T]: case Refl(f: T => T) ``` @@ -108,7 +108,7 @@ enum View[-T]: The definition of `Refl` is incorrect, as it uses contravariant type `T` in the covariant result position of a function type, leading to the following error: -```scala +```scala sc:nocompile -- Error: View.scala:2:12 -------- 2 | case Refl(f: T => T) | ^^^^^^^^^ @@ -118,7 +118,7 @@ function type, leading to the following error: Because `Refl` does not declare explicit parameters, it looks to the compiler like the following: -```scala +```scala sc:nocompile enum View[-T]: case Refl[/*synthetic*/-T1](f: T1 => T1) extends View[T1] ``` diff --git a/docs/_docs/reference/enums/desugarEnums.md b/docs/_docs/reference/enums/desugarEnums.md index 477653d670bb..fad6d5acf021 100644 --- a/docs/_docs/reference/enums/desugarEnums.md +++ b/docs/_docs/reference/enums/desugarEnums.md @@ -32,14 +32,14 @@ are missing them. Rules (7) to (9) define how such cases with `extends` clauses map into `case class`es or `val`s. 1. An `enum` definition - ```scala + ```scala sc:nocompile enum E ... { } ``` expands to a `sealed abstract` class that extends the `scala.reflect.Enum` trait and an associated companion object that contains the defined cases, expanded according to rules (2 - 8). The enum class starts with a compiler-generated import that imports the names `` of all cases so that they can be used without prefix in the class. - ```scala + ```scala sc:nocompile sealed abstract class E ... extends with scala.reflect.Enum { import E.{ } @@ -48,37 +48,37 @@ map into `case class`es or `val`s. ``` 2. A simple case consisting of a comma-separated list of enum names - ```scala + ```scala sc:nocompile case C_1, ..., C_n ``` expands to - ```scala + ```scala sc:nocompile case C_1; ...; case C_n ``` Any modifiers or annotations on the original case extend to all expanded cases. 3. A simple case - ```scala + ```scala sc:nocompile case C ``` of an enum `E` that does not take type parameters expands to - ```scala + ```scala sc:nocompile val C = $new(n, "C") ``` Here, `$new` is a private method that creates an instance of `E` (see below). 4. If `E` is an enum with type parameters - ```scala + ```scala sc:nocompile V1 T1 >: L1 <: U1 , ... , Vn Tn >: Ln <: Un (n > 0) ``` where each of the variances `Vi` is either `'+'` or `'-'`, then a simple case - ```scala + ```scala sc:nocompile case C ``` expands to - ```scala + ```scala sc:nocompile case C extends E[B1, ..., Bn] ``` where `Bi` is `Li` if `Vi = '+'` and `Ui` if `Vi = '-'`. This result is then further @@ -86,42 +86,42 @@ map into `case class`es or `val`s. parameters are not permitted (however value cases with explicit `extends` clause are) 5. A class case without an extends clause - ```scala + ```scala sc:nocompile case C ``` of an enum `E` that does not take type parameters expands to - ```scala + ```scala sc:nocompile case C extends E ``` This result is then further rewritten with rule (9). 6. If `E` is an enum with type parameters `Ts`, a class case with neither type parameters nor an extends clause - ```scala + ```scala sc:nocompile case C ``` expands to - ```scala + ```scala sc:nocompile case C[Ts] extends E[Ts] ``` This result is then further rewritten with rule (9). For class cases that have type parameters themselves, an extends clause needs to be given explicitly. 7. If `E` is an enum with type parameters `Ts`, a class case without type parameters but with an extends clause - ```scala + ```scala sc:nocompile case C extends ``` expands to - ```scala + ```scala sc:nocompile case C[Ts] extends ``` provided at least one of the parameters `Ts` is mentioned in a parameter type in `` or in a type argument in ``. 8. A value case - ```scala + ```scala sc:nocompile case C extends ``` expands to a value definition in `E`'s companion object: - ```scala + ```scala sc:nocompile val C = new { ; def ordinal = n } ``` where `n` is the ordinal number of the case in the companion object, @@ -132,15 +132,15 @@ map into `case class`es or `val`s. in a type argument of ``. 9. A class case - ```scala + ```scala sc:nocompile case C extends ``` expands analogous to a final case class in `E`'s companion object: - ```scala + ```scala sc:nocompile final case class C extends ``` The enum case defines an `ordinal` method of the form - ```scala + ```scala sc:nocompile def ordinal = n ``` where `n` is the ordinal number of the case in the companion object, @@ -151,7 +151,7 @@ map into `case class`es or `val`s. a type parameter of the case, i.e. the parameter name is defined in ``. The compiler-generated `apply` and `copy` methods of an enum case - ```scala + ```scala sc:nocompile case C(ps) extends P1, ..., Pn ``` are treated specially. A call `C(ts)` of the apply method is ascribed the underlying type @@ -175,7 +175,7 @@ If `E` contains at least one simple case, its companion object will define in ad ordinal number and name. This method can be thought as being defined as follows. - ```scala + ```scala sc:nocompile private def $new(_$ordinal: Int, $name: String) = new E with runtime.EnumValue: def ordinal = _$ordinal diff --git a/docs/_docs/reference/enums/enums.md b/docs/_docs/reference/enums/enums.md index 65051bdfb39f..e487d5cb8c58 100644 --- a/docs/_docs/reference/enums/enums.md +++ b/docs/_docs/reference/enums/enums.md @@ -19,7 +19,7 @@ companion object. Enums can be parameterized. -```scala +```scala sc-name:color enum Color(val rgb: Int): case Red extends Color(0xFF0000) case Green extends Color(0x00FF00) @@ -34,11 +34,10 @@ explicit extends clause. The values of an enum correspond to unique integers. The integer associated with an enum value is returned by its `ordinal` method: -```scala -scala> val red = Color.Red -val red: Color = Red -scala> red.ordinal -val res0: Int = 0 +```scala sc-compile-with:color +val red = Color.Red +val ord = red.ordinal +assert(ord == 0) ``` The companion object of an enum also defines three utility methods. @@ -47,20 +46,20 @@ by its name. The `values` method returns all enum values defined in an enumeration in an `Array`. The `fromOrdinal` method obtains an enum value from its ordinal (`Int`) value. -```scala -scala> Color.valueOf("Blue") -val res0: Color = Blue -scala> Color.values -val res1: Array[Color] = Array(Red, Green, Blue) -scala> Color.fromOrdinal(0) -val res2: Color = Red +```scala sc-compile-with:color +val blue = Color.valueOf("Blue") +// blue: Color = Blue +val values = Color.values +// values: Array[Color] = Array(Red, Green, Blue) +val red = Color.fromOrdinal(0) +// red: Color = Red ``` ## User-defined members of enums It is possible to add your own definitions to an enum. Example: -```scala +```scala sc-name:planet enum Planet(mass: Double, radius: Double): private final val G = 6.67300E-11 def surfaceGravity = G * mass / (radius * radius) @@ -80,7 +79,7 @@ end Planet ## User-defined companion object of enums It is also possible to define an explicit companion object for an enum: -```scala +```scala sc-compile-with:planet object Planet: def main(args: Array[String]) = val earthWeight = args(0).toDouble @@ -100,7 +99,7 @@ enum class. Similarly, enum case declarations may not directly reference members of the enum's companion object, even if they are imported (directly, or by renaming). For example: -```scala +```scala sc:nocompile import Planet.* enum Planet(mass: Double, radius: Double): private final val (mercuryMass, mercuryRadius) = (3.303e+23, 2.4397e6) @@ -146,7 +145,7 @@ We now want to deprecate the `Pluto` case. First we add the `scala.deprecated` a Outside the lexical scopes of `enum Planet` or `object Planet`, references to `Planet.Pluto` will produce a deprecation warning, but within those scopes we can still reference it to implement introspection over the deprecated cases: -```scala +```scala sc:nocompile trait Deprecations[T <: reflect.Enum] { extension (t: T) def isDeprecatedCase: Boolean } @@ -166,7 +165,7 @@ We could imagine that a library may use [type class derivation](../contextual/de If you want to use the Scala-defined enums as [Java enums](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html), you can do so by extending the class `java.lang.Enum`, which is imported by default, as follows: -```scala +```scala sc-name:jcolor enum Color extends Enum[Color] { case Red, Green, Blue } ``` @@ -175,9 +174,9 @@ There is no need to provide constructor arguments (as defined in the Java API do After defining `Color` like that, you can use it like you would a Java enum: -```scala -scala> Color.Red.compareTo(Color.Green) -val res15: Int = -1 +```scala sc-compile-with:jcolor +val cmp = Color.Red.compareTo(Color.Green) +assert(cmp == -1) ``` For a more in-depth example of using Scala 3 enums from Java, see [this test](https://github.com/lampepfl/dotty/tree/main/tests/run/enum-java). In the test, the enums are defined in the `MainScala.scala` file and used from a Java source, `Test.java`. @@ -187,7 +186,7 @@ For a more in-depth example of using Scala 3 enums from Java, see [this test](ht Enums are represented as `sealed` classes that extend the `scala.reflect.Enum` trait. This trait defines a single public method, `ordinal`: -```scala +```scala sc:nocompile package scala.reflect /** A base trait of all Scala enum definitions */ @@ -200,7 +199,7 @@ transparent trait Enum extends Any, Product, Serializable: Enum values with `extends` clauses get expanded to anonymous class instances. For instance, the `Venus` value above would be defined like this: -```scala +```scala sc:nocompile val Venus: Planet = new Planet(4.869E24, 6051800.0): def ordinal: Int = 1 override def productPrefix: String = "Venus" @@ -212,7 +211,7 @@ that can be instantiated using a private method that takes a tag and a name as a For instance, the first definition of value `Color.Red` above would expand to: -```scala +```scala sc:nocompile val Red: Color = $new(0, "Red") ``` diff --git a/project/Build.scala b/project/Build.scala index f52bdfd5af41..b2c4fc5ef0b6 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -2323,6 +2323,13 @@ object ScaladocConfigs { .withTargets(tastyRoots) } + def snippetCompilerTargets(dottyLibSrc:String) = List( + s"$dottyLibSrc/scala=compile", + s"$dottyLibSrc/scala/quoted=compile", + s"$dottyLibSrc/scala/compiletime=compile", + s"$dottyLibSrc/scala/util=compile", + s"$dottyLibSrc/scala/util/control=compile", + ) lazy val Scala3 = Def.task { val dottyJars: Seq[java.io.File] = Seq( (`scala2-library-bootstrapped`/Compile/products).value, @@ -2358,11 +2365,9 @@ object ScaladocConfigs { ))) .add(VersionsDictionaryUrl("https://scala-lang.org/api/versions.json")) .add(DocumentSyntheticTypes(true)) - .add(SnippetCompiler(List( - s"$dottyLibRoot/src/scala=compile", - s"$dottyLibRoot/src/scala/compiletime=compile", - s"$dottyLibRoot/src/scala/util=compile", - s"$dottyLibRoot/src/scala/util/control=compile" + .add(SnippetCompiler( + snippetCompilerTargets(s"$dottyLibRoot/src") ++ List( + "docs/_docs/reference/enums=compile" ))) .add(SiteRoot("docs")) .add(ApiSubdirectory(true)) @@ -2375,14 +2380,7 @@ object ScaladocConfigs { Scala3.value .add(defaultSourceLinks(version + "-bin-SNAPSHOT-nonbootstrapped", version).value) .add(ProjectVersion(version)) - .add(SnippetCompiler( - List( - s"$dottyLibrarySrc/scala/quoted=compile", - s"$dottyLibrarySrc/scala/compiletime=compile", - s"$dottyLibrarySrc/scala/util=compile", - s"$dottyLibrarySrc/scala/util/control=compile" - ) - )) + .add(SnippetCompiler(snippetCompilerTargets(dottyLibrarySrc))) .add(CommentSyntax(List( s"$dottyLibrarySrc=markdown", s"$scalaLibrarySrc=wiki",