Skip to content

Scaladoc: Fix snippets in documentation #12987

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/docs/reference/other-new-features/control-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ Scala 3 has a new "quiet" syntax for control expressions that does not rely on
enclosing the condition in parentheses, and also allows to drop parentheses or braces
around the generators of a `for`-expression. Examples:
```scala
//{
import java.io.IOException
type T
var x: Int
var xs: List[Int]
var ys: List[Int]
var body: T
var handle: T
def f(x: Int): Int = ???
//}
if x < 0 then
"negative"
else if x == 0 then
Expand Down
20 changes: 11 additions & 9 deletions docs/docs/reference/other-new-features/creator-applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,26 @@ function application, without needing to write `new`.

Scala 3 generalizes this scheme to all concrete classes. Example:

```scala
class StringBuilder(s: String):
```scala sc-name:Base.scala
class MyStringBuilder(s: String):
def this() = this("")
```

StringBuilder("abc") // old: new StringBuilder("abc")
StringBuilder() // old: new StringBuilder()
```scala sc-compile-with:Base.scala
MyStringBuilder("abc") // old: new MyStringBuilder("abc")
MyStringBuilder() // old: new MyStringBuilder()
```

This works since a companion object with two `apply` methods
is generated together with the class. The object looks like this:

```scala
object StringBuilder:
inline def apply(s: String): StringBuilder = new StringBuilder(s)
inline def apply(): StringBuilder = new StringBuilder()
```scala sc-compile-with:Base.scala
object MyStringBuilder:
inline def apply(s: String): MyStringBuilder = new MyStringBuilder(s)
inline def apply(): MyStringBuilder = new MyStringBuilder()
```

The synthetic object `StringBuilder` and its `apply` methods are called _constructor proxies_.
The synthetic object `MyStringBuilder` and its `apply` methods are called _constructor proxies_.
Constructor proxies are generated even for Java classes and classes coming from Scala 2.
The precise rules are as follows:

Expand Down
69 changes: 47 additions & 22 deletions docs/docs/reference/other-new-features/explicit-nulls.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ val x: String | Null = null // ok
A nullable type could have null value during runtime; hence, it is not safe to select a member without checking its nullity.

```scala
//{
val x: String | Null
//}
x.trim // error: trim is not member of String | Null
```

Expand Down Expand Up @@ -123,7 +126,7 @@ We illustrate the rules with following examples:
- The first two rules are easy: we nullify reference types but not value types.

```java
class C {
abstract class C {
String s;
int x;
}
Expand All @@ -132,7 +135,7 @@ We illustrate the rules with following examples:
==>

```scala
class C:
abstract class C:
val s: String | Null
val x: Int
```
Expand All @@ -145,30 +148,33 @@ We illustrate the rules with following examples:

==>

```scala
class C[T] { def foo(): T | Null }
```scala sc-name:C.scala
class C[T] { def foo(): T | Null = null }
```

Notice this is rule is sometimes too conservative, as witnessed by

```scala
```scala sc:fail sc-compile-with:C.scala
class InScala:
val c: C[Bool] = ??? // C as above
val b: Bool = c.foo() // no longer typechecks, since foo now returns Bool | Null
val c: C[Boolean] = ??? // C as above
val b: Boolean = c.foo() // no longer typechecks, since foo now returns Bool | Null
```

- We can reduce the number of redundant nullable types we need to add. Consider

```java
class Box<T> { T get(); }
class BoxFactory<T> { Box<T> makeBox(); }
abstract class Box<T> { T get(); }
abstract class BoxFactory<T> { Box<T> makeBox(); }
```

==>

```scala
class Box[T] { def get(): T | Null }
class BoxFactory[T] { def makeBox(): Box[T] | Null }
```scala sc-name:Box.scala
abstract class Box[T] { def get(): T | Null }
```

```scala sc-compile-with:Box.scala
abstract class BoxFactory[T] { def makeBox(): Box[T] | Null }
```

Suppose we have a `BoxFactory[String]`. Notice that calling `makeBox()` on it returns a
Expand All @@ -184,16 +190,16 @@ We illustrate the rules with following examples:
- We will append `Null` to the type arguments if the generic class is defined in Scala.

```java
class BoxFactory<T> {
abstract class BoxFactory<T> {
Box<T> makeBox(); // Box is Scala-defined
List<Box<List<T>>> makeCrazyBoxes(); // List is Java-defined
}
```

==>

```scala
class BoxFactory[T]:
```scala sc-compile-with:Box.scala
abstract class BoxFactory[T]:
def makeBox(): Box[T | Null] | Null
def makeCrazyBoxes(): java.util.List[Box[java.util.List[T] | Null]] | Null
```
Expand Down Expand Up @@ -221,10 +227,13 @@ We illustrate the rules with following examples:
==>

```scala
//{
def getNewName(): String = ???
//}
class Constants:
val NAME: String("name") = "name"
val AGE: Int(0) = 0
val CHAR: Char('a') = 'a'
val NAME: String = "name"
val AGE: Int = 0
val CHAR: Char = 'a'

val NAME_GENERATED: String | Null = getNewName()
```
Expand All @@ -242,8 +251,8 @@ We illustrate the rules with following examples:

==>

```scala
class C:
```scala sc-compile-with:Box.scala
abstract class C:
val name: String
def getNames(prefix: String | Null): java.util.List[String] // we still need to nullify the paramter types
def getBoxedName(): Box[String | Null] // we don't append `Null` to the outmost level, but we still need to nullify inside
Expand All @@ -252,7 +261,7 @@ We illustrate the rules with following examples:
The annotation must be from the list below to be recognized as `NotNull` by the compiler.
Check `Definitions.scala` for an updated list.

```scala
```scala sc:nocompile
// A list of annotations that are commonly used to indicate
// that a field/method argument or return type is not null.
// These annotations are used by the nullification logic in
Expand Down Expand Up @@ -283,11 +292,17 @@ Suppose we have Java method `String f(String x)`, we can override this method in

```scala
def f(x: String | Null): String | Null
```

```scala
def f(x: String): String | Null
```

```scala
def f(x: String | Null): String
```

```scala
def f(x: String): String
```

Expand All @@ -304,7 +319,7 @@ Example:

```scala
val s: String | Null = ???
if s != null then
if s != null then ???
// s: String

// s: String | Null
Expand All @@ -316,9 +331,12 @@ assert(s != null)
A similar inference can be made for the `else` case if the test is `p == null`

```scala
val s: String | Null = ???
if s == null then
???
// s: String | Null
else
???
// s: String
```

Expand All @@ -332,13 +350,16 @@ We also support logical operators (`&&`, `||`, and `!`):
val s: String | Null = ???
val s2: String | Null = ???
if s != null && s2 != null then
???
// s: String
// s2: String

if s == null || s2 == null then
???
// s: String | Null
// s2: String | Null
else
???
// s: String
// s2: String
```
Expand All @@ -351,11 +372,14 @@ We also support type specialization _within_ the condition, taking into account
val s: String | Null = ???

if s != null && s.length > 0 then // s: String in `s.length > 0`
???
// s: String

if s == null || s.length > 0 then // s: String in `s.length > 0`
???
// s: String | Null
else
???
// s: String
```

Expand Down Expand Up @@ -442,6 +466,7 @@ We don't support:
val s: String | Null = ???
val s2: String | Null = ???
if s != null && s == s2 then
???
// s: String inferred
// s2: String not inferred
```
Expand Down
23 changes: 13 additions & 10 deletions docs/docs/reference/other-new-features/export.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ movedTo: https://docs.scala-lang.org/scala3/reference/other-new-features/export.

An export clause defines aliases for selected members of an object. Example:

```scala
```scala sc-name:Model.scala
class BitMap
class InkJet

Expand All @@ -31,22 +31,22 @@ class Copier:

The two `export` clauses define the following _export aliases_ in class `Copier`:

```scala
```scala sc:nocompile
final def scan(): BitMap = scanUnit.scan()
final def print(bits: BitMap): Unit = printUnit.print(bits)
final type PrinterType = printUnit.PrinterType
```

They can be accessed inside `Copier` as well as from outside:

```scala
```scala sc-compile-with:Model.scala
val copier = new Copier
copier.print(copier.scan())
```

An export clause has the same format as an import clause. Its general form is:

```scala
```scala sc:nocompile
export path . { sel_1, ..., sel_n }
```

Expand Down Expand Up @@ -86,9 +86,9 @@ referring to private values in the qualifier path
are marked by the compiler as "stable" and their result types are the singleton types of the aliased definitions. This means that they can be used as parts of stable identifier paths, even though they are technically methods. For instance, the following is OK:
```scala
class C { type T }
object O { val c: C = ... }
object O { val c: C = ??? }
export O.c
def f: c.T = ...
def f: c.T = ???
```


Expand All @@ -98,7 +98,7 @@ def f: c.T = ...
1. If an export clause contains a wildcard or given selector, it is forbidden for its qualifier path to refer to a package. This is because it is not yet known how to safely track wildcard dependencies to a package for the purposes of incremental compilation.

1. Simple renaming exports like
```scala
```scala sc:nocompile
export status as stat
```
are not supported yet. They would run afoul of the restriction that the
Expand Down Expand Up @@ -142,16 +142,19 @@ ImportSelectors ::= NamedSelector [‘,’ ImportSelectors]
Export clauses raise questions about the order of elaboration during type checking.
Consider the following example:

```scala
class B { val c: Int }
```scala sc-name:Base.scala
class B { val c: Int = ??? }
object a { val b = new B }
```

```scala sc-compile-with:Base.scala
export a.*
export b.*
```

Is the `export b.*` clause legal? If yes, what does it export? Is it equivalent to `export a.b.*`? What about if we swap the last two clauses?

```
```scala sc:fail sc-compile-with:Base.scala
export b.*
export a.*
```
Expand Down
Loading