Skip to content

Commit

Permalink
Merge branch 'develop' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
ice-phoenix committed Jul 13, 2022
2 parents 9ed2966 + 0fa0c86 commit 7065f67
Show file tree
Hide file tree
Showing 3,704 changed files with 397,419 additions and 14,772 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

grammar/testData/psi/**/*.*
!grammar/testData/psi/**/*.antlrtree.txt
!grammar/testData/psi/**/*.diff

grammar/testData/diagnostics/**/*.*
!grammar/testData/diagnostics/**/*.antlrtree.txt
!grammar/testData/diagnostics/**/*.diff

grammar/src/main/java/**/*

Expand All @@ -15,4 +17,6 @@ build
!docs/scripts/build
!scripts/build

kotlin-js-store

*.pws
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import at.phatbl.shellexec.ShellExec

plugins {
kotlin("jvm") version "1.4.31" apply false
kotlin("jvm") version "1.7.0" apply false
id("at.phatbl.shellexec") version "1.5.2"
}

Expand Down
28 changes: 28 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM pandoc/latex:2.14.2-ubuntu
MAINTAINER Marat Akhin <[email protected]>

WORKDIR /source

# install Java 11
RUN apt-get update
RUN apt-get install -y software-properties-common
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9
RUN apt-add-repository 'deb http://repos.azulsystems.com/ubuntu stable main'
RUN apt-get update
RUN apt-get install -y zulu-11

# install packages for the Kotlin spec
RUN apt-get install -y git
RUN apt-get install -y gpp
RUN apt-get install -y librsvg2-bin
RUN apt-get install -y npm
RUN apt-get install -y curl
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash -
RUN apt-get install -y nodejs

# install more TeX Live packages
RUN tlmgr install --no-persistent-downloads enumitem
RUN tlmgr install --no-persistent-downloads cancel
RUN tlmgr install --no-persistent-downloads todonotes
RUN tlmgr install --no-persistent-downloads titlesec
RUN tlmgr install --no-persistent-downloads newunicodechar
26 changes: 12 additions & 14 deletions docs/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import at.phatbl.shellexec.ShellExec
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.nio.file.Paths
import java.net.URI

plugins {
Expand Down Expand Up @@ -56,13 +54,13 @@ dependencies {
implementation("ru.spbstu:g4-to-ebnf:0.0.0.4")
implementation("ru.spbstu:kotlin-pandoc:0.0.15")
implementation("ru.spbstu:simple-diagrammer:0.0.0.7")
implementation("com.github.ajalt:clikt:1.7.0")
implementation("com.zaxxer:nuprocess:2.0.1")
implementation("org.antlr:antlr4:4.+")
implementation("com.github.ajalt:clikt:2.8.0")
implementation("com.zaxxer:nuprocess:2.0.3")
implementation("org.antlr:antlr4:4.8")
}

tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions.jvmTarget = "11"
}

tasks.create<Jar>("filtersJar") {
Expand All @@ -86,7 +84,7 @@ tasks.create<JavaExec>("convertGrammar") {
outputs.file(outputFile)

classpath = sourceSets["main"].runtimeClasspath
main = "org.jetbrains.kotlin.spec.ConvertGrammarKt"
mainClass.set("org.jetbrains.kotlin.spec.ConvertGrammarKt")
args = listOf("-d", grammarsDir, "-l", lexerGrammar, "-p", parserGrammar, "-o", outputFile)
}

Expand All @@ -102,15 +100,15 @@ tasks.create("prepareShell") {

doFirst {
val res = with(StringBuilder()) {
appendln("PROJECT_DIR=$projectDir")
if (disableTODOS) appendln("TODO_OPTION=--disable-todos")
else appendln("TODO_OPTION=--enable-todos")
appendLine("PROJECT_DIR=$projectDir")
if (disableTODOS) appendLine("TODO_OPTION=--disable-todos")
else appendLine("TODO_OPTION=--enable-todos")

if (enableStaticMath) {
appendln("STATIC_MATH_OPTION=--enable-static-math")
appendln("KATEX_BIN_OPTION=\"--katex=${rootProject.buildDir}/js/node_modules/.bin/katex\"")
appendLine("STATIC_MATH_OPTION=--enable-static-math")
appendLine("KATEX_BIN_OPTION=\"--katex=${rootProject.buildDir}/js/node_modules/.bin/katex\"")
}
else appendln("STATIC_MATH_OPTION=--disable-static-math")
else appendLine("STATIC_MATH_OPTION=--disable-static-math")
}

File("$buildDir/prepare.sh").writeText("$res")
Expand Down Expand Up @@ -143,7 +141,7 @@ tasks.create<JavaExec>("execute") {

classpath = sourceSets["main"].runtimeClasspath

main = project.findProperty("mainClass") as? String ?: ""
mainClass.set(project.findProperty("mainClass") as? String ?: "")
args = (project.findProperty("args") as? String)?.split(" ") ?: emptyList()
val wd = project.findProperty("workDir") as? String
workingDir = wd?.let { File(it) } ?: File(".")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ private object CompoundFilter : CliktCommand() {
val format: Format by argument("Pandoc output format").convert { Format(it) }
val split: Boolean by option().flag("--no-split")
val disableTODOS: Boolean by option().flag("--enable-todos")
val imageDirectory: File? by option().file(fileOkay = false)
val imageDirectory: File? by option().file(canBeFile = false)
val embed: Boolean by option().flag()
val defaultFormat: String? by option()

val disableStaticMath by option().flag("--enable-static-math")
val katex by option()

val outputDirectory: File by option().file(fileOkay = false).defaultLazy { File(".") }
val outputDirectory: File by option().file(canBeFile = false).defaultLazy { File(".") }
val generateTOC: Boolean by option().flag("--no-toc")

override fun run() {
Expand Down
2 changes: 1 addition & 1 deletion docs/src/md/commands.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<#mode quote>

\newcommand{\currentKotlinMajorVersion}{\textrm{1.6}}
\newcommand{\currentKotlinMajorVersion}{\textrm{1.7}}

\newcommand{\opMathTT}[2]{%
\expandafter\newcommand{#1}{\operatorname{\texttt{#2}}}%
Expand Down
2 changes: 1 addition & 1 deletion docs/src/md/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Kotlin language specification
author:
- Marat Akhin
- Mikhail Belyaev
subtitle: Version 1.6-rfc+0.1
subtitle: Version 1.7-rfc+0.1
---

<#include "commands.md">
Expand Down
2 changes: 0 additions & 2 deletions docs/src/md/kotlin.core/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,6 @@ It is implementation-defined how this annotation is processed.

> Note: before Kotlin 1.4.0, there were two other built-in annotations: `@Experimental` (now replaced by `@RequiresOptIn`) and `@UseExperimental` (now replaced by `@OptIn`) serving the same purpose which are now deprecated.
TODO(Experimental status is still experimental itself)

#### `kotlin.Deprecated` / `kotlin.ReplaceWith`

`kotlin.Deprecated` is an annotation class with the following fields:
Expand Down
10 changes: 5 additions & 5 deletions docs/src/md/kotlin.core/cdfa.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,11 +435,11 @@ x?.y
+-------------+------------+ +-------------+------------+
| |
v v
+-------+-------+ +-------+-------+
| | | |
| $3 = null | | $3 = $1.y |
| | | |
+-------+-------+ +-------+-------+
+-------+-------+ +-------+-------+
| | | |
| $3 = null | | $3 = $1.y |
| | | |
+-------+-------+ +-------+-------+
| |
| +-----------------------+
v v
Expand Down
69 changes: 65 additions & 4 deletions docs/src/md/kotlin.core/declarations.md
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ Interfaces differ from classes in that they cannot be directly instantiated in t
In other aspects they are similar to classes, therefore we shall specify their declarations by specifying their differences from class declarations.
* An interface can be declared only in a declaration scope;
* Additionally, an interface cannot be declared in an [object literal];
* Additionally, an interface cannot be declared in an [object literal][Object literals];
* An interface cannot have a class as its supertype;
* An interface cannot have a constructor;
* Interface properties cannot have initializers or backing fields;
Expand Down Expand Up @@ -779,7 +779,7 @@ No other values of this type may be declared, making object a single existing va
Similarly to interfaces, we shall specify object declarations by highlighting their differences from class declarations.
* An object can only be declared in a declaration scope;
* Additionally, an object cannot be declared in an [object literal];
* Additionally, an object cannot be declared in an [object literal][Object literals];
* An object type cannot be used as a supertype for other types;
* An object cannot have an explicit primary or secondary constructor;
* An object cannot have a companion object;
Expand Down Expand Up @@ -820,9 +820,9 @@ A primary $pctor$ or secondary constructor $ctor$ has a corresponding superclass
When a classifier type is initialized using a particular secondary constructor $ctor$ delegated to primary constructor $pctor$ which, in turn, is delegated to the corresponding superclass constructor $sctor$, the following happens, in this *initialization order*:
- $pctor$ is invoked using the specified parameters, initializing all the properties declared by its property parameters *in the order of appearance in the constructor declaration*;
- The superclass object is initialized as if created by invoking $sctor$ with the specified parameters;
- Interface delegation expressions are invoked and the result of each is stored in the object to allow for interface delegation, *in the order of appearance of delegation declarations in the supertype specifier list*;
- $pctor$ is invoked using the specified parameters, initializing all the properties declared by its property parameters *in the order of appearance in the constructor declaration*;
- Each property initialization code as well as the initialization blocks in the class body are invoked *in the order of appearance in the class body*;
- $ctor$ body is invoked using the specified parameters.
Expand All @@ -846,7 +846,12 @@ It stays unspecified even after the "proper" initialization is performed.
> }
> }
>
> class Init(val a: Number /* (1) */) : Base(0xC0FFEE) /* (2) */ {
> interface I
>
> class Init(val a: Number) : Base(0xC0FFEE) /* (2) */,
> I by object : I {
> init { println("2.5") }
> } /* (2.5) */ {
>
> init {
> println("3: $this") /* (3) */
Expand Down Expand Up @@ -1755,6 +1760,62 @@ Reified type parameters can only be substituted by other [runtime-available type
> }
> ```
#### Underscore type arguments
In case one needs to explicitly specify some type parameters via [type arguments][Parameterized classifier types], but wants to use [type inference] for the rest, they can use an *underscore type argument*.
An underscore type argument does not add any type information to the [constraint system][Kotlin type constraints] *besides the presence of a type parameter*, i.e., parameterized declaration with different number of type parameters could be distinguished by different number of underscore type arguments.
If the type inference is successfull, each underscore type argument is considered to be equal to the inferred type for their respective type parameter.
If the type inference is not successfull, it is a compile-time error.
> Example:
> ```kotlin
> fun <T> mk(): T = TODO()
>
> interface MyRunnable<T> {
> fun execute(): T
> }
>
> class StringRunnable : MyRunnable<String> {
> override fun execute(): String = "test"
> }
>
> class IntRunnable : MyRunnable<Int> {
> override fun execute(): Int = 42
> }
>
> inline fun <reified S : MyRunnable<T>, T> run(): T = mk<S>().execute()
>
> fun main() {
> val s = run<StringRunnable, _ /* inferred to String */>()
> assert(s == "test")
>
> val i = run<IntRunnable, _ /* inferred to Int */>()
> assert(i == 42)
> }
> ```
> Example:
> ```kotlin
> fun <T> foo(t: T): T = TODO() // (1)
> fun <T, R : List<T>> foo(t: T, d: Double = 42.0): T = TODO() // (2)
>
> fun bar() {
> val a: Boolean = foo(true)
> // resolves to (1)
> // per overload resolution rules
>
> val b: Int = foo<_ /* U1 */>(42)
> // resolves to (1)
> // with U1 inferred to Int
>
> val c: Double = foo<_ /* U1 */, _ /* U2 */>(42.0)
> // resolves to (2)
> // with U1 inferred to Double and U2 inferred to List<Double>
> }
> ```
### Declaration visibility
Each declaration has a visibility property relative to the scope it is declared in.
Expand Down
16 changes: 12 additions & 4 deletions docs/src/md/kotlin.core/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,15 @@ For further details, please refer to the corresponding section.
The keyword `null` denotes the **null reference**, which represents an absence of a value and is a valid value only for [nullable types][Nullable types].
Null reference has type [`kotlin.Nothing?`][`kotlin.Nothing`] and is, by definition, the only value of this type.

### Constant expressions

We use the term "constant expression" to refer to any expression constructed of the following:

* [constant literals][Constant literals]
* [access expressions][Call and property access expressions] to [enum entries][Enum class declaration]
* [string interpolation][String interpolation expressions] over constant expressions
* an implementation-defined set of functions that can always be evaluated at compile-time

### String interpolation expressions

:::{.paste target=grammar-rule-stringLiteral}
Expand Down Expand Up @@ -434,11 +443,10 @@ A when expression is called **_exhaustive_** if at least one of the following is
- It has an `else` entry;
- It has a bound value and at least one of the following is true:
- The bound expression is of type `kotlin.Boolean` and the conditions contain both:
- A constant expression evaluating to `true`;
- A [constant expression][Constant expressions] evaluating to `true`;
- A constant expression evaluating to `false`;
> Important: here the term "constant expression" refers to any expression constructed of [constant literals][Constant literals], [string interpolation][String interpolation expressions] over constant expressions and an implementation-defined set of functions that may always be evaluated at compile-time
- The bound expression is of a [`sealed`][Sealed classes and interfaces] class or interface `S` and all of its [*direct non-sealed subtypes*][Sealed classes and interfaces] $T_1, \ldots, T_n$ are covered in this expression.
A subtype $T_i$ is considered covered if when expression contains one of the following:
* a type test condition $\is S_j$, where $S_j <: S, T_i <: S_j$;
Expand Down Expand Up @@ -535,7 +543,7 @@ A value created by any constructor call is never equal by reference to a null re
There is an exception to these rules: values of [value classes][Value class declaration] are not guaranteed to be reference equal even if they are created by the same constructor invocation as said constructor invocation is explicitly allowed to be inlined by the compiler.
It is thus highly discouraged to compare inline classes by reference.
For special values created without explicit constructor calls, notably, constant literals and constant expressions composed of those literals, and for values of inline classes, the following holds:
For special values created without explicit constructor calls, notably, [constant literals][Constant literals] and [constant expressions][Constant expressions] composed of those literals, and for values of inline classes, the following holds:
- If these values are [non-equal by value][Value equality expressions], they are also non-equal by reference;
- Any instance of the null reference `null` is equal by reference to any other
Expand Down
60 changes: 50 additions & 10 deletions docs/src/md/kotlin.core/type-inference.md
Original file line number Diff line number Diff line change
Expand Up @@ -549,20 +549,60 @@ If $T$ is an intersection type, the same process is performed for every member o
If $T$ is a nullable type $U?$, the steps given above are performed for its non-nullable counterpart type $U$.
## Builder-style type inference
### Builder-style type inference
Some functions or parameters of functions in the standard library are annotated with the special [`@BuilderInference`][Built-in annotations] annotation, making calls to these functions eligible for the special kind of type inference: **builder-style type inference**.
In order to allow builder-style inference for a function parameter, this parameter must hold the following properties:
> Note: before Kotlin 1.7, builder-style type inference required using the [`@BuilderInference`][Built-in annotations] annotation on lambda parameters.
- It must be of an extension-function type;
- It must be marked with the `@BuilderInference` annotation.
When working with DSLs that have generic builder functions, one may want to infer the generic builder type parameters using the information from the builder's lambda body.
Kotlin supports special kind of type inference called **builder-style type inference** to allow this in some cases.
In essence, the builder-style inference allows a receiver of an extension lambda parameter to be inferred from its usage in addition to standard type information sources.
For a call to an eligible function with a lambda parameter $L$ the inference is performed [as described above][Statements with lambda literals], but the type parameters of the receiver parameter of the lambda expression are *postponed* till the body of the lambda expression is proceeded.
After the inference of statements inside the lambda body, these parameters are inferred using an additional type inference step:
In order to allow builder-style inference for a generic builder function and its type parameter `P`, it should satisfy the following requirements:
- For each call to a member function of the receiver or an extension function of the receiver marked with the `@BuilderInference` annotation, the type constraints are collected and gathered into a single constraint system;
- This system is solved in order to infer the actual type arguments of the receiver.
- It has a lambda parameter of [function type with receiver][Function types], with receiver type `T`
- The receiver type `T` uses type parameter `P` in its type arguments
- The receiver type `T` can be used as receiver for callables which can provide information about `P` via their use
> Note: using the type parameter `P` *directly* as the receiver type `T` (e.g., `fun <Q /* P */> myBuilder(builder: Q /* T */.() -> Unit)`) is not yet supported.
In essence, the builder-style inference allows the type of the lambda parameter receiver to be inferred from its usage in the lambda body.
This is performed only if the standard type inference cannot infer the required types, meaning one could provide additional type information to help with the inference, e.g., via explicit type arguments, and avoid the need for builder-style inference.
If the builder-style inference is needed, for a call to an eligible function with a lambda parameter, the inference is performed [as described above][Statements with lambda literals], but the type arguments of the lambda parameter receiver are viewed as *postponed* type variables till the body of the lambda expression is proceeded.
> Note: during the builder-style inference process, a postponed type variable is not required to be inferred to a concrete type.
After the inference of statements inside the lambda is complete, these postponed type variables are inferred using an additional type inference step, which takes the resulting type constraint system and tries to find the instantiation of the postponed type variables to concrete types.
If the system cannot be solved, it is a compile-time error.
> Note: notable examples of builder-style inference-enabled functions are `kotlin.sequence` and `kotlin.iterator`.
> See standard library documentation for details.
> Example:
> ```kotlin
> fun <K, V> buildMap(action: MutableMap<K, V>.() -> Unit): Map<K, V> { ... }
>
> interface Map<K, out V> : Map<K, V> { ... }
> interface MutableMap<K, V> : Map<K, V> {
> fun put(key: K, value: V): V?
> fun putAll(from: Map<out K, V>): Unit
> }
>
> fun addEntryToMap(baseMap: Map<String, Number>,
> additionalEntry: Pair<String, Int>?) {
> val myMap = buildMap/* <?, ?> */ { // cannot infer type arguments
> // needs builder-style inference
> putAll(baseMap)
> // provides information about String <: K, Number <: V
>
> if (additionalEntry != null) {
> put(additionalEntry.first, additionalEntry.second)
> // provides information about String <: K, Int <: V
> }
> }
> // solves to String =:= K, Number =:= V
> // ...
> }
> ```
TODO(More detailed description of builder-style inference)
Loading

0 comments on commit 7065f67

Please sign in to comment.