diff --git a/docs/src/md/kotlin.core/declarations.md b/docs/src/md/kotlin.core/declarations.md index 356c07c13..ba0da84df 100644 --- a/docs/src/md/kotlin.core/declarations.md +++ b/docs/src/md/kotlin.core/declarations.md @@ -1045,7 +1045,7 @@ This parameter is not named and must always be supplied (either explicitly or im Calling such a function is special because the receiver parameter is not supplied as an argument of the call, but as the [_receiver_][Receivers] of the call, be it implicit or explicit. This parameter is available inside the scope of the function as the implicit receiver or `this`-expression, while nested scopes may introduce additional receivers that take precedence over this one. See [the receiver section][Receivers] for details. -This receiver is also available (as usual) in nested scope using labeled `this` syntax using the name of the declared function as the label. +This receiver is also available (as usual) in nested scope using labeled `this` syntax using the name of the declared function or the receiver type classifier name as the label. For more information on how a particular receiver for each call is chosen, please refer to the [overloading section][Overload resolution]. @@ -1068,6 +1068,22 @@ class Bar { } ``` +#### Contextual function declaration + +A _contextual function declaration_ further extends the extension function declaration syntax with a number of additional special function parameters, the _context receiver parameters_, provided in the form of their respectable types using the special `context` soft keyword. +As with extension receivers, these parameters are not named an must always be supplied. +Unlike extension receivers, context receivers may only be provided implicitly at call site. +See [the receiver section][Receivers] for details. +All context receiver parameters are available inside the scope of the function as implicit receivers and cannot be referenced using unlabeled `this`-expression syntax. +They are, however, available using labeled `this` syntax using the name of the receiver type classifier as the label. + +Context receiver types of a particular function must all be different from each other and no pair of these types may be in a [subtyping relation][Subtyping]. +They may, however, contain a type that is also used as the extension receiver of the function or a type in a subtyping relation with it. + +For more information on how a particular receiver for each call is chosen, please refer to the [overloading section][Overload resolution]. + +TODO: Examples + #### Inlining A function may be declared `inline` using a special `inline` modifier. @@ -1486,6 +1502,23 @@ For all other purposes, extension properties are not different from non-extensio > } > ``` +#### Contextual property declaration + +A _contextual property declaration_ further extends the extension property declaration syntax with a number of additional special function parameters, the _context receiver parameters_, very much alike a [contextual function declaration], supplied using the `context` soft keyword. +As with extension receivers, these parameters are not named and must always be supplied. +Unlike extension receivers, these must always be provided implicitly at call site. +See [the receiver section][Receivers] for details. + +A contextual property declaration may be extension or non-extension, but follows the same limitations as extension properties described in the [corresponding section][Extension property declaration]. + +All context receiver parameters can be accessed inside getter and setter scopes of the property as the implicit receiver or `this`. +It may also be accessed inside nested scopes using [labeled `this` syntax][This-expressions] using the type of the context receiver as the label. + +Same as [contextual function declarations][contextual function declaration], context receiver types of a particular propery must all be different from each other and no pair of these types may be in a [subtyping relation][Subtyping]. +They may, however, contain a type that is also used as the extension receiver of the function or a type in a subtyping relation with it. + +TODO: Examples + #### Property initialization All non-abstract properties must be definitely initialized before their first use. diff --git a/docs/src/md/kotlin.core/overload-resolution.md b/docs/src/md/kotlin.core/overload-resolution.md index d06fe8710..1df016a0e 100644 --- a/docs/src/md/kotlin.core/overload-resolution.md +++ b/docs/src/md/kotlin.core/overload-resolution.md @@ -13,9 +13,7 @@ This section describes *overload resolution process* in detail. Unlike other object-oriented languages, Kotlin does not have only regular class methods, but also top-level functions, local functions, extension functions and function-like values, which complicate the overload resolution process quite a bit. Additionally, Kotlin has infix functions, operator and property overloading, which add their own specifics to this process. -### Basics - -#### Receivers +### Receivers Every function or property that is defined as a method or an extension has one or more special parameters called _receiver_ parameters. When calling such a callable using [navigation operators][Navigation operators] (`.` or `?.`) the left hand side value is called an _explicit receiver_ of this particular call. @@ -27,32 +25,44 @@ Implicit receivers are available in a syntactic scope according to the following - In a [classifier declaration][Classifier declaration] scope (including object and companion object declarations), the declared object is available as implicit `this`; - In a [classifier declaration][Classifier declaration] scope (including object and companion object declarations), the static callables of the declared object are available on a phantom static implicit `this`; - If a function or a property is an extension, `this` parameter of the extension is also available inside the extension declaration; -- If a lambda expression has an extension function type, `this` argument of the lambda expression is also available inside the lambda expression declaration. +- If a function or a property is [contextual][Contextual function declaration], its context receiver parameters are available inside the declaration as implicit receivers; +- If a lambda expression has an [extension function type][Function types], `this` argument of the lambda expression is also available inside the lambda expression declaration; +- If a lambda expression has a [function type with context receivers][Function types], implicit receivers of its context receiver types are also available inside the lambda expression declaration. > Important: a phantom static implicit `this` is a special receiver, which is included in the receiver chain for the purposes of handling static functions from [enum classes][Enum class declaration]. > It may also be used on platforms to handle their static-like entities, e.g., static methods on JVM platform. +Receivers from context receiver parameters or context receiver types are called _context-provided_ receivers. + The available receivers are prioritized in the following way: - Receivers provided in the most inner scope have higher priority as ordered w.r.t. [link relation][Linked scopes]; +- Context-provided receivers have **lower** priority than other _non-top-level_ receivers; - The implicit `this` receiver has higher priority than phantom static implicit `this`; - The phantom static implicit `this` receiver has higher priority than the current class companion object receiver; - Current class companion object receiver has higher priority than any of the superclass companion objects; - Superclass companion object receivers are prioritized according to the inheritance order. -> Important: these rules mean implicit receivers are always totally ordered w.r.t. their priority, as no two implicit receivers can have the same priority. +> Important: DSL-specific annotations (marked with [`kotlin.DslMarker`] annotation) change the availability of implicit receivers in the following way: for all types marked with a particular DSL-specific annotation, only the highest priority implicit receiver is available in a given scope. -> Important: DSL-specific annotations (marked with [`kotlin.DslMarker`] annotation) change the availability of implicit receivers in the following way: for all types marked with a particular DSL-specific annotation, only the highest priority implicit receiver is available in a given scope. +As some scope may immediately provide _several_ receivers (e.g., [contextual function][Contextual function declaration] scope with its context receiver parameters), they will all have the same priority w.r.t. implicit receiver ordering. +These same-priority implicit receivers form a _one-only implicit receiver group_, which is considered as a special implicit receiver with the following semantics. +When using a one-only implicit receiver group as an implicit receiver for the purposes of overload resolution, _every implicit receiver_ from the group is considered as if it is the singular implicit receiver, and if two or more implicit receivers from the group can be used, it is an **overload ambiguity** which must be reported as a compile-time error. -The implicit receiver having the highest priority is also called the _default implicit receiver_. +The implicit receiver having the highest priority (if not a one-only implicit receiver group) is also called the _default implicit receiver_. The default implicit receiver is available in a scope as `this`. -Other available receivers may be accessed using [labeled this-expressions][This-expressions]. +Alternatively, one may use [labeled this-expressions][This-expressions] for access to implicit receivers. + +> Note: a one-only implicit receiver group may have the highest priority, for example, inside a top-level [contextual function declaration]. If an implicit receiver is available in a given scope, it may be used to call callables implicitly in that scope without using the navigation operator. For [extension callables][Callables and `invoke` convention], the receiver used as the extension receiver parameter is called *extension receiver*, while the implicit receiver associated with the declaration scope the extension is declared in is called *dispatch receiver*. For a particular callable invocation, any or both receivers may be involved, but, if an extension receiver is involved, the dispatch receiver must be implicit. +For [contextual callables], the receivers used as the context receiver parameters are called *context receivers*. +Context receivers must always be implicit. + > Note: by definition, local extension callables do not have a dispatch receiver, as they are declared in a statement scope. > Note: there may be situations in which *the same implicit receiver* is used as both the dispatch receiver and the extension receiver for a particular callable invocation, for example: @@ -86,7 +96,9 @@ For a particular callable invocation, any or both receivers may be involved, but > } > ``` -#### The forms of call-expression +TODO(Context receiver examples) + +### The forms of call-expression Any function in Kotlin may be called in several different ways: @@ -102,7 +114,7 @@ For each of these cases, a compiler should first pick a number of _overload cand > Important: the overload candidates are picked **before** the most specific function is chosen. -#### Callables and `invoke` convention +### Callables and `invoke` convention A *callable* $X$ for the purpose of this section is one of the following: @@ -139,7 +151,14 @@ An *extension callable* is one of the following: A *local callable* is any callable which is declared in a [statement scope][Scopes and identifiers]. -#### c-level partition +#### Contextual callables + +A _contextual callable_ is any callable with one or more context receiver parameters. + +* For function-like callables, their [declaration][Contextual function declaration] should contain one or more context receiver parameters; +* For property-like callables with member or extension operator `invoke`, the `invoke` operator declaration should contain one or more context receiver parameters. + +### c-level partition When calculating overload candidate sets, member callables produce the following sets, considered separately, ordered by higher priority first: @@ -156,7 +175,7 @@ Extension callables produce the following sets, considered separately, ordered b Let us define this partition of callables to overload candidate sets as *c-level partition* (callable-level partition). As this partition is the most fine-grained of all other steps of partitioning resolution candidates into sets, it is always performed **last**, after all other applicable steps. -### Building the overload candidate set +### Building the overload candidate set (OCS) #### Fully-qualified call @@ -196,9 +215,7 @@ A call of callable `f` with an explicit receiver `e` is correct if at least one If a call is correct, for a callable `f` with an explicit receiver `e` of type `T` the following sets are analyzed (**in the given order**): 1. Non-extension member callables named `f` of type `T`; -2. Extension callables named `f`, whose receiver type `U` conforms to type `T`, in the current scope and its [upwards-linked scopes][Linked scopes], ordered by the size of the scope (smallest first), excluding the package scope; - * First, we assume there is **no implicit receiver** available for the dispatch receiver of `f` (i.e., we analyze _local_ extension callables only); - * Second, we consider each implicit receiver available for the dispatch receiver of `f` in the order of the implicit [receiver priority][Receivers]; +2. Local extension callables named `f`, whose receiver type `U` conforms to type `T`, in the current scope and its [upwards-linked scopes][Linked scopes], ordered by the size of the scope (smallest first), excluding the package scope; 3. Explicitly imported extension callables named `f`, whose receiver type `U` conforms to type `T`; 4. Extension callables named `f`, whose receiver type `U` conforms to type `T`, declared in the package scope; 5. Star-imported extension callables named `f`, whose receiver type `U` conforms to type `T`; @@ -206,6 +223,10 @@ If a call is correct, for a callable `f` with an explicit receiver `e` of type ` > Note: here type `U` conforms to type `T`, if $T <: U$. +> Note: a call to an extension callable with an explicit extension receiver, as noted above, may involve an implicit dispatch receiver. +> In this case, the case with **no implicit receiver** is considered first; then, for each implicit receiver available, a separate number of sets is constructed according to [the rules for implicit receivers][Call without an explicit receiver]. +> These sets are considered in the order of the implicit [receiver priority][Receivers]. + There is a important special case here, however, as a callable may be a [property-like callable with an operator function `invoke`][Callables and `invoke` convention], and these may belong to different sets (e.g., the property itself may be star-imported, while the `invoke` operator on it is a local extension). In this situation, such callable belongs to the **lowest priority** set of its parts (e.g., for the above case, priority 5 set). @@ -309,15 +330,16 @@ For an identifier named `f` the following sets are analyzed (**in the given orde 1. Local non-extension callables named `f` in the current scope and its [upwards-linked scopes][Linked scopes], ordered by the size of the scope (smallest first), excluding the package scope; 2. The overload candidate sets for each pair of implicit receivers `e` and `d` available in the current scope, calculated as if `e` is the [explicit receiver][Call with an explicit receiver], in order of the [receiver priority][Receivers]; + * In case `e` or `d` is a one-only implicit receiver group (e.g., involving implicit context-provided receivers), and _several_ implicit receivers from the group create a non-empty candidate set, this is an **overload ambiguity** which must be reported as a compile-time error; 3. Top-level non-extension functions named `f`, in the order of: a. Callables explicitly imported into the current file; b. Callables declared in the same package; c. Callables star-imported into the current file; d. Implicitly imported callables (either from the Kotlin standard library or platform-specific ones). -Similarly to how it works for [calls with explicit receiver][Call with an explicit receiver], a property-like callable with an `invoke function` belongs to the **lowest priority** set of its parts. +Similarly to how it works for [calls with explicit receiver][Call with an explicit receiver], a property-like callable with an `invoke` function belongs to the **lowest priority** set of its parts. -When analyzing these sets, the **first** set which contains **any** callable with the corresponding name and conforming types is picked for [c-level partition][c-level partition], which gives us the resulting overload candidate set. +When analyzing these sets, the **first** set which contains **any** [applicable callable][Determining function applicability for a specific call] is picked for [c-level partition][c-level partition], which gives us the resulting overload candidate set. After we have fixed the overload candidate set, we search this set for the [most specific callable][Choosing the most specific candidate from the overload candidate set]. @@ -362,7 +384,7 @@ Determining function applicability for a specific call is a [type constraint][Ko First, for every non-lambda argument of the function called, type inference is performed. Lambda arguments are excluded, as their type inference needs the results of overload resolution to finish. -Second, the following constraint system is built: +Second, the following _applicability constraint system_ is built: - For every non-lambda argument inferred to have type $T_i$, corresponding to the function parameter of type $U_j$, a constraint $T_i <: U_j$ is constructed; - All declaration-site type constraints for the function are also added to the constraint system; @@ -373,15 +395,31 @@ TODO: in fact, it is an intersection of both non-suspend and suspend variants TODO: taking into account the fact that $\FT(L) -> R <: \FTR(L) -> R <: \FT(L) -> R$, this is not entirely correct. It's not that important for applicability though. -If this constraint system is sound, the function is applicable for the call. -Only applicable functions are considered for the next step: [choosing the most specific candidate from the overload candidate set][Choosing the most specific candidate from the overload candidate set]. - -Receiver parameters are handled in the same way as other parameters in this mechanism, with one important exception: any receiver of type $\Nothing$ is deemed not applicable for any member callables, regardless of other parameters. +Receiver parameters are handled in the same way as other parameters in this constraint system, with one important exception: any receiver of type $\Nothing$ is deemed not applicable for any member callables, regardless of other parameters. This is due to the fact that, as $\Nothing$ is the subtype of any other type in Kotlin type system, it would have allowed **all** member callables of **all** available types to participate in the overload resolution, which is theoretically possible, but very resource-consuming and does not make much sense from the practical point of view. Extension callables are still available, because they are limited to the declarations available or imported in the current scope. > Note: although it is impossible to create a value of type $\Nothing$ directly, there may be situations where performing overload resolution on such value is necessary; for example, it may occur when doing safe navigation on values of type $\NothingQ$. +If the applicability constraint system is sound, the callable is _context-agnostic_ applicable for the call. + +If a _context-agnostic_ applicable callable is not [contextual][Contextual callables], it is _fully applicable_ for the call. + +If a _context-agnostic_ applicable callable is contextual, we check if its context receiver parameters can be satisfied w.r.t. the call. + +* For each context receiver parameter $P_i$ of type $T_i$ we perform the following. + * Find the **first** implicit receiver $r_j$ of a suitable type $R_j <: T_i$, in order of the [receiver priority][Receivers]; + * The suitability check is done by adding the constraint $R_j <: T_i$ to the applicability constraint system; + * If the applicability constraint system becomes unsound, we move to the next implicit receiver; + * If the applicability constraint system remains sound, we fix the use of implicit receiver $r_j$ for the context receiver parameter $P_i$. + * If $r_j$ is a one-only implicit receiver group and several implicit receivers from the group satisfy the context receiver parameter $P_i$, this is an **overload ambiguity** which must be reported as a compile-time error; + * If we cannot find an implicit receiver of a suitable type for some context receiver parameter, the check fails and the callable is considered inapplicable; +* If we found an implicit receiver of a suitable type for every context receiver parameter, the check succeeds. + +If this check is successful, the contextual callable is _fully applicable_ for the call. + +Only fully applicable callables are considered for the next step: [choosing the most specific candidate from the overload candidate set][Choosing the most specific candidate from the overload candidate set]. + ### Choosing the most specific candidate from the overload candidate set #### Rationale @@ -431,6 +469,9 @@ For every two distinct members of the candidate set $F_1$ and $F_2$, the followi > Note: this constraint system checks whether $F_1$ can forward itself to $F_2$. +> Note: it may seem strange to process built-in integer types in a way different from other types, but it is needed for cases when the call argument is an integer literal with an [integer literal type][Integer literal types]. +> The $\Widen$ operator ensures the [desired priority][Integer type widening] between overloads with integer type arguments. + If the resulting constraint system is sound, it means that $F_1$ is equally or more applicable than $F_2$ as an overload candidate (aka applicability criteria). The check is then repeated with $F_1$ and $F_2$ swapped. @@ -444,8 +485,7 @@ In case 1, the more applicable candidate of the two is found and no additional s In case 2, an additional step is performed. -- Any non-parameterized callable is a more specific candidate than any parameterized callable; - If there are several non-parameterized candidates, further steps are limited to those candidates. +- Any non-parameterized callable is a more specific candidate than any parameterized callable. In case 3, several additional steps are performed in order. @@ -454,9 +494,8 @@ In case 3, several additional steps are performed in order. - For each candidate we count the number of default parameters *not* specified in the call (i.e., the number of parameters for which we use the default value). The candidate with the least number of non-specified default parameters is a more specific candidate; - For all candidates, the candidate having any variable-argument parameters is less specific than any candidate without them. - -> Note: it may seem strange to process built-in integer types in a way different from other types, but it is needed for cases when the call argument is an integer literal with an [integer literal type][Integer literal types]. -> In this particular case, several functions with different built-in integer types for the corresponding parameter may be applicable, and the `kotlin.Int` overload is selected to be the most specific. +- Any [contextual callable][Contextual callables] is a more specific candidate than any non-contextual callable; +- A contextual callable $A$ is a more specific candidate than another contextual callable $B$, if $A$ has _strictly more_ context receiver parameters than $B$. > Important: compiler implementations may extend these steps with additional checks, if they deem necessary to do so. @@ -712,6 +751,8 @@ Second, the type information needed to perform the resolution steps is acquired The `invoke` operator convention **does not** apply to callable reference candidates. Third, and most important, is that, in the case of a call with a callable reference as a parameter, the resolution is **bidirectional**, meaning that both the callable being called and the callable being referenced are to be resolved _simultaneously_. +> Important: callable references to [contextual callables] are not supported. + #### Resolving callable references not used as arguments to a call In a simple case when the callable reference is not used as an argument to an overloaded call, its resolution is performed as follows: @@ -719,7 +760,7 @@ In a simple case when the callable reference is not used as an argument to an ov - For each callable reference candidate, we perform the following steps: - We build its type constraints and add them to the constraint system of the expression the callable reference is used in; - A callable reference is deemed applicable if the constraint system is sound; -- For all applicable candidates, the resolution sets are built according to the same rules [as building OCS for regular calls][Building the overload candidate set]; +- For all applicable candidates, the resolution sets are built according to the same rules [as building OCS for regular calls][Building the overload candidate set (OCS)]; - If the highest priority set contains more than one callable, this is an overload ambiguity and should be reported as a compile-time error. - Otherwise, the single callable in the set is chosen as the result of the resolution process. diff --git a/docs/src/md/kotlin.core/type-system.md b/docs/src/md/kotlin.core/type-system.md index 100745d36..accd7ac5f 100644 --- a/docs/src/md/kotlin.core/type-system.md +++ b/docs/src/md/kotlin.core/type-system.md @@ -827,14 +827,39 @@ $$\FTR(\RT, A_1, \ldots, A_n) \rightarrow R \equiv \FT(\RT, A_1, \ldots, A_n) \r i.e., receiver is considered as yet another argument of its function type. -> Note: this means that, for example, these two types are equivalent w.r.t. type system +In addition to extension receiver, a function type (suspending or not) can additionally specify a number of **context receivers**. + +A function type with context receivers + +$$\mathtt{context}(T_1, \ldots, T_m)\quad\FTR(\RT, A_1, \ldots, A_n) \rightarrow R$$ + +or + +$$\mathtt{context}(T_1, \ldots, T_m)\quad\FT(A_1, \ldots, A_n) \rightarrow R$$ + +consists of a number of **context receiver types** $T_1, \ldots, T_m$ and the base function type $\FTR$ or $\FT$ which may or may not have an extension receiver. +All context receivers can be considered as additional arguments to the corresponding function type, meaning that + +$$ + \begin{aligned} + &\mathtt{context}(T_1, \ldots, T_m)\quad\FTR(\RT, A_1, \ldots, A_n) \rightarrow R \\ + &\quad{}\quad{}\quad{}\quad{}\equiv \FT(T_1, \ldots, T_m, \RT, A_1, \ldots, A_n, R) \\ + &\mathtt{context}(T_1, \ldots, T_m)\quad\FT(A_1, \ldots, A_n) \rightarrow R \\ + &\quad{}\quad{}\quad{}\quad{}\equiv \FT(T_1, \ldots, T_m, A_1, \ldots, A_n, R) + \end{aligned} +$$ + +> Note: this means that, for example, all these types are equivalent w.r.t. type system > -> * `Int.(Int) -> String` -> * `(Int, Int) -> String` +> * `Int.(Double) -> String` +> * `(Int, Double) -> String` +> * `context(Int) (Double) -> String` +> * `context(Int) Double.() -> String` +> * `context(Int, Double) () -> String` > -> However, these two types are **not** equivalent w.r.t. [overload resolution][Overload resolution], as it distinguishes between functions with and without receiver. +> However, these types are **not** equivalent w.r.t. [overload resolution][Overload resolution], as it distinguishes between functions with and without receiver. -TODO(Specify other cases when these two types are **not** equivalent) +TODO(Specify other cases when these types are **not** equivalent) Furthermore, all function types $\FunctionN$ are subtypes of a general argument-agnostic type [$\Function$][`kotlin.Function`-typesystem] for the purpose of unification; this subtyping relation is also used in [overload resolution][Determining function applicability for a specific call]. @@ -862,6 +887,7 @@ Furthermore, all function types $\FunctionN$ are subtypes of a general argument- > val barRef: (Int) -> Any = Number::bar > ``` + ##### Suspending function types Kotlin supports structured concurrency in the form of [coroutines] via [suspending functions]. diff --git a/grammar/src/main/antlr/KotlinLexer.g4 b/grammar/src/main/antlr/KotlinLexer.g4 index 403f1e904..6a3c7dda5 100755 --- a/grammar/src/main/antlr/KotlinLexer.g4 +++ b/grammar/src/main/antlr/KotlinLexer.g4 @@ -163,6 +163,7 @@ INLINE: 'inline'; INFIX: 'infix'; EXTERNAL: 'external'; SUSPEND: 'suspend'; +CONTEXT: 'context'; OVERRIDE: 'override'; ABSTRACT: 'abstract'; FINAL: 'final'; @@ -298,6 +299,7 @@ IdentifierOrSoftKey | EXPECT | ACTUAL | VALUE + | CONTEXT /* Strong keywords */ | CONST | SUSPEND @@ -506,6 +508,8 @@ Inside_REIFIED: REIFIED -> type(REIFIED); Inside_EXPECT: EXPECT -> type(EXPECT); Inside_ACTUAL: ACTUAL -> type(ACTUAL); +Inside_CONTEXT: CONTEXT -> type(CONTEXT); + Inside_BooleanLiteral: BooleanLiteral -> type(BooleanLiteral); Inside_IntegerLiteral: IntegerLiteral -> type(IntegerLiteral); Inside_HexLiteral: HexLiteral -> type(HexLiteral); diff --git a/grammar/src/main/antlr/KotlinLexer.tokens b/grammar/src/main/antlr/KotlinLexer.tokens index a207d69c1..afac78eb2 100644 --- a/grammar/src/main/antlr/KotlinLexer.tokens +++ b/grammar/src/main/antlr/KotlinLexer.tokens @@ -120,55 +120,56 @@ INLINE=119 INFIX=120 EXTERNAL=121 SUSPEND=122 -OVERRIDE=123 -ABSTRACT=124 -FINAL=125 -OPEN=126 -CONST=127 -LATEINIT=128 -VARARG=129 -NOINLINE=130 -CROSSINLINE=131 -REIFIED=132 -EXPECT=133 -ACTUAL=134 -RealLiteral=135 -FloatLiteral=136 -DoubleLiteral=137 -IntegerLiteral=138 -HexLiteral=139 -BinLiteral=140 -UnsignedLiteral=141 -LongLiteral=142 -BooleanLiteral=143 -NullLiteral=144 -CharacterLiteral=145 -Identifier=146 -IdentifierOrSoftKey=147 -FieldIdentifier=148 -QUOTE_OPEN=149 -TRIPLE_QUOTE_OPEN=150 -UNICODE_CLASS_LL=151 -UNICODE_CLASS_LM=152 -UNICODE_CLASS_LO=153 -UNICODE_CLASS_LT=154 -UNICODE_CLASS_LU=155 -UNICODE_CLASS_ND=156 -UNICODE_CLASS_NL=157 -QUOTE_CLOSE=158 -LineStrRef=159 -LineStrText=160 -LineStrEscapedChar=161 -LineStrExprStart=162 -TRIPLE_QUOTE_CLOSE=163 -MultiLineStringQuote=164 -MultiLineStrRef=165 -MultiLineStrText=166 -MultiLineStrExprStart=167 -Inside_Comment=168 -Inside_WS=169 -Inside_NL=170 -ErrorCharacter=171 +CONTEXT=123 +OVERRIDE=124 +ABSTRACT=125 +FINAL=126 +OPEN=127 +CONST=128 +LATEINIT=129 +VARARG=130 +NOINLINE=131 +CROSSINLINE=132 +REIFIED=133 +EXPECT=134 +ACTUAL=135 +RealLiteral=136 +FloatLiteral=137 +DoubleLiteral=138 +IntegerLiteral=139 +HexLiteral=140 +BinLiteral=141 +UnsignedLiteral=142 +LongLiteral=143 +BooleanLiteral=144 +NullLiteral=145 +CharacterLiteral=146 +Identifier=147 +IdentifierOrSoftKey=148 +FieldIdentifier=149 +QUOTE_OPEN=150 +TRIPLE_QUOTE_OPEN=151 +UNICODE_CLASS_LL=152 +UNICODE_CLASS_LM=153 +UNICODE_CLASS_LO=154 +UNICODE_CLASS_LT=155 +UNICODE_CLASS_LU=156 +UNICODE_CLASS_ND=157 +UNICODE_CLASS_NL=158 +QUOTE_CLOSE=159 +LineStrRef=160 +LineStrText=161 +LineStrEscapedChar=162 +LineStrExprStart=163 +TRIPLE_QUOTE_CLOSE=164 +MultiLineStringQuote=165 +MultiLineStrRef=166 +MultiLineStrText=167 +MultiLineStrExprStart=168 +Inside_Comment=169 +Inside_WS=170 +Inside_NL=171 +ErrorCharacter=172 '...'=6 '.'=7 ','=8 @@ -274,17 +275,18 @@ ErrorCharacter=171 'infix'=120 'external'=121 'suspend'=122 -'override'=123 -'abstract'=124 -'final'=125 -'open'=126 -'const'=127 -'lateinit'=128 -'vararg'=129 -'noinline'=130 -'crossinline'=131 -'reified'=132 -'expect'=133 -'actual'=134 -'null'=144 -'"""'=150 +'context'=123 +'override'=124 +'abstract'=125 +'final'=126 +'open'=127 +'const'=128 +'lateinit'=129 +'vararg'=130 +'noinline'=131 +'crossinline'=132 +'reified'=133 +'expect'=134 +'actual'=135 +'null'=145 +'"""'=151 diff --git a/grammar/src/main/antlr/KotlinParser.g4 b/grammar/src/main/antlr/KotlinParser.g4 index 628dbed38..8e8afdbdd 100644 --- a/grammar/src/main/antlr/KotlinParser.g4 +++ b/grammar/src/main/antlr/KotlinParser.g4 @@ -287,7 +287,7 @@ typeProjectionModifier ; functionType - : (receiverType NL* DOT NL*)? functionTypeParameters NL* ARROW NL* type + : (contextModifier NL*)? (receiverType NL* DOT NL*)? functionTypeParameters NL* ARROW NL* type ; functionTypeParameters @@ -760,7 +760,8 @@ modifier | propertyModifier | inheritanceModifier | parameterModifier - | platformModifier) NL* + | platformModifier + | contextModifier) NL* ; typeModifiers @@ -770,6 +771,7 @@ typeModifiers typeModifier : annotation | SUSPEND NL* + | contextModifier NL* ; classModifier @@ -842,6 +844,9 @@ platformModifier | ACTUAL ; +contextModifier + : CONTEXT NL* LPAREN NL* type NL* (COMMA NL* type)* RPAREN; + // SECTION: annotations annotation @@ -916,6 +921,7 @@ simpleIdentifier | CONST | SUSPEND | VALUE + | CONTEXT ; identifier diff --git a/grammar/testData/diagnostics/callableReference/property/propertyFromAbstractSuperClass.antlrtree.txt b/grammar/testData/diagnostics/callableReference/property/propertyFromAbstractSuperClass.antlrtree.txt index 51fc6f195..f07077b3f 100644 --- a/grammar/testData/diagnostics/callableReference/property/propertyFromAbstractSuperClass.antlrtree.txt +++ b/grammar/testData/diagnostics/callableReference/property/propertyFromAbstractSuperClass.antlrtree.txt @@ -76,7 +76,7 @@ File: propertyFromAbstractSuperClass.kt - e390474b6d27985868b418ca2233e4e6 PRIVATE("private") VAL("val") simpleIdentifier - Identifier("context") + CONTEXT("context") COLON(":") type typeReference @@ -410,7 +410,7 @@ File: propertyFromAbstractSuperClass.kt - e390474b6d27985868b418ca2233e4e6 COMMA(",") classParameter simpleIdentifier - Identifier("context") + CONTEXT("context") COLON(":") type typeReference @@ -538,7 +538,7 @@ File: propertyFromAbstractSuperClass.kt - e390474b6d27985868b418ca2233e4e6 postfixUnaryExpression primaryExpression simpleIdentifier - Identifier("context") + CONTEXT("context") RPAREN(")") NL("\n") RCURL("}") diff --git a/grammar/testData/diagnostics/constructorConsistency/multipleAreNull.antlrtree.txt b/grammar/testData/diagnostics/constructorConsistency/multipleAreNull.antlrtree.txt index e08443f01..8a93a1c43 100644 --- a/grammar/testData/diagnostics/constructorConsistency/multipleAreNull.antlrtree.txt +++ b/grammar/testData/diagnostics/constructorConsistency/multipleAreNull.antlrtree.txt @@ -38,7 +38,7 @@ File: multipleAreNull.kt - c1db05b9aed9b68bc78c8f7e6ca58e39 functionValueParameter parameter simpleIdentifier - Identifier("context") + CONTEXT("context") COLON(":") type nullableType @@ -59,7 +59,7 @@ File: multipleAreNull.kt - c1db05b9aed9b68bc78c8f7e6ca58e39 functionValueParameter parameter simpleIdentifier - Identifier("context") + CONTEXT("context") COLON(":") type nullableType @@ -92,7 +92,7 @@ File: multipleAreNull.kt - c1db05b9aed9b68bc78c8f7e6ca58e39 functionValueParameter parameter simpleIdentifier - Identifier("context") + CONTEXT("context") COLON(":") type nullableType @@ -137,7 +137,7 @@ File: multipleAreNull.kt - c1db05b9aed9b68bc78c8f7e6ca58e39 functionValueParameter parameter simpleIdentifier - Identifier("context") + CONTEXT("context") COLON(":") type nullableType diff --git a/grammar/testData/diagnostics/inference/regressions/kt2883.antlrtree.txt b/grammar/testData/diagnostics/inference/regressions/kt2883.antlrtree.txt index 0a335c5b5..33a1c0a36 100644 --- a/grammar/testData/diagnostics/inference/regressions/kt2883.antlrtree.txt +++ b/grammar/testData/diagnostics/inference/regressions/kt2883.antlrtree.txt @@ -113,7 +113,7 @@ File: kt2883.kt - 91abddac7c7af7dde8fc4557d2d1194f functionValueParameter parameter simpleIdentifier - Identifier("context") + CONTEXT("context") COLON(":") type typeReference